我的查询是在数据上运行的,这个数据需要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)。
我非常感谢有关如何获得所需数据和修复查询时间慢的任何反馈。
先谢谢。
答案 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;