[英]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
将是col7
, col3
将是col16
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.