SELECT *
FROM table lm
WHERE `lm`.`CreateTime` >= '2021-07-13'
AND `lm`.`CreateTime` <= '2021-07-13 23:59:59'
AND lm.GoodsId IN (224, 225, 272, 1224, 10011, 10007)
ORDER BY lm.`OrderID` desc
LIMIT 30;
explain计划
具体sql如上,CreateTime 和GoodsId有索引,OrderID是主键,总表2000w数据,通过条件筛选出来的数据只有20条,
但是通过OrderID排序,然后limit 的时候 就非常慢,需要十几秒,
尝试过几种其他情况,比如
修改排序字段为 CreateTime,或者OrderID, CreateTime,
或者修改Limit 后面的数量改为小于等于20的数,
去除limit或者去除order by
查询都很快。
实在没法理解这样的原因,按照mysql的执行顺序,order limit最后执行,我前面的结果集大小才20条,排序也是应该是排序这20条啊,使用limit后为什么会这么慢
你看下他走的那个索引,
大概率是在走 OrderID 索引
mysql?如果去掉orderby,多久能查到?
去掉order by 秒查的
SELECT *
FROM table lm
WHERE lm
.CreateTime
>= '2021-07-13'
AND lm
.CreateTime
<= '2021-07-13 23:59:59'
AND lm.GoodsId IN (224, 225, 272, 1224, 10011, 10007)
ORDER BY lm.OrderID
desc
LIMIT 30;
select * from table as a left join (
SELECT OrderID
FROM table lm
WHERE lm
.CreateTime
>= '2021-07-13'
AND lm
.CreateTime
<= '2021-07-13 23:59:59'
AND lm.GoodsId IN (224, 225, 272, 1224, 10011, 10007) ) as b on a.OrderID = b.OrderID ORDER BY a.OrderID desc limit 30
慢的是因为你这个里in 这几个字段CreateTime,GoodsId 单独加一个索引式式
这些都有索引的,上面说了的
@秦随境迁: 你把SQL执行分析结果 截图发上来看看了
@为乐而来: 上面的图就是explain 结果啊
换成 BETWEEN and试试,或者先查出来一部分,二次在查询排序试试
select * from
(
SELECT *
FROM table lm
AND lm.GoodsId IN (224, 225, 272, 1224, 10011, 10007)
) as lm2
WHERE lm2.`CreateTime` BETWEEN '2021-07-13 00:00:00' and '2021-07-13 23:59:59'
ORDER BY lm2.`OrderID` desc
LIMIT 30;
索引走的有问题,你的rows不应该有3万多条吧
这个问题解决了吗?感觉语句本身并没什么问题,可以考虑执行语句前清除缓存测试效果
这里应该和你的 * 有关没走索引
SELECT id
FROM table
where id in (
SELECT id
FROM table lm
WHERE lm
.CreateTime
>= '2021-07-13'
AND lm
.CreateTime
<= '2021-07-13 23:59:59'
AND lm.GoodsId IN (224, 225, 272, 1224, 10011, 10007)
ORDER BY lm.OrderID
desc
LIMIT 30;
)