mysql - 具有许多嵌套子句的查询速度缓慢

标签 mysql in-clause

我在有许多嵌套子句的查询中遇到缓慢的问题。

查询如下:

select SA0_.sid as stid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid in (select AC1_.acid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid in (select AC1_.acid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid in (select AC1_.acid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid in (select AC1_.acid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid in (select AC1_.acid from table_starea SA0_ left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid where SA0_.sid in (select SB1_.sid from table_arstaff AC0_ left outer join table_stf SB1_ on AC0_.sid=SB1_.sid left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid where AC0_.acid=19)))))))))));

我检查了相同的解释,发现如下:

+----+--------------+-------------------+------------+------------+----------------------------------------+---------------------+---------+----------------------------------------------------+------+----------+--------------------------+
| id | select_type  | table     | partitions | type       | possible_keys                          | key                 | key_len | ref                        | rows | filtered | Extra                    |
+----+--------------+-------------------+------------+------------+----------------------------------------+---------------------+---------+----------------------------------------------------+------+----------+--------------------------+
|  1 | SIMPLE       | <subquery2>   | NULL       | ALL        | NULL                                   | NULL                | NULL    | NULL                       | NULL |   100.00 | Using where              |
|  1 | SIMPLE       | SA0_      | NULL       | ref        | table_starea_ix01                      | table_starea_ix01   | 5       | <subquery2>.sid                    |    1 |   100.00 | Using index              |
|  1 | SIMPLE       | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | const                      |    4 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | SA0_      | NULL       | ref        | FKFA890976F203761F,table_starea_ix01   | table_starea_ix01   | 5       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | ain2013Realdb.SA0_.acid                |    2 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | SA0_      | NULL       | ref        | FKFA890976F203761F,table_starea_ix01   | table_starea_ix01   | 5       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | ain2013Realdb.SA0_.acid                |    2 |   100.00 | Using index              |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | SA0_      | NULL       | ref        | FKFA890976F203761F,table_starea_ix01   | table_starea_ix01   | 5       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | ain2013Realdb.SA0_.acid                |    2 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | SA0_      | NULL       | ref        | FKFA890976F203761F,table_starea_ix01   | table_starea_ix01   | 5       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | ain2013Realdb.SA0_.acid                |    2 |   100.00 | Using index              |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | SA0_      | NULL       | ref        | FKFA890976F203761F,table_starea_ix01   | table_starea_ix01   | 5       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | Using where; Using index |
|  2 | MATERIALIZED | AC1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SA0_.acid                |    1 |   100.00 | Using index              |
|  2 | MATERIALIZED | AC0_      | NULL       | ref        | table_arstaff_ix01,tab_attach_fk2      | table_arstaff_ix01  | 4       | ain2013Realdb.SA0_.acid                |    2 |   100.00 | Using index              |
|  2 | MATERIALIZED | SB1_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.AC0_.sid             |    1 |   100.00 | NULL                     |
|  2 | MATERIALIZED | SG2_      | NULL       | eq_ref     | PRIMARY                                | PRIMARY             | 4       | ain2013Realdb.SB1_.sgid                |    1 |   100.00 | Using index              |
+----+--------------+-------------------+------------+------------+----------------------------------------+---------------------+---------+----------------------------------------------------+------+----------+--------------------------+

有人可以提出一个解决方案来使该查询快速执行吗?

我使用 INNER JOIN 重写了查询,如下所示:

