東坡下載:內(nèi)容最豐富最安全的下載站!

首頁知識庫編程開發(fā) → 在SQL Server中Not In子查詢性能分析

在SQL Server中Not In子查詢性能分析

相關(guān)文章發(fā)表評論 來源:本站整理時(shí)間:2017/11/25 9:22:56字體大。A-A+

更多

作者:專題點(diǎn)擊:43次評論:0次標(biāo)簽: SQLServer

Not In的主要問題是由于對Null值的處理問題所導(dǎo)致,那么對Null值的處理究竟為什么會(huì)導(dǎo)致性能問題?讓我們來看圖5的示例。圖5中,我們使用了Adventurework示例數(shù)據(jù)庫,并為了演示目的將SalesOrderDetail表的ProductId的定義由Not Null改為Null,此時(shí)我們進(jìn)行一個(gè)簡單的Not In查詢。如圖5所示。

圖5.Not In的執(zhí)行計(jì)劃

在圖5中,我們看到一個(gè)Row Count Spool操作符,該操作符用于確認(rèn)ProductId列中是否有Null值(過程是對比總行數(shù)和非Null行數(shù),不想等則為有Null值,雖然我們知道該列中沒有Null值,但由于列定義是允許Null的,因此SQL Server必須進(jìn)行額外的確認(rèn)),而該操作符占用了接近一半的查詢成本。因此我們對比Not Exists,如圖6所示。

圖6.Not In Vs Not Exists

由圖6可以看出,Not In的執(zhí)行成本幾乎是Not Exists的3倍,僅僅是由于SQL Server需要確認(rèn)允許Null列中是否存在Null。根據(jù)圖3中Not In的等價(jià)形式,我們完全可以將Not In轉(zhuǎn)換為等價(jià)的Not Exist形式,如圖7所示。

圖7.Not In轉(zhuǎn)換為Not Exists

我們來對比圖7和其等價(jià)Not In查詢的成本,如圖8所示。

圖8.成本上完全等價(jià)

因此我們可以看到Not In需要額外的步驟處理Null值,上述情況是僅僅在SalesOrderDetail表中的ProductId列定義為允許Null,如果我們將SalesOrderHeader的SalesOrderID列也定義為允許Null時(shí),會(huì)發(fā)現(xiàn)SQL Server還需要額外的成本確認(rèn)該列上是否有Null值。如圖9所示。

圖9.SQL Server通過加入Left Anti Semi Join操作符解決列允許Null的問題

此時(shí)Not In對應(yīng)的等價(jià)Not Exist形式變?yōu)槿绱a清單1所示。

SELECT  *FROM    Sales.SalesOrderHeader aWHERE   NOT EXISTS ( SELECT *FROM   Sales.SalesOrderDetail bWHERE  a.SalesOrderID = b.ProductID )AND NOT EXISTS ( ( SELECT   *FROM     Sales.SalesOrderDetail bWHERE    b.ProductID IS NULL) )AND NOT EXISTS ( SELECT 1FROM   ( SELECT    *FROM      Sales.SalesOrderHeader) AS cWHERE  c.SalesOrderID IS NULL )

代碼清單1.當(dāng)連接列兩列定義都允許Null時(shí),Not In等價(jià)的Not Exists形式

此時(shí)我們簡單對比Not In和Not Exists的IO情況,如圖10所示。

圖10.Not In吃掉很高的IO

擴(kuò)展知識

相關(guān)評論

閱讀本文后您有什么感想? 已有 人給出評價(jià)!

  • 2791 喜歡喜歡
  • 2101 頂
  • 800 難過難過
  • 1219 囧
  • 4049 圍觀圍觀
  • 5602 無聊無聊
熱門評論
最新評論
發(fā)表評論 查看所有評論(0)
昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)