索引深入淺出(8/10):覆蓋索引或列包含

在索引深入淺出:非聚集索引的B樹結構在聚集表里,在聚集表里,我們看到非聚集索引的葉子層只包含非聚集索引鍵和聚集索引鍵。從聚集表結構或堆表結構里拿到剩下列,SQL Server需要進行書簽/鍵查找操作。很多情況下書簽或鍵查找非常消耗資源。我們來看個例子。

在這里我們打開了IO統計信息,還有點擊工具欄的顯示包含實際的執行計劃。

 1 USE IndexDB
 2 GO
 3 DROP TABLE dbo.SalesOrderDetail                               
 4 GO                               
 5 SELECT * INTO dbo.SalesOrderDetail FROM AdventureWorks2008r2.Sales.SalesOrderDetail
 6 GO
 7 CREATE UNIQUE CLUSTERED INDEX ix_SalesOrderDetail ON dbo.SalesOrderDetail(SalesOrderDetailID)
 8 GO
 9 CREATE UNIQUE NONCLUSTERED INDEX ix_Productid ON dbo.SalesOrderDetail(ProductId,SalesOrderId)
10 GO 
11 SET STATISTICS IO ON
12 GO
13 SELECT SalesOrderDetailid,productid,salesorderid,orderqty,unitprice 
14 FROM SalesOrderDetail 
15 WHERE productid=707 AND SalesOrderID=43680

在IO統計信息里,SQL Server拿每條記錄需要進行5個IO操作。在執行計劃里,我們看到,查詢開銷的50%貢獻給了書簽查找(鍵查找)操作。

注意,這個表的非聚集索引有229個頁,非聚集索引的B樹結構深度為2。在這個非聚集索引里只要進行2個IO操作就可以完成查找操作,另外3個IO貢獻給了書簽查找。你可以用DBCC IND命令驗證下或者參考下索引深入淺出(4/10):非聚集索引的B樹結構在聚集表。

假設這個查詢(用不同的參數)在應用程序里經常用到,現在你需要優化它。我們該怎么做?我們對此唯一能優化的話就是避免鍵查找(Key lookup)操作。因此我們修改下非聚集索引,把剩下2列(OrderQty, UnitPrice),不是聚集索引鍵,也不是非聚集索引鍵,也加入非聚集索引鍵。

1 DROP INDEX ix_Productid ON dbo.SalesOrderDetail
2 GO
3 CREATE UNIQUE NONCLUSTERED INDEX ix_Productid ON dbo.SalesOrderDetail(ProductId,SalesOrderId,OrderQty ,UnitPrice)
4 GO
5 SELECT SalesOrderDetailid,productid,salesorderid,orderqty,unitprice FROM SalesOrderDetail WHERE productid=707 AND SalesOrderID=43680 

從執行計劃里我們可以看到,我們已經回避了鍵查找操作,把IO操作從5個降到了3次。但是我們如果用DBCC IND看下非聚集索引,我們發現由于還這個改動,我們的非聚集索引深度增加了。因為索引層的增加,非聚集索引需要進行3次IO來完成這個操作。這將是最糟糕的,如果選擇列更多的話,我們就需要在非聚集索引里增加更多的列來避免鍵查找操作。

覆蓋索引(covering index?)就是用來解決這個問題的。覆蓋索引幫助我們在非聚集索引的葉子層增加非主鍵列,最小可能增加B樹結構的深度。可以用CREATE INDEX語句增加包含列完成。

當索引包含查詢列是,這個為稱為覆蓋索引。當我們創建非聚集索引去覆蓋一個查詢時,我們可以在索引里包含非主鍵列來覆蓋查詢列,這些覆蓋列在主查詢列里不會用到。這樣查詢性能會提升,因為查詢優化器在索引里就可以定位到需要列的數據,表或聚集索引不會被訪問。

1 DROP INDEX ix_Productid ON dbo.SalesOrderDetail
2 GO
3 CREATE UNIQUE NONCLUSTERED INDEX ix_Productid ON dbo.SalesOrderDetail(ProductId,SalesOrderId) 
4 include(OrderQty ,UnitPrice)
5 GO
6 SELECT SalesOrderDetailid,productid,salesorderid,orderqty,unitprice FROM SalesOrderDetail 
7 WHERE productid=707 AND SalesOrderID=43680 

