环境:
DB: mysql 5.7.xx
OS: windows server 2012 r2
CPU: E3 1220-V5
内存: 4G。
数据库配置(基本上是默认配置):
join_buffer_size = 128M
sort_buffer_size = 2M
read_rnd_buffer_size = 2M
innodb_buffer_pool_size = 128M
表现:
有个表service_log,
其中有ID, DIAL_NUMBER, contact_name, contact_result, remark, CREATE_TIME等20多个常规字段。ID是PK,在contact_name,create_time等列上建有单独索引。
此表每日产生的新数据大概在1万左右,目前有数据近300万。
有一个查询,查询字段较多:
select id, dial_number, contact_name ....
from service_log
where create_time between '2016-10-01' and '2016-10-02'
从300万数据中,查询出近8000条数据,耗时大概在40秒左右。
查看执行计划,已经用了create_time上的索引。
显然这个效率很难接受,但是索引已经用上,实在想不出其他办法了。
请问除了分区,还有什么好办法吗?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
一次性取到太大的结果集不一定就是好。
除了加大对应的配置参数之外,可以考虑把一条sql查分为N条sql,这个可以具体的自己测试,比如每次取三个小时四个小时这样试试看得到一个平衡。
并发高吗,重复查询的概率高不高,可以尝试打开或者关闭查询缓存。
你要看时间花在哪里,是查找上,还是传输上。。。查找的话就说明优化没做好
建立组合索引,最频繁使用的列放在左边;查看列的选择性(即该列的索引值数量与记录数量的比值),比值越高,效果越好。
感谢各位回答,后来发现这个问题的症结在哪儿了,时间耗在回表操作了。
select id, dial_number, contact_name ....
from service_log
where create_time between '2016-10-01' and '2016-10-02'
这个查询,如果改成这样:
select id
from service_log
where create_time between '2016-10-01' and '2016-10-02'
速度飞快,因为SELECT 后面只有一个主键PK,直接在索引里就能确定每个满足条件的记录的ID了。
而如果SELECT后面还有其他字段,则需要根据PK去表里找出相应记录,找出其他字段的值,这就是回表操作了,这个过程很慢。这个应该是属于IO问题吧?