SQLServer索引调优实践(2)
继续,继续SQLServer索引调优实践。这次探讨一下索引覆盖 - SQL Server主要使用索引去查询你需要的数据,当索引包括所有的你请求查询的字段,SQL Server将不需要去在表中查询。这个概念称做索引覆盖。 SQLServer2005的Non-clustered INDEX增加了一个包含列(i
继续,继续SQLServer索引调优实践。这次探讨一下索引覆盖 - SQL Server主要使用索引去查询你需要的数据,当索引包括所有的你请求查询的字段,SQL Server将不需要去在表中查询。这个概念称做“索引覆盖”。
SQLServer2005的Non-clustered INDEX增加了一个“包含列(included column) ”选项。在 SQL Server 2005 中,可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。通过包含非键列,可以创建覆盖更多查询的非聚集索引。当查询中的所有列都作为键列或非键列包含在索引中时,带有包含性非键列的索引可以显著提高查询性能。这样可以实现性能提升,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。
但应避免添加不必要的列。添加过多的索引列(键列或非键列)会对性能产生不良影响,应该合理使用。和Clustered INDEX,或者组合索引,结合使用,扩大索引覆盖,但不大可能所有列都有索引覆盖,磁盘开销和数据insert updat时索引的重新计算的时间开销是巨大的。总之,合理的索引设计是建立在对各种查询的分析和预测上的,只有正确地使索引与程序结合起来,才能产生最佳的优化方案。
继续实践,先建个实验表 Table1:
建两个索引:
1. 主键ID是Clustered INDEX
2. 非聚簇索引Non-Clustered INDEX建立在Age列上,包含列:Count。
CREATE NONCLUSTERED INDEX [cnt] ON [dbo].[table1]
(
[Age] ASC
)
INCLUDE ( [Count])
ON [PRIMARY]
我们的测试SQL语句是:从10万条记录中取出4条记录,两种写法
1. SELECT * FROM table1 WHERE age 2. SELECT count FROM table1 WHERE age
看看运行效率如何:
磁盘IO和时间:
实际执行计划:
性能居然相差20多倍。为什么?
原来第二句Select Count在索引覆盖范围内,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。而第一句Select * 选择了所有字段,其中有一个字段Name不在索引覆盖范围内(既不在聚簇索引列,也不在非聚簇索引覆盖列内),SQL Server可以在同一个查询中为一个表使用多个索引,并可以合并多个索引(使用联接算法),以便搜索关键字共同覆盖一个查询。查询分析优化器会自动进行选择, 上述执行计划就是优化的结果,依然比第二个index seek慢了20倍。
然后我又把sql改了一下,变成从10万条记录中取得大部分数据( 返回99900条),小于号改成大于号:
1. SELECT * FROM table1 WHERE age > 100;
2. SELECT count FROM table1 WHERE age > 100;
看看结果:
磁盘IO和时间:
实际执行计划:
依然是第二句索引覆盖的快,这是毋庸置疑的。但第一句执行计划有所不同,SQLServer查询分析优化器选择了不同的策略,改为聚簇索引扫描。上面说过了,SQL Server可以在同一个查询中为一个表使用多个索引,并可以合并多个索引(使用联接算法),以便搜索关键字共同覆盖一个查询。查询分析优化器会自动进行选择, 上述执行计划就是优化的结果。
为何结果集较小和结果集较大SQLServer选择的索引方案不同?
(From园友 高强:当 WHERE age 100时,由于记录数比较多,所以SQL SERVER 认为直接根据聚集索引叶级页面链表扫描页面得出结果更快。不管怎样,最终目的就是在相同结果集情况下,尽可能减少逻辑IO。)
看到这儿,恐怕喜欢用Select*的同学也要节制一下使用了,有时候SQLServer中Select*代价是很高的。当然类似这种SQL是没有问题的,(where exists (select * from ...)),因为SQLServer查询分析优化器会聪明的知道此Select*非彼Select*。
数据库是一个很复杂的系统,即使你不是数据库专家,是应用开发人员,知道一点SQLServer内部更多的东西会有好处,而合理的索引设计是建立在对各种查询的分析和预测上的,只有正确地使索引与程序结合起来, 才能产生最佳的优化方案。
- SQLServer索引调优实践
或许您对以下文章有兴趣:
- 程序员办网站创业,几个问题你想好了吗?
- CTO谈豆瓣网和校内网技术架构变迁
- AJAX延迟异步加载边栏+服务器端缓存AJAX输出
- 二级下拉菜单被遮住,css设置z-index在ie下没作用的问题解决办法
- 简单JS实现走马灯效果的文字(无需jQuery)
- jQuery和ExtJS的timeOut超时设置和event事件处理

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

對於 SQL Server 資料庫中已存在同名對象,需要採取下列步驟:確認物件類型(表格、檢視、預存程序)。如果物件為空,可使用 IF NOT EXISTS 跳過建立。如果物件有數據,使用不同名稱或修改結構。使用 DROP 刪除現有物件(謹慎操作,建議備份)。檢查架構更改,確保沒有引用刪除或重新命名的物件。

匯入步驟如下:將 MDF 檔案複製到 SQL Server 的資料目錄(通常為 C:\Program Files\Microsoft SQL Server\MSSQL\DATA)。在 SQL Server Management Studio(SSMS)中,開啟資料庫並選擇「附加」。點選“新增”按鈕,選擇 MDF 檔案。確認資料庫名稱,點選確定按鈕即可。

當 SQL Server 服務無法啟動時,可採取下列步驟解決:檢查錯誤日誌以確定根本原因。確保服務帳戶具有啟動服務的權限。檢查依賴項服務是否正在執行。禁用防毒軟體。修復 SQL Server 安裝。如果修復不起作用,重新安裝 SQL Server。

若要查看 SQL Server 連接埠號碼:開啟 SSMS,連線到伺服器。在物件資源管理器中找到伺服器名稱,右鍵單擊它,然後選擇“屬性”。在「連線」標籤中,查看「TCP 連接埠」欄位。

SQL Server 資料庫檔案通常儲存在下列預設位置:Windows: C:\Program Files\Microsoft SQL Server\MSSQL\DATALinux: /var/opt/mssql/data可透過修改資料庫檔案路徑設定來自訂資料庫檔案位置。

若誤刪 SQL Server 資料庫,可採取下列步驟還原:停止資料庫活動;備份日誌檔案;檢查資料庫日誌;復原選項:從備份還原;從交易日誌還原;使用 DBCC CHECKDB;使用第三方工具。請定期備份資料庫並啟用交易日誌以防止資料遺失。

如果 SQL Server 安裝失敗,可透過下列步驟清理:解除安裝 SQL Server刪除註冊表項刪除檔案和資料夾重新啟動計算機

SQL Server 英文安裝可透過下列步驟變更為中文:下載對應語言套件;停止 SQL Server 服務;安裝語言套件;變更執行個體語言;變更使用者介面語言;重新啟動應用程式。