可以發現,我們已經避免了鍵查找操作,并把IO操作降到了2次。IO操作清楚的告訴我們聚集索引的深度是2。我們用DBCC IND和DBCC PAGE命令驗證下。

 1 SELECT index_id FROM sys.indexes WHERE name='ix_Productid' AND OBJECT_ID= OBJECT_ID('SalesOrderDetail')
 2 GO
 3 DBCC ind('IndexDB','SalesOrderDetail',2) 
 4 
 5 TRUNCATE TABLE dbo.sp_table_pages
 6 INSERT INTO sp_table_pages EXEC('DBCC IND(IndexDB,SalesOrderDetail,2)')
 7 GO
 8 
 9 SELECT * FROM dbo.sp_table_pages ORDER BY IndexLevel DESC --根節點/索引頁
10 
11 DBCC TRACEON(3604)
12 DBCC PAGE(IndexDB,1,2800,3)--根頁
13 
14 DBCC TRACEON(3604)
15 DBCC PAGE(IndexDB,1,2736,3)--葉子頁

include語句提到的列已經加到了葉子層的頁,沒有對非頁層頁造成影響。
列包含非常有用,我們可以把不能在索引鍵里加的列,在列包含里加入。另外避免超過當前索引大小的限制(最大鍵列數為 16,最大索引鍵大小為 900 字節)。我們可以包含除去text,ntext和image類型的其他列,列包含也同樣支持計算列(computed column)。

參考文章:?

http://www.sqlservercentral.com/blogs/practicalsqldba/2013/03/25/sql-server-part-8-explaining-the-covering-index-or-included-columns/

轉載于:https://www.cnblogs.com/woodytu/p/4509673.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375016.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375016.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375016.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

靶場練習第二十三天~vulnhub靶場之GOATSELINUX: 1

一、準備工作 kali和靶機都選擇NAT模式(kali與靶機同網段) 1.靶場環境 下載鏈接:GoatseLinux: 1 ~ VulnHub 2.kali的ip 命令:ifconfig 3.靶機的ip 掃描靶機ip sudo arp-scan -l 二、信息收集 1.nmap的信息收集 (1)掃描靶機…

Spring事務報Connection is read-only

昨天做項目時,寫了個方法,程序突然報了Connection is readonly. Queries leading to data modification are not allowed調了程序半天,最后才發現是自己在spring配置文件中增加了事務.把方法寫成了大寫開頭了,但是spring配置是以小寫開頭 代碼…

HTTP協議具體解釋

HTTP是一個屬于應用層的面向對象的協議。因為其簡捷、高速的方式。適用于分布式超媒體信息系統。它于1990年提出,經過幾年的使用與發展,得到不斷地完好和擴展。眼下在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的規范化工作正在進行之中&#x…

靶場練習第二十四天~vulnhub靶場之Raven-1

一、準備工作 kali和靶機都選擇NAT模式(kali與靶機同網段) 1.靶場環境 下載鏈接:Raven: 1 ~ VulnHub 2.kali的ip 命令:ifconfig 3.靶機的ip 掃描靶機ip sudo arp-scan -l 二、信息收集 1.nmap的信息收集 (1)掃描靶機開放的…

【知識積累】DES算法之C#加密Java解密

一、前言 在項目需要添加安全模塊,客戶端調用服務端發布的service必須要經過驗證,加密算法采用DES,客戶端采用C#進行加密,服務端使用Java進行解密。廢話不多說,直接上代碼。 二、客戶端 客戶端采用C#進行開發&#xff…

Space.js – HTML 驅動的頁面 3D 滾動效果

為了讓我們的信息能夠有效地溝通,我們需要創建用戶和我們的媒體之間的強有力的聯系。今天我們就來探討在網絡上呈現故事的新方法,并為此創造了一個開源和免費使用的 JavaScript 庫稱為 space.js。該庫是 HTML 驅動的,這意味著你不需要在網站上…

離職感言-Symbio的5年工作回顧和總結(轉載)

離職感言-Symbio的5年工作回顧和總結 (2011-06-02 21:06:30) 轉載▼2005年底,當時我在西安過的還不錯,結了婚,買了房,在公司也受老板器重,但是初為人父,孩子帶給我的那種人生緊迫感:“再不趁還…

64位CentOS6.2安裝erlang及rabbitmqServer

CentOS 6.2 64bit 安裝erlang及RabbitMQ Server 1、操作系統環境(CentOS 6.2 64bit) 1 [rootHAproxy ~]# cat /etc/issue2 3 CentOS release 6.2 (Final)4 Kernel \r on an \m5 [rootHAproxy ~]# cat /proc/cpuinfo |grep "clflush size"6 clflush size : 647 clf…

