简体   繁体   English

如何优化慢速Mysql SELECT查询?

[英]How to optimize slow Mysql SELECT queries?

Here is my query: 这是我的查询:

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

I don't know what is making this query slow, whether it's the order by ,or the where clauses... 我不知道是什么让这个查询变慢,无论是order by还是where子句......

Properely added the index also, but it's still slow. 也正确地添加了索引,但它仍然很慢。

I'am using JSP + STRUTS + EJB2.0 + MYSQL. 我使用的是JSP + STRUTS + EJB2.0 + MYSQL。 The table1 has more than half million records. table1有超过50万条记录。 How can I optimize the query or what are the other possibilities to improve the speed of execution? 如何优化查询或提高执行速度的其他可能性有哪些?

table structure 表结构

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]

I don't know what it is making this query slow, whether order by, or conditions.. 我不知道是什么让这个查询变慢,无论是顺序还是条件......

Half a million records should fit in memory if they're the usual sort of name, phone nr, email sort of thing (and not documents). 如果它们是通常的名称,电话号码,电子邮件类型的东西(而不是文档),那么50万条记录应该适合内存。 So if it's -very- slow, something is very wrong. 所以如果它非常慢,那就是非常错误的。

properly added index also,still slow. 正确添加索引也仍然很慢。

Which columns are indexed? 哪些列被编入索引? You need to index by the column that will filter most effectively. 您需要按最有效过滤的列进行索引。 For example, if col2 is the answer to a yes or no question, it won't help to index by that. 例如,如果col2是肯定或否定问题的答案,那么索引也无济于事。

Your query - 您的查询 -

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

This will first need a covering index 这首先需要一个覆盖指数

alter table table1 add index search_idx(col1,col2,col3) ;

Now to resolve the order by clause you will need to index that as well 现在要解决order by子句,您还需要对其进行索引

alter table table1 add index col4_idx(col4) ;

Now note that the or condition is killer and performace wise its better to convert this to union all 现在请注意, 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

You may use explain select for the above queries to analyze the query health. 您可以使用explain select来进行上述查询来分析查询运行状况。

Make sure to take a backup of the table before applying the index. 确保在应用索引之前备份表。

https://dev.mysql.com/doc/refman/5.0/en/select-optimization.html 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 https://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

Are you sure your WHERE-condition is correct? 你确定你的WHERE条件是否正确?

AND takes precedence over OR, so AND优先于OR,所以

where col1= 'val' and col2='Y' and col3='203' OR col3='201'

is the same as 是相同的

where (col1= 'val' and col2='Y' and col3='203') OR (col3='201')

But you probably want 但你可能想要

where col1= 'val' and col2='Y' and (col3='203' OR col3='201')

Edit: Based on your comment my assumption was wrong and you actually want the original result (Then I would suggest adding parentheses to make it clear). 编辑:根据你的评论,我的假设是错误的,你实际上想要原始结果(然后我建议添加括号以使其清楚)。 The only possible index in that case would be on col3 (if it's selective enough). 在这种情况下唯一可能的索引是col3 (如果它足够有选择性)。

I don't know if mysql's optimizer is smart enough to access a table using the same index twice, if not you need to UNION ALL two queries: 我不知道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

Edit2: After the OP edited the question the column names are wrong ( col2 will be col7 and col3 will be col16 ) 编辑2:OP编辑问题后列名称错误( col2将是col7col3将是col16

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

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