我有一张拥有170,000条记录的拥抱表。
此查询之间有什么区别
Showing rows 0 - 299 (1,422 total, Query took 1.9008 sec)
SELECT 1 FROM `p_apartmentbuy` p
where
p.price between 500000000 and 900000000
and p.yard = 1
and p.dateadd between 1290000000 and 1320000000
ORDER BY `p`.`id` desc
limit 1669
解释
这一个:
Showing rows 0 - 299 (1,422 total, Query took 0.2625 sec)
SELECT 1 FROM `p_apartmentbuy` p
where
p.price between 500000000 and 900000000
and p.yard = 1
and p.dateadd between 1290000000 and 1320000000
ORDER BY `p`.`id` desc
limit 1670
说明:
这两个查询都使用1个具有相同数据的表,并且具有相同的where clasue,但只限制行数不同
答案 0 :(得分:3)
MySQL有一个用于排序的缓冲区。当要排序的东西太大时,它会对块进行排序,然后合并它们。这称为“filesort”。你的第1670行显然只是溢出了排序缓冲区。
阅读更多详情here。
现在为什么它为内存排序选择另一个键...我不太确定;但显然它的策略不太好,因为它最终会变慢。
答案 1 :(得分:1)
回顾:奇怪的是返回更多行的查询运行得更快
这与缓冲区与文件排序无关,排序1400条记录的时间不到1秒
第一个解释显示查询优化器执行线性扫描,第二个解释使用索引显示它。即使是部分有用的索引通常也比没有索引要好得多。
在内部,mysql维护有关索引大小的统计信息,并尝试猜测哪个索引,或者线性扫描是否会更快。这个估计是特定于数据的,我看到mysql使用正确的索引99次中的100次,但是每次都选择不同的并且运行查询的速度要慢50倍。
您可以覆盖内置查询优化器并指定要手动使用的索引,使用SELECT ... FROM ... FORCE INDEX(...)