Java 如何优化慢速Mysql选择查询?
我的问题是:Java 如何优化慢速Mysql选择查询?,java,mysql,sql,performance,Java,Mysql,Sql,Performance,我的问题是: 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子句 Propevere也加入了该指数,但速度仍然缓慢 我正在使用JSP+STRUTS+EJB2.0+
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子句
Propevere也加入了该指数,但速度仍然缓慢
我正在使用JSP+STRUTS+EJB2.0+MYSQL。
表1有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) ;
现在要解决ORDERBY子句,您还需要为其编制索引
alter table table1 add index col4_idx(col4) ;
现在请注意,或
条件是致命的,从性能上讲,最好将其转换为联合所有
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
,以分析查询运行状况
确保在应用索引之前备份表
您确定您的WHERE条件正确吗 优先于或,所以
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的优化器是否足够聪明,可以使用同一个索引访问两次表,否则需要合并所有两个查询:
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
)表定义,解释此查询应返回多少行?使您的查询速度变慢的是order by
,而不是where
条件它返回50万条记录中满足条件的所有记录,以及通常有多少条记录满足条件?如果您获取50万条记录,然后,大约10000条记录-对于条件col1='val',共10000条记录,对于条件col7='Y',共7000条记录,对于条件col16='209',共6000条记录,对于条件col16='201',共2000条记录,因此最终输出大约为3000条记录。这将不会返回与原始查询相同的结果,优先于OR@dnoeth:您是否注意到这个union all
只是这个答案中第一个查询的一个拆分?在原始查询中,其中col1='val'和col2='Y'以及col3='203'或col3='201'
,我认为这是不正确的,因为没有和(cond1或con2)
导致一些意外结果。@Ravinder Reddy:是的,它基于第一个答案,但第一个答案返回的结果集与OP的查询结果集不同。@dnoeth:OP可能在不知不觉中使用了这种查询格式。他已经同意建议的查询给出了一个where col1='val'和col2='Y',以及(col3='203'或col3='201')这会有什么不同吗?当然,它返回的结果完全不同。你需要知道你真正想要的是什么。查询提供了所需的输出,但我面临的唯一问题是它的输出响应缓慢。@vineeth.soman:所以所有当前的答案都无法解决这个问题,因为他们试图优化错误的查询:-)你能提供一些信息吗,查询返回的行数以及col3
(=选择性)的每个值的平均行数(如果您获取500000条记录),然后,大约10000条记录-对于条件col1='val'共10000条记录,对于条件col7='Y'共7000条记录,对于条件col16='209'共6000条记录,对于条件col16='201'共2000条记录,因此最终输出大约为3000条记录