2016-03-08 104 views
4

我有這個疑問,實際上它是與此類似,這是爲測試目的:TOP性能問題

SELECT 
[Distinct1].[ProspectID] AS [ProspectID] 
FROM (SELECT DISTINCT 
    [Limit1].[ProspectID] AS [ProspectID] 
    FROM (SELECT TOP 10 
     [Extent1].[ProspectID] AS [ProspectID] 
     FROM [sqlsolvent].[crm_SearchTable] AS [Extent1] 
     WHERE ([Extent1].[CP_Name] LIKE '%dsd%' ESCAPE N'~') 
    ) AS [Limit1] 
) AS [Distinct1] 

這是它的執行計劃:

enter image description here

當我刪除TOP 10從查詢我得到這個執行計劃:

enter image description here

沒有TOP 10的第二個執行計劃速度提高了2倍,有人能解釋爲什麼TOP會如此改變執行計劃,爲什麼它會如此慢?即使查詢沒有返回任何結果,也不應該只將頂端添加到結果集中,爲什麼查詢在返回時什麼都不會影響性能?

+0

[TOP(以及爲什麼)TOP影響執行計劃?](http://dba.stackexchange.com/questions/24832/how-and-why-does-top-impact-an-execution-plan/ 24848#24848) –

回答

1

你可以參考它提供瞭解決方法

解決方法

要解決此問題support article from Microsoft,工藝,收集每個分區的TOP N 元素的查詢。然後,從該 元素集合中找到TOP N元素。

你可以參考這個article瞭解詳細內容:

頂級運營商,當由SELECT操作者調用,調用嵌套 循環運算符來獲得一排;將其返回給SELECT操作符;和 然後等待,直到它再次被調用 - 通常 發生得相當快,除非SELECT運算符必須等待 應用程序或網絡發出該行。同樣的事情發生了兩次 多次,但是當SELECT操作符第四次調用Top操作符 時,Top操作符將立即返回「 數據末尾」條件,而永遠不會打擾它的後代嵌套的 循環節點。無論SalesOrderHeader表有多少行,TOP條款保證永遠不會有多於三個 查找。我們在第一個計劃中使用的Sort運算符比 31,465查找要便宜,但比三次查找要貴得多。

+1

你爲什麼認爲這個關於分區表的問題也導致了OP的性能問題? –

+0

@TimSchmelter: - 老實說,我猜對了! –

2

注意,有一個在你的查詢時出現錯誤 - top必須與一些明確的排序被用來沿,否則結果的順序是不確定的,正因爲如此,在top的結果本身是不確定的。

我不能確定地告訴你發生了什麼事情,但強加顯式排序可能會讓你的結果更有意義 - 要麼它會允許更合理的執行計劃,要麼會讓你的「無頂」查詢更慢。

在任何情況下,在執行清晰操作之前,您都要施加一個排序和一個限制。雖然無頂端查詢可以使用索引來執行distinct(在整個表格上),但當您使用top時,這些查詢將不再可用,尤其是因爲您的過濾器不允許使用任何索引(like '%whatever%'是一種很好的方式殺死性能:))。由於distinct的列是聚簇索引,因此distinct實際上非常便宜 - 只要您可以使用該索引即可。總而言之,我會看看這兩個查詢如何執行更多的數據。這種放緩很可能會變成具有大量實際數據的加速 - 很難猜測這些東西:)

2

第二個查詢被拆分爲並行流,這取決於機器配置,會提高性能。 TOP運算符不會這樣做,因爲它試圖獲得儘可能多的行,直到TOP條件滿足爲止,而不是所有行。

如果where子句嚴格,表掃描需要掃描更多表,直到滿足TOP條件。如果where子句不嚴格(例如,它匹配總行數的很大百分比),那麼使用TOP的查詢可能比沒有TOP的查詢快。