2011-08-19 67 views
0

我需要返回數據庫中與給定點相當接近的所有條目。目前,我這樣做(在WHERE部分):查詢中的簡單功能

OR ( 
    (Addresses.Latitude IS NOT NULL) 
    AND (Addresses.Longitude IS NOT NULL) 
    AND (Abs(Addresses.Latitude - @SearchInLat) < 0.5) 
    AND (Abs(Addresses.Longitude - @SearchInLng) < 0.5) 
) 

我做的曼哈頓距離而不是笛卡爾距離我的數據庫有大量的記錄,並計算平方根是緩慢的。

我對SQL數據庫相當陌生,但我記得在SELECT procudures中有一些函數被認爲效率很差。這是否甚至適用於真正簡單的功能,如取絕對值?是這樣的:

OR ( 
    (Addresses.Latitude IS NOT NULL) 
    AND (Addresses.Longitude IS NOT NULL) 
    AND ((Addresses.Latitude - @SearchInLat) < 0.5) 
    AND ((Addresses.Latitude - @SearchInLat) > -0.5) 
    AND ((Addresses.Longitude - @SearchInLng) < 0.5) 
    AND ((Addresses.Longitude - @SearchInLng) > -0.5) 
) 

更好的解決方案?

+0

我想你的意思是在第二個例子中刪除ABS。 –

+0

我做了,謝謝。在提交之前我總是閱讀兩遍,但總是看起來錯過了一些東西! – Oliver

回答

5

在返回的數據上運行函數通常效率不高 - 就像您的ABS一樣。不過,我認爲在這種情況下你不會遇到麻煩。你可以通過嘗試類似的方式來避免使用該功能:

OR ( 
    (Addresses.Latitude IS NOT NULL) 
    AND (Addresses.Longitude IS NOT NULL) 
    AND ((Addresses.Latitude - @SearchInLat) BETWEEN -0.5 AND 0.5) 
    AND ((Addresses.Longitude - @SearchInLng) BETWEEN -0.5 AND 0.5) 
+0

太好了,謝謝。我不知道有這樣的語法。我試過'-0.5 <(Addresses.Latitude - @SearchInLat)<0.5',但那是無效的。 – Oliver

+1

請注意,這有些不同。原文是'>'和'<'; 'BETWEEN'實際上是'> ='和'<='... –

+0

如果將它改爲'Addresses.Latitude BETWEEN -0.5 - @SearchInLat AND 0.5 - @ SearchInLat'會更好,因爲終點只需要計算一次。 –

2

我認爲ABS和一些內置函數(如數學函數)很容易被優化器處理 - 其他的不是很多(字符串和日期操作)。

在你的特殊情況下,我認爲你可以使用ABS。

+0

感謝您的提示。處理優化器非常痛苦!一個微小的變化可以讓它以完全不同的方式工作。我發現很難確定什麼東西有幫助,什麼東西阻礙。 – Oliver