2017-02-01 35 views
1

我有一個ZipCodes表,它包含美國和加拿大的郵政編碼和相關信息 - 包括經度和緯度。使用子查詢提高UPDATE查詢的性能

我有記錄被插入到我不能修改的單獨應用程序的表中。這些記錄缺少經度和緯度數據,所以我想相應地填充記錄。 (在任何人詢問之前,在運行時與ZipCodes表進行聯接似乎不是一種選擇,因爲性能,這就是爲什麼我已經結束了我在哪裏)

我有如下所示的查詢,它將被設置爲按計劃任務運行,應該更新尚未查找其地理數據的任何記錄。此查詢(每次100個)需要大約1分35秒才能運行。

我正在尋求任何和所有的選擇,我在這裏做什麼,這可能會提高性能。

我使用了一個計劃任務,因爲我擔心整個服務器都會被INSTEAD OF INSERT或AFTER INSERT觸發器絆倒,以此來做同樣的事情...但這一直是我的首選。鑑於當前的性能問題,觸發器似乎不可能。

ZipCodes表在CityName和ProvinceAbbr上有一個非聚集索引,其中還包括了PostalCode,Latitude和Longitude列。我有允許行鎖和允許頁鎖設置爲false。這個表格中的數據會每個季度改變一次MAYBE,所以髒讀數很好。

如果需要,我可以提供執行計劃結果......但不知道如何給我提示如何生成複製/粘貼材料。 = D

ZipCodes表有947,172條記錄,並且LoadsAvail表在任何給定時間都有大約38k條記錄......記錄正在實時/不斷地被插入,更新和刪除,有時候會以較大的批量(I' d一次最多插入20個,通常更像一次一個或兩個插入)。

一旦大部分記錄都有其地理數據,每分鐘可能少於100個記錄被更新,但我想知道是否有更好的方法來完成所有這些。

UPDATE TOP (100) 
    LoadsAvail 

SET 
    coordinatesChecked = 1, 
    FromLatitude = ( SELECT TOP (1) Latitude 
             FROM ZipCodes AS ZipCodes_1 WITH(NOLOCK) 
             WHERE (CityName = loadsavail.FromCity) AND (ProvinceAbbr = loadsavail.FromState) 
            ), 
    FromLongitude = ( SELECT TOP (1) Longitude 
             FROM ZipCodes AS ZipCodes_2 WITH(NOLOCK) 
             WHERE (CityName = loadsavail.FromCity) AND (ProvinceAbbr = loadsavail.FromState) 
            ), 
    ToLatitude = ( SELECT TOP (1) Latitude 
            FROM ZipCodes AS ZipCodes_3 WITH(NOLOCK) 
            WHERE  (CityName = loadsavail.ToCity) AND (ProvinceAbbr = loadsavail.toState) 
           ), 
    ToLongitude = ( SELECT TOP (1) Longitude 
            FROM ZipCodes AS ZipCodes_4 WITH(NOLOCK) 
            WHERE  (CityName = loadsavail.ToCity) AND (ProvinceAbbr = loadsavail.toState) 
           ) 
WHERE 
    coordinatesChecked = 0 
+1

我只想離開這個位置。 http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

+0

是的,我讀過。這似乎更適合使用NOLOCK - 一個用作查找表的表,有大量數據,每隔一個季度就會改變MAYBE一次? –

+0

如果數據不會頻繁改變,那麼提示可能不會損害任何東西....但是這不可能會有幫助,因爲數據不會被鎖定。 :) –

回答

3

可以使用加入的代替子查詢

UPDATE T1 
SET T1.coordinatesChecked = 1, 
    T1.FromLatitude = T2.Latitude, 
    T1.FromLongitude = T2.Longitude 
    T1.ToLatitude = T3.Latitude, 
    T1.ToLongitude = T3.Longitude 
FROM   LoadsAvail AS T1 LEFT JOIN ZipCodes AS T2 ON T1.FromCity = T2.CityName AND T1.FromState = T2.ProvinceAbbr 
           LEFT JOIN ZipCodes AS T3 ON T1.toCity = T3.CityName AND T1.toState = T3.ProvinceAbbr 
WHERE T1.coordinatesChecked = 0 
+0

如果爲CityName和ProvinceAbbr找到多條記錄,這項工作是否可行?由於它是一個郵政編碼數據庫,通常城市/州組合有多個郵政編碼。你覺得這個查詢會更快嗎? –

+0

是的,我會工作,你可以檢查查詢執行計劃。我認爲這種方法比對每行更新執行4個子查詢更好 – Hadi

+0

這是很好的檢查執行計劃並給我們一個反饋 – Hadi