淺析SQL Server 聚焦索引對非聚集索引的影響
前言
在學(xué)習(xí)SQL 2012基礎(chǔ)教程過程中會時(shí)不時(shí)穿插其他內(nèi)容來進(jìn)行講解,相信看過SQL Server 2012 T-SQL基礎(chǔ)教程的童鞋知道前面寫的所有內(nèi)容并非都是摘抄書上內(nèi)容,如若是這樣那將沒有任何意義,學(xué)習(xí)的過程必須同時(shí)也是一個(gè)思考的過程,無論是獨(dú)立思考也好還是查資料也罷都是思考而非走馬觀花,要不然過一段時(shí)間又會健忘。簡短的內(nèi)容,深入的理解。
話題
非聚集索引定義:非聚集索引也是一個(gè)B樹結(jié)構(gòu),與聚集索引不同的是,B樹的葉子節(jié)點(diǎn)存的是指向堆或聚集索引的指針。你真的理解了嗎??你能舉出例子嗎??其實(shí)本節(jié)最終想表達(dá)的就是這個(gè)意思,定義太長,我們抽象一點(diǎn)來定義并得出最終結(jié)論,請往下看。
聚集索引對非聚集索引影響
關(guān)于聚集索引和非聚集索引的概念、原理、創(chuàng)建都不會再敘述,若對此不太了解請參考園中其他園友的詳細(xì)介紹。
首先我們創(chuàng)建測試表
USE SQLStudy GO CREATE TABLE [dbo].[Test]( [ID] [int] NOT NULL, [First] [nchar](10) NULL, [Second] [nchar](10) NULL ) GO
接下來我們再來創(chuàng)建測試數(shù)據(jù)
INSERT INTO [SQLStudy].[dbo].[Test] ([ID],[First],[Second]) SELECT 1,'First1','Second1' UNION ALL SELECT 2,'First2','Second2' UNION ALL SELECT 3,'First3','Second3' UNION ALL SELECT 4,'First4','Second4' UNION ALL SELECT 5,'First5','Second5' GO
緊接著我們對表上的First和Second列創(chuàng)建聚集索引,如下
CREATE NONCLUSTERED INDEX [IX_MyTable_NonClustered] ON [dbo].[Test] ( [First] ASC, [Second] ASC )
此時(shí)我們來同時(shí)運(yùn)行兩個(gè)查詢,看看其執(zhí)行計(jì)劃【注】:上一篇已經(jīng)說過,請啟用包括實(shí)際執(zhí)行的計(jì)劃。
SELECT ID FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1' SELECT Second FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1' GO
此時(shí)我們看到的執(zhí)行計(jì)劃如下:
通過上述毫無疑問我們可以得出結(jié)論:查詢1是利用的全表掃描,而查詢2利用的非聚集索引查找。我們應(yīng)該對于這個(gè)結(jié)論沒有任何懷疑,因?yàn)橐诙€(gè)查詢的Second列在此之前已經(jīng)創(chuàng)建額非聚集索引,而對于查詢1中的ID則沒有,所以會造成查詢1的全表掃描,而查詢2則是非聚集索引查找。
下面我們對表上的列ID創(chuàng)建聚集索引。
CREATE CLUSTERED INDEX [IX_MyTable_Clustered] ON [dbo].[Test] ( [ID] ASC )
此時(shí)我們再來運(yùn)行如下查詢:
SELECT ID FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1' SELECT Second FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1' GO
此時(shí)再來看看查詢執(zhí)行計(jì)劃:
通過上述我們對列ID創(chuàng)建了聚集索引,我們肯定能立馬知道兩者都是利用索引查找,確實(shí)沒錯(cuò),但是,但是你發(fā)現(xiàn)沒有,睜大眼睛看看,我們明明在列ID上創(chuàng)建的是聚集索引,理論上應(yīng)該是聚集索引查找才對啊,這就是我們本文所需要討論的問題。
問題探討
我們將問題進(jìn)行如下概述,當(dāng)我們在列上創(chuàng)建聚集索引時(shí)且查詢返回該列,同時(shí)查詢條件是創(chuàng)建了非聚集索引的列,此時(shí)對于創(chuàng)建了聚集索引的列的查詢執(zhí)行計(jì)劃則是非聚集索引查找,這其中到底發(fā)生了什么?
實(shí)際發(fā)生的情況是非聚集索引內(nèi)部引用了聚集索引, 當(dāng)聚集索引被創(chuàng)建后在表中的數(shù)據(jù)會按照物理邏輯進(jìn)行排序,當(dāng)聚集索引沒有被創(chuàng)建時(shí)此時(shí)非聚集索引指向的表中的數(shù)據(jù)并最終返回?cái)?shù)據(jù),但是一旦聚集索引創(chuàng)建了此時(shí)非聚集索引則會重建從而此時(shí)指向的是聚集索引,說到這里對于園友CareySon對于非聚集索引的描述:非聚集索引也是一個(gè)B樹結(jié)構(gòu),與聚集索引不同的是,B樹的葉子節(jié)點(diǎn)存的是指向堆或聚集索引的指針。概括的非常精準(zhǔn),若創(chuàng)建了聚集索引此時(shí)非聚集索引的指針則指向的是聚集索引,否則此時(shí)指向的是堆也就是表中的數(shù)據(jù)。所以此時(shí)在這種情況下,當(dāng)查詢創(chuàng)建了聚集索引的列時(shí)是進(jìn)行了非聚集索引查找。
至此,我們可以得出結(jié)論:當(dāng)在檢索的列上創(chuàng)建了聚集索引時(shí)(僅僅返回創(chuàng)建聚集索引的列),此時(shí)查詢不會使用聚集索引查找來檢索結(jié)果而是使用非聚集索引查找來檢索結(jié)果。
總結(jié)
個(gè)人覺得對于一個(gè)定義出來之前我們得首先拋出這樣一個(gè)問題,如上述非聚集索引的定義:非聚集索引也是一個(gè)B樹結(jié)構(gòu),與聚集索引不同的是,B樹的葉子節(jié)點(diǎn)存的是指向堆或聚集索引的指針。初次看到這句感覺沒什么,泛泛而談,感覺似乎理解了,當(dāng)遇到這樣的問題時(shí)卻不知所措,其實(shí)就是對定義理解的不夠深入或者說不夠透,當(dāng)一個(gè)定義出來時(shí)你能舉出這個(gè)定義的例子或者場景,那可能才算是真正了解了。本節(jié)我們到此結(jié)束,對于SQL這一系列會秉著簡短的內(nèi)容,深入的理解來講解,同時(shí)也會循序漸進(jìn)講講查詢性能問題,由拋出問題到最終解決問題才算是收貨多多。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,同時(shí)也希望多多支持腳本之家!
- SQL Server 2005通用分頁存儲過程及多表聯(lián)接應(yīng)用
- SQL設(shè)置SQL Server最大連接數(shù)及查詢語句
- 解析SQL Server聚焦移除(Bookmark Lookup、RID Lookup、Key Lookup)
- 詳解SQL Server的聚焦過濾索引
- 淺述SQL Server的聚焦強(qiáng)制索引查詢條件和Columnstore Index
- 淺析SQL Server的分頁方式 ISNULL與COALESCE性能比較
- 詳解SQL Server中的數(shù)據(jù)類型
- 淺析SQL Server的聚焦使用索引和查詢執(zhí)行計(jì)劃
- 如何快速刪掉SQL Server登錄時(shí)登錄名下拉列表框中的選項(xiàng)
- 淺談SQL Server交叉聯(lián)接 內(nèi)部聯(lián)接
相關(guān)文章
SQL?Server表空間碎片化回收的實(shí)現(xiàn)
本文主要介紹了SQL?Server表空間碎片化回收的實(shí)現(xiàn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03數(shù)據(jù)庫SQL語句優(yōu)化總結(jié)(收藏)
網(wǎng)上關(guān)于SQL優(yōu)化的教程很多,但是比較雜亂。近日有空整理了一下,寫出來跟大家分享一下,感興趣的朋友參考下2017-03-03SQL Server復(fù)制刪除發(fā)布時(shí)遇到錯(cuò)誤18752的問題及解決方法
朋友反饋他無法刪除一臺SQL Server數(shù)據(jù)庫上的發(fā)布,具體情況為刪除一個(gè)SQL Server Replication的發(fā)布時(shí),遇到這樣的錯(cuò)誤問題如何解決呢,下面小編給大家分享SQL Server復(fù)制刪除發(fā)布時(shí)遇到錯(cuò)誤18752的問題及解決方法,感興趣的朋友一起看看吧2024-01-01sqlserver循環(huán)刪除表中的數(shù)據(jù)最好方案
這篇文章主要介紹了sqlserver?中?循環(huán)刪除表中的數(shù)據(jù),這樣不會鎖表,導(dǎo)致業(yè)務(wù)出現(xiàn)問題,本文給大家分享最新解決方案,文中給大家補(bǔ)充介紹了foreach 循環(huán)中刪除一條數(shù)據(jù)_SQL Server中刪除重復(fù)數(shù)據(jù)的幾個(gè)方法,需要的朋友可以參考下2023-11-11SQL Server判斷數(shù)據(jù)庫、表、列、視圖、存儲過程、函數(shù)是否存在總結(jié)
這篇文章主要介紹了SQL Server判斷數(shù)據(jù)庫、表、列、視圖、存儲過程、函數(shù)是否存在,本文是一篇總結(jié)篇,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05Sql?server連接Oracle數(shù)據(jù)庫完整圖文教程
又一次在項(xiàng)目中用到了在SQLServer添加Oracle鏈接服務(wù)器,索性這里總結(jié)下,這篇文章主要給大家介紹了關(guān)于Sql?server連接Oracle數(shù)據(jù)庫的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01