【问题标题】:MYSQL: Left Join is very slowMYSQL:左连接很慢
【发布时间】:2015-11-02 10:43:33
【问题描述】:

我正在为我的数据库使用 MySQl,我有三个表,我想使用左连接将它们连接起来,但性能非常慢。

下表是:

CREATE TABLE IF NOT EXISTS `register_doctor` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `doc_title` int(11) NOT NULL,
  `first_name` varchar(35) NOT NULL,
  `last_name` varchar(35) DEFAULT NULL,
  `gender` int(11) NOT NULL,
  `city_id` int(11) NOT NULL,
  `province_id` int(11) NOT NULL,
  `specialty_id` int(11) NOT NULL,
  `status` int(11) NOT NULL COMMENT '0 = Pending; 1 = Verified, 2 = Not Reg Yet, 3 = Pending Approval',
  `str_number` char(6) DEFAULT NULL,
  `editted_by` int(11) DEFAULT NULL,
  `editted_date` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `city_id` (`city_id`),
  KEY `specialty_id` (`specialty_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10267 ;

CREATE TABLE IF NOT EXISTS `ref_doctor_practice_place` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `doctor_id` int(11) NOT NULL,
  `practice_place_id` int(11) NOT NULL,
  `is_primary` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `doctor_id_2` (`doctor_id`,`practice_place_id`),
  KEY `doctor_id` (`doctor_id`),
  KEY `practice_place_id` (`practice_place_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=23677 ;

CREATE TABLE IF NOT EXISTS `practice_place` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(75) NOT NULL,
  `statement` text,
  `address` varchar(200) NOT NULL,
  `phone` varchar(15) NOT NULL,
  `fax` varchar(15) NOT NULL,
  `email` varchar(50) NOT NULL,
  `village_id` varchar(50) NOT NULL,
  `sub_district_id` varchar(50) NOT NULL,
  `province_id` varchar(50) NOT NULL,
  `zipcode` varchar(10) NOT NULL,
  `website` varchar(50) NOT NULL,
  `latitude` double NOT NULL,
  `longitude` double NOT NULL,
  `type` int(11) NOT NULL,
  `managed_by` int(11) DEFAULT '0',
  `doctor_group_id` int(11) NOT NULL,
  `category` varchar(50) NOT NULL,
  `photo_file` char(36) NOT NULL,
  `is_branch` int(11) NOT NULL,
  `parent_id` int(11) NOT NULL,
  `editted_by` int(11) NOT NULL,
  `editted_date` bigint(20) NOT NULL,
  `status` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `village_id` (`village_id`),
  KEY `doctor_group_id` (`doctor_group_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=24182 ;

我的查询是这样的:

SELECT SQL_CALC_FOUND_ROWS RD.id as rd_id
                         , RD.first_name
                         , RD.last_name
                         , RD.gender
                         , RD.str_number
                         , GROUP_CONCAT(DISTINCT PP.type SEPARATOR '|') as pp_type
                      FROM register_doctor RD 
                      LEFT 
                      JOIN ref_doctor_practice_place RDPP  
                        ON RDPP.doctor_id = RD.id
                      LEFT 
                      JOIN practice_place PP 
                        ON PP.id = RDPP.practice_place_id
                     GROUP 
                        BY RD.id 
                     ORDER 
                        BY RD.id DESC 
                     LIMIT 0,25

谁能帮我解决这个问题?非常感谢。

应草莓的要求,我把使用 EXPLAIN 的结果放在这里:

id  select_type     table   type    possible_keys   key         key_len ref                     rows    Extra   
1   SIMPLE      RD  index   PRIMARY,city_id PRIMARY     4   NULL                    15  NULL
1   SIMPLE      RDPP    ref     doctor_id   doctor_id   4   k6064619_lokadok.RD.id          1   NULL
1   SIMPLE      PP  eq_ref  PRIMARY,id  PRIMARY     4   k6064619_lokadok.RDPP.practice_place_id     1   NULL

【问题讨论】:

  • 您可能还有另一个名为practice_place 的表,请同时提供该表的创建语句。
  • 迫不及待地想看到这个非规范化数据 (|)
  • rostbot,您好,感谢您发现我的错误。我已经添加了另一个表。
  • 不幸的是,我在这里看不出什么错误:-(
  • 您对 WHERE 子句中使用的所有列都有索引吗?

标签: mysql left-join


【解决方案1】:

对不起各位。我应该发布真正的查询。左连接实际上是这样的:

LEFT JOIN ref_doctor_practice_place RDPP ON **ABS(RDPP.doctor_id) = RD.id**

我认为 ABS 并不重要,所以我将其删除以使其更直接。但实际上这是罪魁祸首。

我的查询没有问题。所以结案。感谢您尝试帮助我。欣赏它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多