2010-06-21 54 views
0

我有一個MySQL查詢,根據標準從數據庫中提取經緯度,測試這些點是否在多邊形內,並返回多邊形內的點。有沒有一種方法可以優化在每一行上運行函數的MySQL查詢?

一切工作正常。問題是查詢需要大約。 20秒返回結果。有沒有一種方法來優化此查詢,以便查詢速度更快?

SELECT latitude, longitude 
FROM myTable 
WHERE offense = 'green' AND myWithin(
POINTFROMTEXT(CONCAT('POINT(', latitude, ' ', longitude, ')')) , POLYFROMTEXT('POLYGON((...bunch of lat longs...))') 
) = 1; 

我跑了EXPLAIN SELECT ...它生產

ID | select_type |表| |鍵入| possible_keys |鍵| key_len | ref | 行|額外

1 SIMPLE myTable的所有NULL NULL NULL NULL 137003使用其中

有沒有一種方法來優化其在數據庫的每個緯度和經度運行或者是這是好得不能再好查詢?

我在考慮做一個選擇到另一個表,然後查詢結果表,但我希望有一種方法來提高此查詢的性能。

如果有人有任何建議或意見,我很樂意聽到他們。

感謝,

Laxmidi

回答

1

多邊形有多大?你可以定義一個「邊框」,圍繞整個多邊形,然後做:

SELECT latitude, longitude 
FROM myTable 
WHERE 
    offense = 'green' AND 
    latitude BETWEEN rect_left AND rect_right AND 
    longitude BETWEEN rect_top AND rect_bottom AND 
    myWithin(
    POINTFROMTEXT(CONCAT('POINT(', latitude, ' ', longitude, ')')), 
    POLYFROMTEXT('POLYGON((...bunch of lat longs...))')) = 1; 

這樣一來,它可以使用緯度和經度的索引來縮小點的數量,它具有運行復雜的東西上。

+0

嗨codeka, 多邊形是鄰里。它們形狀不規則。 有沒有辦法運行MBRContains和myWithin函數?據我瞭解,MBRContains給出了誤報。它是否會給出錯誤的否定?如果沒有,也許這將是一個解決方案。如果有一種方法可以與myWithin函數一起使用MBRContains,那麼我可以避免爲每個鄰域添加邊界矩形的列。喜歡聽你的想法。我認爲「邊界矩形」是一個好主意。 – Laxmidi 2010-06-21 22:46:55

+0

您不必爲邊界矩形添加列,這很容易計算。只要拿出你的「一堆經緯度」並計算最小和最大緯度 - 分別是'rect_left'和'rect_right'。 「一堆經緯度」的最小和最大經度分別是'rect_bottom'和'rect_top'。在運行查詢之前,您可以簡單地計算該值。 – 2010-06-22 01:08:29

+0

嗨Dean, 感謝您的留言。非常好的一點。我沒有想到這一點。問題解決了。非常感謝。 – Laxmidi 2010-06-24 15:23:44

0

我看到優化兩個明顯的途徑:

  • 降低的結果集越多,你運行你的函數O(n)時間之前。現在,您正在運行137003次函數 - 如果您無法進一步篩選結果集,則無法避免這種情況。

  • 使函數更快,這樣您仍然運行它137K次,但每次調用都需要更少的時間,從而減少了總運行時間。

現在你的函數每行運行0.1459毫秒,這真的不錯。您可能想嘗試找到一些方法來進一步減少要運行它的行數。通過巧妙地使用WHERE來減少結果集也具有讓您的數據庫爲您做一些優化的好處,這就是您想要如何使用它的好處。

+0

嗨尼克, 謝謝你的留言。我很高興我的功能運行得相當快。我必須努力減少函數運行的次數。 我真的很感謝你的幫助。 – Laxmidi 2010-06-22 00:07:03

相關問題