这是我的问题:
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]
答案 0 :(得分:0)
我不知道是什么让这个查询变慢,无论是顺序还是条件......
如果他们是通常的名字,电话号码,电子邮件类型的东西(而不是文件),那么50万条记录应该适合记忆。因此,如果它非常慢,那就是非常错误。
正确添加索引,仍然很慢。
哪些列被编入索引?您需要按最有效过滤的列进行索引。例如,如果col2是肯定或否定问题的答案,那么它将无助于索引。
答案 1 :(得分:0)
您的查询 -
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
答案 2 :(得分:0)
你确定你的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
EDIT2:
在OP编辑问题后,列名称错误(col2
将为col7
而col3
将为col16
)