为什么INNER JOIN查询这么慢? - LEFT JOINS加快了速度

时间:2014-10-20 08:28:34

标签: mysql

早上好。

有人可以向我解释,为什么在MySQL中,如果我将成为INNER JOINS并在WHERE clouse中从一个连接表中的索引列中添加简单条件,则首先执行连接,然后执行扫描中间结果提供的条件?

我认为,优化查询应首先从where子句中包含的表中选择适当的行,然后执行正确的连接,因为这会减少表读取错误?目前的行为对我来说只是愚蠢的。此类行为的示例如下。

explain select 
    patent0_.id as id1_6_0_,
    referencen1_.id as id1_7_1_,
    service2_.id as id1_8_2_,
    applicant3_.id as id1_0_3_,
    country4_.id as id1_2_4_,
    patent0_.applicant_id as applica14_6_0_,
    patent0_.applicationDate as applicat2_6_0_,
    patent0_.applicationLanguage as applicat3_6_0_,
    patent0_.applicationNumber as applicat4_6_0_,
    patent0_.classification as classifi5_6_0_,
    patent0_.creationDate as creation6_6_0_,
    patent0_.disabled as disabled7_6_0_,
    patent0_.licenceInfo as licenceI8_6_0_,
    patent0_.patentName as patentNa9_6_0_,
    patent0_.publicationDate as publica10_6_0_,
    patent0_.publicationNumber as publica11_6_0_,
    patent0_.registrationDate as registr12_6_0_,
    patent0_.registrationNumber as registr13_6_0_,
    referencen1_.creationDate as creation2_7_1_,
    referencen1_.design_id as design_i8_7_1_,
    referencen1_.error as error3_7_1_,
    referencen1_.hasRenewal as hasRenew4_7_1_,
    referencen1_.info as info5_7_1_,
    referencen1_.patent_id as patent_i9_7_1_,
    referencen1_.referenceNumber as referenc6_7_1_,
    referencen1_.service_id as service10_7_1_,
    referencen1_.trademark_id as tradema11_7_1_,
    referencen1_.type as type7_7_1_,
    service2_.additional_name as addition2_8_2_,
    service2_.name as name3_8_2_,
    applicant3_.address as address2_0_3_,
    applicant3_.addressSource_id as address13_0_3_,
    applicant3_.city as city3_0_3_,
    applicant3_.country_id as country14_0_3_,
    applicant3_.createdDate as createdD4_0_3_,
    applicant3_.deleted as deleted5_0_3_,
    applicant3_.disabled as disabled6_0_3_,
    applicant3_.entryCount as entryCou7_0_3_,
    applicant3_.entryCountChanged as entryCou8_0_3_,
    applicant3_.manualModified as manualMo9_0_3_,
    applicant3_.modifiedDate as modifie10_0_3_,
    applicant3_.name as name11_0_3_,
    applicant3_.zipCode as zipCode12_0_3_,
    country4_.dateFormat as dateForm2_2_4_,
    country4_.englishName as englishN3_2_4_,
    country4_.iso3166 as iso4_2_4_,
    country4_.locale as locale5_2_4_,
    country4_.name as name6_2_4_,
    country4_.polishName as polishNa7_2_4_
from 
    patent patent0_
        inner join 
    referencenumber referencen1_ ON patent0_.id = referencen1_.patent_id
        inner join
    service service2_ ON referencen1_.service_id = service2_.id
        inner join
    applicant applicant3_ ON patent0_.applicant_id = applicant3_.id
        inner join
    country country4_ ON applicant3_.country_id = country4_.id
where
    patent0_.applicant_id = 102014

解释结果:

+----+-------------+--------------+--------+-----------------------------------------------------------------------+------------------------------+---------+-----------------------------------+-------+-------------+
| id | select_type | table        | type   | possible_keys                                                         | key                          | key_len | ref                               | rows  | Extra       |
+----+-------------+--------------+--------+-----------------------------------------------------------------------+------------------------------+---------+-----------------------------------+-------+-------------+
|  1 | SIMPLE      | applicant3_  | const  | PRIMARY,FK_cjteymxk1h6sce00e4vtar8we                                  | PRIMARY                      | 4       | const                             |     1 | NULL        |
|  1 | SIMPLE      | country4_    | const  | PRIMARY                                                               | PRIMARY                      | 4       | const                             |     1 | NULL        |
|  1 | SIMPLE      | service2_    | ALL    | PRIMARY                                                               | NULL                         | NULL    | NULL                              |    27 | NULL        |
|  1 | SIMPLE      | referencen1_ | ref    | patent_id_UNIQUE,FK_fcy9m21m0jaid4l8e8bbsms1v,FK_5lMjxN8AZfRUOuCWebvP | FK_fcy9m21m0jaid4l8e8bbsms1v | 5       | trademarks.service2_.id           | 60454 | Using where |
|  1 | SIMPLE      | patent0_     | eq_ref | PRIMARY,FK_8991d6757d10418eaa7cd8fe1da                                | PRIMARY                      | 4       | trademarks.referencen1_.patent_id |     1 | Using where |
+----+-------------+--------------+--------+-----------------------------------------------------------------------+------------------------------+---------+-----------------------------------+-------+-------------+

我当时希望此查询首先使用正确的applicant_id获取所有专利,然后在该行上执行INNER JOINS。为了实现这一点,我必须将所有内部关节改为左连接。 那么为什么INNER JOINS有这么糟糕的优化路径呢?如何解决? 根据要求,此处是LEFT JOINS INNER JOINS

+----+-------------+--------------+--------+------------------------------------------+--------------------------------+---------+------------------------------------+---------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------------+--------+------------------------------------------+--------------------------------+---------+------------------------------------+---------+-------+ | 1 | SIMPLE | patent0_ | ref | FK_8991d6757d10418eaa7cd8fe1da | FK_8991d6757d10418eaa7cd8fe1da | 5 | const | 86 | NULL | | 1 | SIMPLE | referencen1_ | ref | patent_id_UNIQUE,FK_5lMjxN8AZfRUOuCWebvP | patent_id_UNIQUE | 5 | trademarks.patent0_.id | 1632272 | NULL | | 1 | SIMPLE | service2_ | eq_ref | PRIMARY | PRIMARY | 4 | trademarks.referencen1_.service_id | 1 | NULL | | 1 | SIMPLE | applicant3_ | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL | | 1 | SIMPLE | country4_ | eq_ref | PRIMARY | PRIMARY | 4 | trademarks.applicant3_.country_id | 1 | NULL | +----+-------------+--------------+--------+------------------------------------------+--------------------------------+---------+------------------------------------+---------+-------+ 的同一查询的执行计划
{{1}}

0 个答案:

没有答案