前端时间接到公司的一个任务,想把云端服务的cpu的利用率给降下来,在优化慢sql的过程中,阿里云扫描出来的问题的sql中有一条的执行计划是这样的
UPDATE table_name SET origin_data_id='2024-06-15101102A50',
org_id=1111111,
eid='xxxxxxxxx',
modify_time='2024-06-25 13:00:00.521',
datasyn_status=2,
datasyn_status_desc='aaaaa',
datasyn_msg=''
WHERE rec_status=1
AND eid = 'xxxxxxxxx' AND org_id = 1111111 AND origin_data_id = '2024-06-15101102A50' AND status = 1 AND datasyn_status = 1
查看执行计划如下:
Using intersect(idx_orgid_origindataid_status,idx_datasyn_status);
Using intersect 使用了索引的交叉,分别使用了 idx_orgid_origindataid_status 和 idx_datasyn_status 索引,查询后取两个数据集的交集,说实话,我是第一次见。这种会有一种性能问题,虽然命中索引,但是扫描行数会增加,但是是真的影响性能的时候才需要取解决,不然没必要,还是按照mysql自己的解决方案走最好。如果还是不想用 Using intersect,有一些解决办法,可以直接删除不用的索引,也可以查询的时候强制指定索引,还可以隐藏不需要的索引,或者直接禁止使用这种索引方式。
- 直接删除不需要的索引
- 禁用 Using intersect
SET optimizer_switch = 'index_merge_intersection=off'
- 隐藏索引,不过该功能好像只在 mysql8.0中有,也称为不可见索引
将索引设置为可见:
ALTER TABLE table_xxxx ALTER INDEX idx_xxxx VISIBLE;
将索引设置为隐藏
ALTER TABLE table_xxxxx ALTER INDEX idx_xxxx INVISIBLE;