2010-09-23 112 views
1

我有一個表foo它記錄鳥類的目擊。 foo_id是它的PK,其他有關的列是s_date,緯度和經度。 species_id是它的FK。我有索引s_date,經度和緯度species_id。表富有2000萬條記錄並且在不斷增加。 以下查詢給出了給定緯度/長度的前10個最新物種目擊。查詢花費的時間太多(有時候超過10分鐘)。如何優化它?我正在使用mysql。優化查詢

SELECT species_id, max(s_date) 
FROM foo 
WHERE latitude >= minlat 
    AND latitude <= maxlat 
    AND longitude >= minlon 
    AND longitude <= max lon 
GROUP BY species_id 
ORDER BY MAX(s_date) DESC LIMIT 0, 10; 
+0

另外適當的索引,有沒有一大堆優化... – 2010-09-23 19:11:13

+0

是species_id一個真正的FK,與它的索引和約束,或FK只是它的暱稱? – Midhat 2010-09-23 19:13:00

+0

我認爲FK「暱稱」更適合它的定義 – androidharry 2010-09-23 19:24:54

回答

0

我知道你在提到的字段上有單獨的索引。你可能想嘗試(latitude, longitude)增加一個綜合指數(又名多列索引):

CREATE INDEX ix_foo_lat_lng ON foo (latitude, longitude); 

您可能需要您的查詢運行EXPLAIN看什麼指數(ES),MySQL的使用。從MySQL Manual :: How MySQL Uses Indexes報價:

假設你發出以下聲明SELECT

mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2; 

如果col1col2存在多列索引,適當的行可以直接取出。如果在col1col2上存在單獨的列索引,優化程序將嘗試使用Index Merge optimization,或者嘗試通過確定哪個索引找到更少的行並使用該索引來獲取行來嘗試查找最具限制性的索引。

您還可能有興趣在檢查出下面的介紹:

筆者介紹瞭如何使用Haversine Formula在MySQL的命令接近和限制您的搜索到一個定義的範圍。他還介紹瞭如何使用經緯度列上的傳統索引來避免此類查詢的全表掃描。


PDF Version

+0

感謝您的答案。有關通過按部件順序優化組的任何建議? – androidharry 2010-09-23 19:32:50

+0

@androidharry:如果'(緯度,經度)'上的複合索引起作用,並且將結果集限制爲幾行,那麼'GROUP BY'應該會自動很快。現在它很慢,因爲(查看上面的註釋)你的查詢只是使用'longitude'索引,所以中間結果集非常大。 – 2010-09-23 19:39:02

+0

我已經在使用類似於演示文稿中所示的內容。我從http://www.movable-type.co.uk/scripts/latlong-db.html找到了這個公式。它正在使用地球半徑進行計算,而在演示中正在使用69英里。我想知道哪一個是正確的? – androidharry 2010-09-24 06:08:05