Kafka的Producer和Consumer源碼學習

先解釋下兩個概念: high watermark (HW) 它表示已經被commited的最后一個message offset(所謂commited, 應該是ISR中所有replica都已寫入),HW以下的消息都已被ISR中各個replica同步,從而保持一致。HW以上的消息可能是臟數據:部分r…

for+next()實現數組的遍歷及while list each 的使用

//要求使用for循環語句來完成該數組的遍歷//輸出每一項的鍵名和對應值&#xff1a; $a array( a > 34, 5 > 51, 13, 32, bb>15, 2 > 31 ); $len count($a); for($i0;$i<$len;$i)…

讀Pyqt4教程,帶你入門Pyqt4 _005

對話框窗體或對話框是現代GUI應用不可或缺的一部分。dialog定義為兩個或多個人之間的交談。在計算機程序中dialog是一個窗體&#xff0c;用來和程序“交談”。對話框用來輸入數據、修改數據、改變程序設置等等。對話框是用戶和計算機程序溝通的重要手段。 QColorDialog 顏色對話…

Linux內核的啟動過程分析

秦鼎濤 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000  一、實驗目的及要求&#xff1a; 使用gdb跟蹤調試內核從start_kernel到init進程啟動 詳細分析從start_kernel到init進程啟動的過程并結合實驗截圖撰寫一篇署名博客&#xff0c;并在博客文…

static修飾符詳解

static表示“全局”或者“靜態”的意思&#xff0c;用來修飾成員變量和成員方法&#xff0c;也可以形成靜態static代碼塊&#xff0c;但是Java語言中沒有全局變量的概念。被static修飾的成員變量和成員方法獨立于該類的任何對象。也就是說&#xff0c;它不依賴類特定的實例&…

四則運算2+psp0

程序要求&#xff1a; 1.題目避免重復 2.可定制&#xff08;數量\打印方式&#xff09; 3.可以一下控制參數 ① 是否有乘除法 ② 是否有括號&#xff08;最多支持十個數參與運算&#xff09; ③ 數值范圍 ④加減有無負數 ⑤除法有無余數 分析&#xff1a;① 如果是兩個數…

kettle作業中的js如何寫日志文件

在kettle作業中JavaScript腳本有時候也扮演非常重要的角色&#xff0c;此時我們希望有一些日志記錄。下面是job中JavaScript記錄日志的方式。 job的js寫日志的方法。 得到日志輸出實例 org.pentaho.di.core.logging.LogWriter.getInstance();按照日志的級別輸出&#xff1a; pu…

淺析Kerberos原理,及其應用和管理

文章作者&#xff1a;luxianghao 文章來源&#xff1a;http://www.cnblogs.com/luxianghao/p/5269739.html 轉載請注明&#xff0c;謝謝合作。 免責聲明&#xff1a;文章內容僅代表個人觀點&#xff0c;如有不當&#xff0c;歡迎指正。 --- 一&#xff0c;引言 Kerberos簡單來…

2014! 的末尾有多少個0

2014&#xff01; 的末尾有多少個0<?xml version"1.0" encoding"UTF-8"?> 假設 末尾有 k 個0&#xff0c;所以 2014&#xff01; x * 10^k ; 10 ^ k &#xff08;2 * 5 &#xff09;^ k 2^k * 5^k, 明顯所有數字中因數含有2的數字多于含有5的數…

[轉載]一句話插配置文件

http://www.t00ls.net/viewthread.php?tid13901 一句話插入配置文件system.asp沒有過濾雙引號&#xff0c;插入一句就行。常規插法如下&#xff1a;"%><%eval request("d")%><%但金刀客這篇文件&#xff08;http://www.cqzh.cn/post/328.html&…

android插件化-獲取apkplug框架已安裝插件-03

上一篇文章成功的將apkplug框架嵌入了應用中而且啟動 鏈接http://www.apkplug.com/blog/?post10 這一篇文章實現怎樣獲取全部已安裝插件 一 獲取框架的SystemBundle的上下文BundleContext apkplug框架啟動會自己主動創建一個SystemBundle, 它是框架的第一個插件不可停止和卸…

Java實現棧。

定義一個接口MyStack接口&#xff1a; package Stack; public interface MyStack<T> { boolean isEmpty(); int length(); boolean push(T date); T pop();} 數組實現&#xff1a; package Stack; public class ArrayStack<T> implements MyStack<T>{ privat…