繁体   English   中英

如何优化慢速Mysql SELECT查询?

[英]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将是col7col3将是col16

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM