问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

索引用了!查询速度为什么还是那么慢?!

发布网友 发布时间:2022-04-22 05:37

我来回答

4个回答

热心网友 时间:2023-10-15 09:31

1. 执行计划中明明有使用到索引,为什么执行还是这么慢?

2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)

优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+

在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+

由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+

在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'

执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。

热心网友 时间:2023-10-15 09:31

查询的速度并不是单纯看有没有索引的,和很多东西是有关系的
首先,你的数据表有多大,如果达到千万级别,个人建议你对表分区,这样才能从根本上提高效率,你虽然只需要一万条数据,但是他需要检索的数据却有上千万条。
其次,你的程序写的是否优秀?是否用到了索引字段。你的索引是否有效?有些时候索引是会失效的,需要重新更新一下。
再次,你的物理设备是否正常,速度是不是不太好?
你的数据库设置是否合理,日志之类的是否正确?
总之,需要考虑的东西很多,慢慢设置一下,事情总会好转的。

热心网友 时间:2023-10-15 09:32

估计是查的时候索引没用上。

热心网友 时间:2023-10-15 09:32

一万条数据原则上不会很慢的,你把SQL语句贴出来看看
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
vivo手机死机一直亮屏也关不了 vivo手机死机了怎么办,无法关机 为什么我的vivo手机死机关不了机? 企业经营分析手册图书目录 腾达311R如何设置限速,请指教 计算机系统结构:量化研究方法目录 无线W311R,设置限速! 拼多多投直通车亏(拼多多开直通车亏本) 拼多多烧直通车亏本(拼多多直通车一直亏钱) 拼多多烧直通车亏本(拼多多开直通车赔钱) 我的电脑不能进入BIOS界面了 SQL语句执行很慢,怎么回事? 电脑能开机不能进入bios,是不是主板坏了? 求助,sql语句无法用到索引,执行很慢 我的电脑开机一直卡在asus界面,也进不去bios界面... 电脑开机时一直停留在BIOS界面加载进度,始终进不... 我家电脑进不了bios啊,怎么办,技嘉的 单片机C语言数组,十六进制转十进制 我的电脑为什么进不了BIOS界面 62235英语怎么写? 电脑开机无法进入系统,不能进入bios,停留在主板... 五位数62a3b是45的倍数,这个数最大是多少? 电脑总是bios界面进不去 62A3B是45的倍数,这个五位数最大是多少? 五位数62a3b最是45的倍数这个数最大是多少? 电脑进入不了bios界面怎么办 62235用英语怎么说? 62235什么银行 三星怎么看已连wifi的密码 三星手机怎么查询输入过的wifi密码? 电脑有几年没用过了,能开机进不了界面 SQL 语句执行感觉很慢,怎么回事? 电脑开机停留在智能主板的界面好久!而且进去不了B... 123456789相加减最终等20 电脑一直重复重启重装系统进不了BIOS 如何解决SQL查询速度太慢? 普洱茶究竟有没有保质期的? 斯诺克各位大师的世界排名。要前二十的。 全国涂料培训班。谁知道? 普洱茶的保质期有多久,是像朋友说的越陈越香吗? 普洱茶生茶保质期几年? 普洱茶有保质期吗 冻水饺用冷水还是热水下锅? 冻饺子是冷水下锅还是热水下锅? 出了事故,只报警了没报保险,事后再走保险可以吗? 车撞石墩走了过后可以报保险吗? 汽车撞到人当场没报保险事后可以再报保险吗? 车撞了,没及时报警,事后可以走保险吗 车辆发生事故后离开了现场可否报保险呢? 我的车子前几天撞得现在还能报保险吗?