[英]How to optimize slow Mysql SELECT queries?
这是我的查询:
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
WHERE col1= 'val' and col7='Y' and col16='203' OR col16='201' order by col4 desc
我不知道是什么让这个查询变慢,无论是order by
还是where子句......
也正确地添加了索引,但它仍然很慢。
我使用的是JSP + STRUTS + EJB2.0 + MYSQL。 table1有超过50万条记录。 如何优化查询或提高执行速度的其他可能性有哪些?
表结构
col1 varchar(20) NO PRI
col2 varchar(50) NO PRI
col3 varchar(50) YES [NULL]
col4 varchar(20) YES [NULL]
col5 varchar(6) YES [NULL]
col6 varchar(20) YES [NULL]
col7 varchar(1) YES [NULL]
col8 mediumtext YES [NULL]
col9 mediumtext YES [NULL]
col10 mediumtext YES [NULL]
col11 mediumtext YES [NULL]
col12 mediumtext YES [NULL]
col13 mediumtext YES [NULL]
col14 mediumtext YES [NULL]
col15 mediumtext YES [NULL]
col16 varchar(20) YES [NULL]
col17 varchar(50) YES [NULL]
col18 varchar(5) YES [NULL]
col19 varchar(5) YES [NULL]
col20 varchar(5) YES [NULL]
col21 text YES [NULL]
col 22 text YES [NULL]
col23 text YES [NULL]
col24 varchar(5) YES [NULL]
col25 int(11) YES [NULL]
我不知道是什么让这个查询变慢,无论是顺序还是条件......
如果它们是通常的名称,电话号码,电子邮件类型的东西(而不是文档),那么50万条记录应该适合内存。 所以如果它非常慢,那就是非常错误的。
正确添加索引也仍然很慢。
哪些列被编入索引? 您需要按最有效过滤的列进行索引。 例如,如果col2是肯定或否定问题的答案,那么索引也无济于事。
您的查询 -
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
where
col1= 'val'
and col2='Y'
and (col3='203' OR col3='201')
order by col4 desc
这首先需要一个覆盖指数
alter table table1 add index search_idx(col1,col2,col3) ;
现在要解决order by子句,您还需要对其进行索引
alter table table1 add index col4_idx(col4) ;
现在请注意, or
条件是杀手和性能明智,将其转换为union all
更好
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
where
col1= 'val'
and col2='Y'
and col3='203'
union all
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
where
col1= 'val'
and col2='Y'
and col3='201'
order by col4 desc
您可以使用explain select
来进行上述查询来分析查询运行状况。
确保在应用索引之前备份表。
https://dev.mysql.com/doc/refman/5.0/en/select-optimization.html
https://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
你确定你的WHERE条件是否正确?
AND优先于OR,所以
where col1= 'val' and col2='Y' and col3='203' OR col3='201'
是相同的
where (col1= 'val' and col2='Y' and col3='203') OR (col3='201')
但你可能想要
where col1= 'val' and col2='Y' and (col3='203' OR col3='201')
编辑:根据你的评论,我的假设是错误的,你实际上想要原始结果(然后我建议添加括号以使其清楚)。 在这种情况下唯一可能的索引是col3
(如果它足够有选择性)。
我不知道mysql的优化器是否足够聪明,可以使用相同的索引两次访问一个表,如果不是,你需要UNION ALL两个查询:
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
WHERE col1= 'val' AND col2='Y' AND col3='203'
UNION ALL
SELECT col1, col2, col3, col4, col5, col6,col7, col8,..,col18
FROM table1
WHERE col3='201'
ORDER BY col4 DESC
编辑2:OP编辑问题后列名称错误( col2
将是col7
, col3
将是col16
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.