And*_*rew 5 mysql sql performance database-performance
我的查询问题需要17秒才能执行(350k行):
SELECT idgps_unit, MAX(dt)
FROM gps_unit_location
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)
说明
1 SIMPLE gps_unit_location index fk_gps2 5 422633
Run Code Online (Sandbox Code Playgroud)
玩完之后,我带来了这个需要1秒的解决方案:
Select idgps_unit, MAX(dt) from (
SELECT idgps_unit, dt
FROM gps_unit_location
) d1
Group by 1
Run Code Online (Sandbox Code Playgroud)
说明:
1 PRIMARY <derived2> ALL 423344 Using temporary; Using filesort
2 DERIVED gps_unit_location index gps_unit_location_dt_gpsid 10 422617 Using index
Run Code Online (Sandbox Code Playgroud)
现在我很困惑 - 为什么查询#2很快,而查询#1似乎是相同的查询,似乎写得更有效率.
Index1:DT,Index2:idgps_unit,Index3:idgps_unit + DT
执行时间是一致的; 查询#1总是需要17-19秒; 而#1 <1秒.
我正在使用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
Run Code Online (Sandbox Code Playgroud)
首先,我假设它gps_unit_location实际上是一个表而不是视图。其次,我还假设您已多次运行这两个查询,因此缓存不是解释。(缓存是指您运行第一个查询,它将表加载到页面缓存中,第二个查询从内存而不是磁盘中读取。)
你有索引吗gps_unit_location(idgps_unit)?记录范围很广吗?如果这些问题的答案是“是”,那么可能会发生以下情况。
如果是这样,您可能会遇到一个奇怪的索引问题。您可能会认为索引会加速此类查询。不过,它的作用是按顺序查找值idgps_id。如果索引不包含日期,则数据库需要从每个页面获取数据。如果该表无法装入内存,那么这通常会导致缓存未命中,即加载页面的时间过长。
相比之下,如果表很宽并且引擎执行全表扫描,那么它可以快速浏览表并提取感兴趣的两个字段。这让他们站在一边。如果它们相对于整个表来说很小,那么对它们进行排序可能会花费很少的时间。瞧,查询完成得更快。
我的猜测是第二个结构取消了索引的使用。
顺便说一句,您可以通过将索引更改为 来解决此问题gps_unit_location(idgps_unit, dt)。通过将字段包含在索引中,查询不必加载数据。
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |