国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

使用正確的篩選參數來提高查詢性能

2024-07-21 02:46:25
字體:
來源:轉載
供稿:網友
使用正確的篩選參數來提高查詢性能

在今天的文章里我想談下SQL Server里與索引相關的特殊性能問題。

問題描述

假設下列的簡單查詢,在你的日常SQL Server里,這樣的查詢你已經看到過幾百遍了:

1 -- Results in an Index Scan2 SELECT * FROM Sales.SalesOrderHeader3 WHERE YEAR(OrderDate) = 2005 AND MONTH(OrderDate) = 74 GO

用那個簡單查詢,我們請求在特定年份特定月份里的銷售信息。并不復雜。遺憾的是這個查詢性能很差——即使在OrderDate列使用了非聚集索引。當你查看執行計劃時,你會看到查詢優化器選擇了在OrderDate列上的非聚集索引,但遺憾的是SQL Server進行的索引的全掃描,而不是高效的查找操作。

這真不是SQL Server的局限性,而是關系數據庫的工作和思考方式:)只要你在索引列上使用了表達式(函數調用,計算)(即所謂的篩選參數(Search Argument)),數據庫引擎必須去掃描那個索引,而不是進行查找操作。

解決方法

在執行計劃里為了獲得可擴展的查找操作,你必須要換種方式重寫你的查詢來避免DATEPART函數的調用:

1 -- Results in an Index Seek2 SELECT * FROM Sales.SalesOrderHeader3 WHERE OrderDate >= '20050701' AND OrderDate < '20050801'4 GO

從重寫的查詢可以看到,查詢返回同樣的結果,但我們已經剔除了DATEPART函數的調用。當你查看執行計劃時,你會看到SQL Server進行了查找操作——在那個情況下,這個是所謂的局部范圍掃描(Partial Range Scan):SQL Server查找到第1個值,然后掃描到請求范圍的最有值。如果你想在索引列上下文調用函數,你必須保證在查詢里,這些函數調用的執行在你列的右側。我們來看一個具體的例子。下面查詢把CreditCardID索引列轉化為CHAR(4)數據類型:

1 -- Results in an Index Scan2 SELECT * FROM Sales.SalesOrderHeader3 WHERE CAST(CreditCardID AS CHAR(4)) = '1347'4 GO

當你仔細看執行計劃時,你會看到SQL Server再次掃描整個非聚集索引。如果你的表越來越大,這是真不能擴展的。如果你在查詢里在你索引列的右側執行轉化,你就可以在索引列上剔除函數調用,SQL Server就可以進行查找操作:

1 -- Results in an Index Seek2 SELECT * FROM Sales.SalesOrderHeader3 WHERE CreditCardID = CAST('1347' AS INT)4 GO

小結

從這篇文章里,你可以看到,在你的索引列里不直接調用任何函數或間接調用函數是非常重要的。不然的話SQL Server會掃描你的索引,而不是進行高效的查找操作。而且當你表越來越大時,掃描從不擴展。

如果你碰到這個特殊行為的其他好例子,想分享的話,歡迎留言。

感謝關注。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巴青县| 革吉县| 海丰县| 弥勒县| 崇礼县| 麻城市| 汤原县| 通许县| 嘉峪关市| 桂阳县| 沧源| 四子王旗| 固始县| 桃源县| 潼南县| 全州县| 南城县| 黑龙江省| 宜兴市| 芦山县| 丹阳市| 阿图什市| 仁寿县| 黑水县| 太仆寺旗| 云浮市| 吴桥县| 盱眙县| 同江市| 交口县| 周宁县| 克拉玛依市| 顺平县| 苏尼特左旗| 洞口县| 新平| 苗栗市| 云和县| 赤壁市| 松滋市| 沙坪坝区|