选择 SA0_.sid 作为 stid from table_starea SA0_ left external join table_arcons AC1_ on SA0_.acid=AC1_.acid 其中 SA0_.sid in (select different sid from ((select SB1_.sid, AC0_.acid from table_arstaff AC0_ left external)在 AC0_.sid=SB1_.sid 上连接 table_stf SB1_ 在 SB1_.sgid=SG2_.sgid 上左外连接 table_stfgr SG2_ 在 SB1_.sgid=SG2_.sgid 上) TAB19 INNER JOIN(从 ((从 table_starea SA0_ 左外连接 table_arcons AC1_ 选择 AC1_.acid,SA0_.sid) SA0_.acid=AC1_.acid) TAB17 INNER JOIN (select sid from ((select SB1_.sid, AC0_.acid from table_arstaff AC0_ 左外连接 table_stf SB1_ 上 AC0_.sid=SB1_.sid 左外连接 table_stfgr SG2_ 上 SB1_。 sgid=SG2_.sgid) TAB15 INNER JOIN (selectacid from ((select AC1_.acid, SA0_.sid from table_starea SA0_ left external join table_arcons AC1_ on SA0_.acid=AC1_.acid) TAB13 INNER JOIN (select sid from ((select SB1_.sid, AC0_.acid 来自 table_arstaff AC0_ 左外连接 table_stf SB1_ 在 AC0_.sid=SB1_.sid 上左外连接 table_stfgr SG2_ 在 SB1_.sgid=SG2_.sgid) TAB11 INNER JOIN (从 ((select AC1_.acid , SA0_.sid from table_starea SA0_ 左外连接 table_arcons AC1_ on SA0_.acid=AC1_.acid) TAB9 INNER JOIN (select sid from ((select SB1_.sid, AC0_.acid from table_arstaff AC0_ 左外连接 table_stf SB1_ on AC0_.sid =SB1_.sid SB1_.sgid=SG2_.sgid 上的左外连接 table_stfgr SG2_) TAB7 INNER JOIN (select Acid from ((select AC1_.acid, SA0_.sid from table_starea SA0_ 左外连接 SA0_.acid=AC1_ 上的 table_arcons AC1_。 Acid) TAB5 INNER JOIN (select sid from (select SB1_.sid, AC0_.acid from table_arstaff AC0_左外连接 table_stf SB1_ on AC0_.sid=SB1_.sid left外连接 table_stfgr SG2_ on SB1_.sgid=SG2_.sgid) TAB3 INNER JOIN(从 table_starea SA0_ 左外连接 table_arcons AC1_ 上选择 AC1_.acid、SA0_.sid SA0_.acid=AC1_.acid) TAB2 INNER JOIN(从 table_arstaff AC0_ 左外连接 table_stf SB1_ 在 AC0_ 上选择 SB1_.sid。 sid=SB1_.sid 左外连接 table_stfgr SB1_.sgid=SG2_.sgid 上的 SG2_,其中 AC0_.acid=19) TAB1 ON TAB2.sid = TAB1.sid) TAB4 on TAB3.acid = TAB4.acid) TAB6 on TAB5.sid = TAB6.sid)) TAB8 上 TAB7.acid = TAB8.acid)) TAB10 上 TAB9.sid = TAB10.sid)) TAB12 上 TAB11.acid = TAB12.acid)) TAB14 上 TAB13.sid = TAB14.sid)) TAB16 上的 TAB15.acid = TAB16.acid)) TAB18 上的 TAB17.sid = TAB18.sid)) TAB20 上的 TAB19.acid = TAB20.acid));

这会带来优化吗?

最佳答案

关于性能的第一个建议..在大多数性能 INNER JOIN 子句中,每个 IN 子句都可以轻松更改,例如,对于更深的嵌套级别,您可以更改代码

    ....
     select AC1_.acid 
                      from table_starea SA0_ 
      left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid 
      where SA0_.sid in ( 
        select SB1_.sid 
        from table_arstaff AC0_ 
        left outer join table_stf SB1_ on AC0_.sid=SB1_.sid 
        left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid 
        where AC0_.acid=19   )

     ....)))))))));

  ......
   select AC1_.acid 
    from table_starea SA0_ 
    left outer join table_arcons AC1_ on SA0_.acid=AC1_.acid 

  ) t2 on AC0_.acid = t2.acid
  INNER JOIN (
    select SB1_.sid 
    from table_arstaff AC0_ 
    left outer join table_stf SB1_ on AC0_.sid=SB1_.sid 
    left outer join table_stfgr SG2_ on SB1_.sgid=SG2_.sgid 
    where AC0_.acid=19 
  ) t1 on t1.sid = SA0_.sid 


      ....)))))))));

结果是相同的,但内部联接应该更快..

你可以从更深层次开始重构你的代码,并用相应的 INNER JOIN 逐一重构所有 IN 子句

关于mysql - 具有许多嵌套子句的查询速度缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51965501/

相关文章:

mysql - UTF-8字符有问题;我看到的不是我存储的

"NOT IN"值列表的 MySQL 变量格式

mysql - 尝试使用 into 语句错误

sql-server - 1 个表上有 2 个字段的 In 子句

sql - 使用sql计算类型时间的总和

MySQL:一张表中的一条语句

mysql - 反向子句 IN 命名查询 Hibernate

php - SELECT WHERE IN 不检索所有记录

php - 奇怪的 mySQL 错误代码 1271

mysql - SQL查询以根据通配符替换字符串