為什麼相同的執行計劃在某些情況下會導致 LOB 讀取?
我有一個
spatial
索引和以下查詢:SELECT DS2.[ID] ,DS2.[InstanceID] ,DS2.[Location].STDistance(@Location) FROM [dbo].[DataSource01] DS1 INNER JOIN [dbo].[DataSource02] DS2 WITH (INDEX = [IX_DataSource02_Location]) ON DS1.[ID] = DS2.[ID] WHERE DS2.[Location].STDistance(@Location) < 144840.96; -- 90 miles in meters
其中
@Location
是目前使用者位置。對於兩個不同的使用者,我得到兩個不同的執行時間 - 0 秒和 5 秒,我想了解是什麼原因造成的。我得到兩個相同的執行計劃:
一切似乎都一樣,除了
Filter
運算符 - 在較快的情況下,返回 5 k 行,而在另一種情況下返回 1.8 k 行。我比較了兩個查詢的讀取,似乎第二個正在執行大量 LOB 讀取:
我想知道當計劃相同並且每個運算符的數據大小和行相同(除了那個
Filter
)時,什麼會導致這樣的 LOB 讀取?運算符還有另一個區別
Clustered Index Seek(Spatial)
-Number of Executions
較快的查詢是 1142,而較慢的是 1180。
Warnings
運算符的Clustered Index Seek (Spatial)
是Columns With No Statistics
。它們是Column Reference
:[extended_index_1523900896_384000].Attr [extended_index_1523900896_384000].pk0 [extended_index_1523900896_384000].pk1
執行計劃-慢查詢:http ://dox.bg/files/dw?a=c133c2a7fb
執行計劃——快速查詢:http ://dox.bg/files/dw?a=24818510fb
查詢在相同的硬體上執行。
比較這兩個計劃揭示了這個片段:
<Warnings> <SpillToTempDb SpillLevel="1" /> </Warnings>
這兩個計劃以相同的記憶體授權進入執行,但一個具有實際的 3910 行(和溢出),而另一個具有 1502 行。據我所知,差異來自空間運算符本身。所以最終你看到的執行時差異來自實際的空間數據。我還可以看到,您計算距離的實際點不同:
<ColumnReference Column="@Location" ParameterRuntimeValue="POINT (-75.549 39.7366)" /> <ColumnReference Column="@Location" ParameterRuntimeValue="POINT (-83.6026 41.6721)" />
溢出並有更多行要處理的計劃是您標記為“FAST”的計劃。你確定你沒有貼錯標籤嗎?溢出更慢更有意義。
只能在幾何或地理數據類型上創建空間索引。這意味著您的位置數據類型必須是其中之一。
兩個使用者是在同一個盒子還是在不同的位置執行這個查詢?
兩個使用者都有不同的位置,這意味著索引搜尋搜尋(B+樹)單個使用者的位置將在不同的 Deepest-Cell 相遇。
比較兩個執行計劃給出不同的邏輯讀取,因為兩者都在為索引搜尋掃描不同的參數值。當條件比較不同的@location時,因為每個使用者有不同的@location,這也是邏輯讀取不同的原因。
空間索引工作細節… https://www.simple-talk.com/sql/t-sql-programming/sql-server-spatial-indexes/