当我在MariaDB 10.1 / MySQL 5.7中执行下面的查询时,结果有849行,并在0,016秒内执行。
SELECT a.*
FROM bco_dav_dm.d_ttlz_cli a
WHERE FL_ATND_FNAL = 0
AND a.ID_ATND = 218
ORDER BY A.FL_CRTR, A.DT_PRMR_ATVC_LNHA;
但是当我添加LIMIT子句只返回1行时,查询会在9秒内执行!为什么?
我测试过: 使用LIMIT 1,查询在9秒内执行。 使用LIMIT 2,查询在9秒内执行。 使用LIMIT 3,查询在9秒内执行。 使用LIMIT 4及以上(5,6,7,8 ... 100,200,300,400),查询在0,016秒内执行!!!
我已经多次测试过,而且我总是得到相同的结果。
我将如何在Web App中使用此查询,我只需要1条记录,我不知道为什么LIMIT< = 3会减慢查询速度!
在其他帖子中,使用更高OFFSET的会话自然会减慢查询速度,但我不会使用OFFSET。
我的解释:
select_type: SIMPLE
table:a
type:ref
possible_keys:ID_ATND,FL_ATND_FNAL
key:ID_ATND
key_len:5
ref:const
rows:1846
Extra: Using where; Using filesort
编辑:
我注意到当我使用LIMIT 3或低于我的解释变化时
select_type: SIMPLE
table:a
type:ref
possible_keys:ID_ATND,FL_ATND_FNAL
key:ORDER_BY_CRTR_DT
key_len:6
ref:const
rows:1764
Extra: Using where
索引ORDER_BY_CRTR_DT是我在ORDER BY中使用的组合索引
INDEX ORDER_BY_CRTR_DT(FL_CRTR, DT_PRMR_ATVC_LNHA);
答案 0 :(得分:1)
基于成本的优化器会根据不同的限制查看情况略有不同,在这种情况下,只是得到了明显的错误。您会更频繁地看到这种奇怪的行为,并且几乎都是基于成本的数据库。
在这种情况下,您看到差异的位置在另一个计划中的所选索引ORDER_BY_CRTR_DT
和ID_ATND
中,然后数据库将使用该位置来估计行数。看到较少的行数,基于成本的优化器假定查询更快(简化的视点)。
有时可以帮助重建表和索引,以便它们都能在描述数据的直方图中获得有关数据的最新信息。随着时间的推移,由于插入,更新和删除,结果可能会再次发生变化,导致计划再次降级。然而,通常通过定期重建来实现计划的稳定。
备选方案您可以强制使用索引,因此对此计划禁用基于成本的优化程序。然而,这可能会像基于成本的优化器现在失败一样适得其反。
第二种方法是删除索引,该索引为您提供9s结果,如果未使用或对其他查询影响不大,则可能是一个选项。