这个查询在生产中运行了大约15个小时,我正在寻找替代方案来改进它,
我认为有些改进可能会有所帮助,请参见以下评论:
SELECT table1.*
FROM table1
WHERE UPPER(LEFT(table1.cloumn1, 1)) IN ('A', 'B')
AND table1.cloumn2 = 'N' /* add composite index for cloumn2,
column3 */
AND table1.cloumn3 != 'Y'
AND table1.id IN (
SELECT MAX(id)
FROM table1
GROUP BY column5,column6
) /* move this clause to 2nd after
where */
AND table1.column4 IN (
SELECT column1
FROM table2
WHERE column2 IN ('VALUE1', 'VALUE2')
AND (SUBSTRING(column3,6,1) = 'Y'
OR SUBSTRING(column3,25,1) = 'Y')
) /* move this clause to 1st after
where */
AND (table1.column5,table1.column6) NOT IN (
SELECT column1, column2
FROM table3
WHERE table3.column3 IN ('A', 'B')/* add index for this column*/
)
AND DATE_FORMAT(timstampColumn, '%Y/%m/%d') > DATE_ADD(CURRENT_DATE,
INTERVAL - 28 DAY)) /* need index ON this col? */ ;
如有任何意见/建议,我们将不胜感激。
更新:只更新过滤顺序,查询性能提高到28秒左右,添加一些索引并替换一些子查询到连接后,将在此处更新
2条答案
按热度按时间pqwbnv8z1#
假设您可以添加有用的索引(这将有助于您的一些检查),那么可以尝试尽早排除行。
我怀疑表1中每列5/6的组合都有相当多的行。如果您能尽早获得其中每一个的最新信息(即,使用您加入的子查询),那么您就可以在需要检查任何未编入索引的where子句之前从表1中排除大多数行。您还可以通过对表3上的子查询执行进一步的联接来排除其中的一些查询。
没有测试,但如果我对你的数据库结构的假设是正确的,那么这可能是一个即时消息provement:-
eivnm1vs2#
(这可能有助于
SHOW CREATE TABLE
.)不能使用索引;这可能相当于:
请提供
EXPLAIN
.你用的是什么版本?
它可能(依赖于版本)有助于
IN ( SELECT ... )
“派生”表中的子句:UPPER(LEFT(table1.cloumn1, 1)) IN ('A', 'B')
LEFT(table1.cloumn1, 1) IN ('A', 'B')
table1.cloumn1 >= 'A'
AND table1.cloumn1 < 'C'