Sql-Server

為什麼相同的執行計劃在某些情況下會導致 LOB 讀取?

  • July 28, 2016

我有一個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/

引用自:https://dba.stackexchange.com/questions/144403