需要帮助优化MySQL查询 - Join中的OR语句导致LONG查询时间过长

时间:2014-01-17 23:47:47

标签: mysql sql performance

我的查询是在数据上运行的,这个数据需要60-80秒。查询中的一个更改将其降低到250毫秒以下,但此更改会导致数据被排除在需要的范围内。

这是我正在使用的基本数据的SQL Dump(对于sqlfiddle来说太大了):http://pastebin.com/W8w1KFba

注意:我添加了“SQL_NO_CACHE”用于测试目的,我知道一些列名称有拼写错误,但这些列名仅用于测试目的,转储中的模式是基于实际数据构建的,但不包括实际列名和数据。 / p>

慢查询

查询

SELECT SQL_NO_CACHE
 `Table1`.`recordID`
FROM
  `Table1`
  LEFT JOIN `Table2` ON `Table1`.`recordID`=`Table2`.`table1RecordID`
  LEFT JOIN `Table3` ON `Table2`.`tabel3RecordID`=`Table3`.`recordID` OR `Table3`.`table1RecordID`=`Table1`.`recordID`
WHERE
  (`Table3`.`status` = '3' OR `Table3`.`status` = '4')  AND
  (`Table1`.`groupName` = 'Sample Name')
GROUP BY `Table2`.`tabel3RecordID` ASC, `Table1`.`recordID` ASC;

解释

+----+-------------+--------+------+--------------------------------------+--------------+---------+------------------------+-------+-----------------------------------------------------------+
| id | select_type | table  | type |             possible_key             |     key      | key_len |          ref           | rows  |                          Extras                           |
+----+-------------+--------+------+--------------------------------------+--------------+---------+------------------------+-------+-----------------------------------------------------------+
|  1 | SIMPLE      | Table1 | ref  | PRIMARY,groupName                    | groupName    | 768     | const                  |    77 | Using where; Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | Table2 | ref  | fk_packageID                         | fk_packageID | 5       | testDb.Table1.recordID |    88 |                                                           |
|  1 | SIMPLE      | Table3 | ALL  | PRIMARY,fk_packageID,regStatus,pkgID | NULL         | NULL    | NULL                   | 11326 | Using where; Using join buffer                            |
+----+-------------+--------+------+--------------------------------------+--------------+---------+------------------------+-------+-----------------------------------------------------------+

快速(修改慢查询)查询

查询

SELECT SQL_NO_CACHE
 `Table1`.`recordID`
FROM
  `Table1`
  LEFT JOIN `Table2` ON `Table1`.`recordID`=`Table2`.`table1RecordID`
  LEFT JOIN `Table3` ON `Table2`.`tabel3RecordID`=`Table3`.`recordID`
WHERE
  (`Table3`.`status` = '3' OR `Table3`.`status` = '4')  AND
  (`Table1`.`groupName` = 'Sample Name')
GROUP BY `Table2`.`tabel3RecordID` ASC, `Table1`.`recordID` ASC;

差分

删除

OR `Table3`.`table1RecordID`=`Table1`.`recordID`

从第6行

解释

+----+-------------+--------+--------+--------------------------------+--------------+---------+------------------------------+------+-----------------------------------------------------------+
| id | select_type | table  |  type  |          possible_key          |     key      | key_len |             ref              | rows |                          Extras                           |
+----+-------------+--------+--------+--------------------------------+--------------+---------+------------------------------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | Table1 | ref    | PRIMARY,groupName              | groupName    |     768 | const                        |   77 | Using where; Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | Table2 | ref    | fk_registrationID,fk_packageID | fk_packageID |       5 | testDb.Table1.recordID       |   88 | Using where                                               |
|  1 | SIMPLE      | Table3 | eq_ref | PRIMARY,regStatus              | PRIMARY      |       4 | testDb.Table2.tabel3RecordID |    1 | Using where                                               |
+----+-------------+--------+--------+--------------------------------+--------------+---------+------------------------------+------+-----------------------------------------------------------+

无法使用更快查询的原因是因为可能存在Table3包含数据的情况,其中table1RecordID中的ID与Table1的recordID匹配,因此我希望它包含Table2中的数据。所以我想要Table3中的数据,其中Table2具有匹配的ID以及Table3数据,其中Table1 ID与表3中的列匹配。当我在ON子句中使用OR来获取包含的数据时,这会大大减慢查询速度。我看到的问题是它创建了一个临时表,并将其复制到文件系统(filesort)。

我非常感谢有关如何获得所需数据和修复查询时间慢的任何反馈。

先谢谢。

1 个答案:

答案 0 :(得分:0)

尝试对表进行两次连接,并为每个连接分开比较。我认为这是逻辑:

SELECT SQL_NO_CACHE `Table1`.`recordID`
FROM `Table1`
      LEFT JOIN `Table2` ON `Table1`.`recordID`=`Table2`.`table1RecordID`
      LEFT JOIN `Table3` ON `Table2`.`tabel3RecordID`=`Table3`.`recordID`
      LEFT JOIN `Table3` t3 on t3.`table1RecordID`=`Table1`.`recordID`
WHERE (`Table3`.`status` in ('3', '4') or t3.status in ('3', '4'))  AND
      (`Table1`.`groupName` = 'Sample Name')
GROUP BY `Table2`.`tabel3RecordID` ASC, `Table1`.`recordID` ASC;