【发布时间】:2018-10-09 19:20:30
【问题描述】:
这个查询在生产中运行了大约 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? */ ;
感谢任何 cmets/建议。
更新:只更新过滤顺序,查询性能提高到~28秒,在添加一些索引和替换一些子查询到连接后会在这里更新
【问题讨论】:
-
多个nonSARGable expressions:
UPPER(LEFT(table1.cloumn1, 1)),DATE_FORMAT(timstampColumn, '%Y/%m/%d'),SUBSTRING(column3,6,1) -
“我正在寻找改进的替代方案”,考虑使用 PostgreSQL 而不是 MySQL。PostgreSQL 支持表达式索引,这意味着您可以索引函数。postgresql.org/docs/9.1/static/indexes-expressional.html
-
或者使用 MySQL 5.7.6+ 生成的列来索引函数。像
column AS (UPPER(LEFT(table1.cloumn1, 1))) stored这样你就可以索引了。 -
@RaymondNijland -
UPPER(LEFT(table1.cloumn1, 1))为此,我正在考虑将索引创建为create index name_first on my_table (cloumn1(1));以排除LEFT的使用。 -
查询中有多余的括号吗?当我对其进行快速语法检查时似乎有。但可能最好进行连接而不是使用子查询。特别是对于获取每个 column5 / column6 的最大 id 的主要检查。这样 MySQL 可以排除最早的最大记录数。
标签: mysql performance optimization indexing query-optimization