我的查询出现问题需要17秒才能执行(350k行):
SELECT idgps_unit, MAX(dt)
FROM gps_unit_location
GROUP BY 1
解释
1 SIMPLE gps_unit_location index fk_gps2 5 422633
玩完之后,我带来了这个需要1秒的解决方案:
Select idgps_unit, MAX(dt) from (
SELECT idgps_unit, dt
FROM gps_unit_location
) d1
Group by 1
说明:
1 PRIMARY <derived2> ALL 423344 Using temporary; Using filesort
2 DERIVED gps_unit_location index gps_unit_location_dt_gpsid 10 422617 Using index
现在我很困惑 - 为什么查询#2很快,而查询#1似乎是相同的查询,似乎写得更有效。
Index1:DT,Index2:idgps_unit,Index3:idgps_unit + DT
执行时间一致;查询#1总是需要17-19秒;而#1&lt; 1sec。
我正在使用Godaddy VPS Windows Server 2008经济版
表示例:
id | idgps_unit | dt | location
1 | 1 | 2012-01-01 | 1
2 | 1 | 2012-01-02 | 2
3 | 2 | 2012-01-03 | 3
4 | 2 | 2012-01-04 | 4
5 | 3 | 2012-01-05 | 5
答案 0 :(得分:1)
我会说你的索引没有正确设置,你的第二个查询是一种内部查询,它有效地创建了自己的内部索引组,如果这有意义的话!
答案 1 :(得分:1)
首先,我假设gps_unit_location
实际上是一个表而不是一个视图。其次,我还假设您已多次运行两个查询,因此缓存不是解释。 (缓存是你运行第一个查询,它将表加载到页面缓存中,第二个从内存而不是磁盘读取。)
你有gps_unit_location(idgps_unit)
的索引吗?记录非常广泛吗?如果这些问题的答案为“是”,则可能发生以下情况。
如果是这样,您可能会对索引有一个奇怪的问题。你会认为索引会加速这样的查询。但它的作用是按顺序查找idgps_id
中的值。如果索引不包含日期,则数据库需要从每个页面获取数据。如果表不适合内存,那么这通常会导致缓存未命中 - 也就是加载页面的时间。
相比之下,如果表格很宽并且引擎进行全表扫描,那么它可以在表格中拉链并提取感兴趣的两个字段。它把它们放在一边。如果它们相对于整个表格较小,那么对它们进行排序可能只需要很少的时间。瞧,查询结束得更快。
我的猜测是第二个结构会删除索引的使用。
顺便说一下,您可以通过将索引更改为gps_unit_location(idgps_unit, dt)
来解决此问题。通过在索引中包含该字段,查询不必加载数据。