SQL Server 2008 處理隱式數據類型轉換在執行計劃中的增強

通過如下測試驗證,首先建立數據分布不平均的測試表。

USE?tempdb GOCREATE?TABLE?_t( ????c?varchar(50) );CREATE?INDEX?IX_c?ON?_t(?c?);GO--?加入?10000?條數據INSERT?_tSELECT?(9999?+?id)?FROM(????SELECT?TOP?10000?id?=?ROW_NUMBER()?OVER(?ORDER?BY?GETDATE()?)????FROM?sys.all_columns?a,?sys.all_columns )ID --?將?100?-?10000?的數據變成相同值UPDATE?_t?SET?c?=?''?WHERE?c?>=?'10100'

然后通過 varhcar和nvarchar值分別測試滿足條件1條和滿足條件8900條的執行計劃預估行數。

ALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGOSELECT?*?FROM?_t?WHERE?c?=?'10005';?????--?實際1條GOSET?SHOWPLAN_ALL?OFF;GOALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGOSELECT?*?FROM?_t?WHERE?c?=?N'10005';?????--?實際1條GOSET?SHOWPLAN_ALL?OFF;GOALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGOSELECT?*?FROM?_t?WHERE?c?=?'';??????????--?實際9900條GOSET?SHOWPLAN_ALL?OFF;GOALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGOSELECT?*?FROM?_t?WHERE?c?=?N'';?????????--?實際9900條GOSET?SHOWPLAN_ALL?OFF;GO

得到的查詢計劃預估行數如下圖所示

SQL Server 2008 處理隱式數據類型轉換在執行計劃中的增強

從圖中顯示的預估數據行數可以看到,對于varchar值(不需要隱匿的數據類型轉換),其預估的結果是準確的。但對于nvarchar值,不管指定的值是只有一條數據,還是有8900條數據匹配,其預估的結果都是99.0099,這說明預估并沒有考慮我們指定的值。
進一步用變量測試

ALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGODECLARE?@v?varchar;SELECT?*?FROM?_t?WHERE?c?=?@v;?--?varcharGOSET?SHOWPLAN_ALL?OFF;GOALTER?INDEX?IX_c?ON?_t?REBUILD;GOSET?SHOWPLAN_ALL?ONGODECLARE?@nv?nvarchar;SELECT?*?FROM?_t?WHERE?c?=?@nv;?--?nvarcharGOSET?SHOWPLAN_ALL?OFF;GO

結果如下圖所示:
SQL Server 2008 處理隱式數據類型轉換在執行計劃中的增強

不管是varchar,還是nvarchar的變量,預估的行數都是99.0099,這個值與使用nvarchar常量值的結果一樣,看來sql Server查詢優化器應該確實把 GetRangeThroughConvert 的結果看成變量了,這個應該是設計上考慮不太周全的地方了,畢竟指定固定常量值的時候,GetRangeThroughConvert的結果應該也是確定值才對。

本文講解了SQL Server的相關內容,更多相關內容請關注php中文網。

相關推薦:

如何讓MySQL中單句實現無限層次父子關系查詢

如何讓MySQL中單句實現無限層次父子關系查詢

如何讓MySQL中單句實現無限層次父子關系查詢

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享