2013-02-19 45 views
5

我與我的查詢花了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似乎是相同的查詢,似乎寫得更有效。

指數1:DT,索引2: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 
+0

mysql或tsql?!? – 2013-02-19 17:06:14

+2

這兩個查詢的執行時間是否一致?因爲當第一個查詢被執行並被第二個查詢使用時,結果可能會被緩存。 – Slowcoder 2013-02-19 17:08:20

+0

如果您可以在這些查詢上發佈運行'EXPLAIN'的結果,可能會有所幫助。 – 2013-02-19 17:14:19

回答

1

首先,我假設gps_unit_location真的是一張表,而不是一個視圖。其次,我還假設你已經多次運行這兩個查詢,所以緩存不是解釋。 (高速緩存將是運行第一個查詢,它加載到表頁面緩存和內存,而不是磁盤讀取第二)

你對gps_unit_location(idgps_unit)的指數?記錄非常廣泛嗎?如果這些問題的答案是「是」,那麼可能會發生以下情況。

如果是這樣,您可能會對索引有一個奇怪的問題。你會認爲索引會加快這樣的查詢。但它的作用是按順序查找idgps_id中的值。如果索引不包含日期,那麼數據庫需要從每個頁面獲取數據。如果表格不適合內存,那麼這通常會導致緩存未命中 - 也就是加載頁面的時間。

相比之下,如果表格很寬並且引擎執行全表掃描,那麼它可以壓縮表格並提取兩個感興趣的字段。它把他們放在一邊。如果它們相對於整個桌子很小,那麼排序它們可能花費很少的時間。瞧,查詢完成得更快。

我的猜測是第二個結構會刪除索引的使用。

順便說一下,您可以通過將索引更改爲gps_unit_location(idgps_unit, dt)來解決此問題。通過在索引中包含該字段,查詢不必加載數據。

+0

'gps_unit_location(idgps_unit,dt)'解決了這個問題!謝謝! – Andrew 2013-02-19 19:13:44

1

我會說你的指數法沒有設置正確,你的第二個查詢是一種內部查詢是有效的如果有意義的話,創建自己的內部索引組!