亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

解析SQL Server聚焦移除(Bookmark Lookup、RID Lookup、Key Lookup)

2024-08-31 01:04:24
字體:
來源:轉載
供稿:網友

前言

前面幾節都是講的基礎內容,本節我們講講索引性能優化,當對大數據進行處理時首先想到的就是索引,一旦遇到這樣的問題則手忙腳亂,各種查資料,為何平常不扎實基本功呢,我們由淺入深,簡短的內容,深入的理解,而非一上來就把問題給框死,立馬給出解決方案,拋出問題,再到解決問題,你GET了沒有。

Bookmark Lookup、RID Lookup、Key Lookup定義

一說到這三者,如果對索引研究不深的童鞋估計是懵逼的,什么玩意,我們姑且將上面三者翻譯為:標簽查找、行ID查找、鍵查找。標簽查找和鍵查找是一個意思,在SQL 2005之前叫Key Lookup。怎么解釋,如何定義呢?首先我們不看定義,直接看下面一步一步解析,如果你實在忍不住,請看園友【永紅】的見解,解釋還是非常到位。我們簡短的說明下此三者概念。

在查詢中,我們對返回的列在查詢條件上若建立了非聚集索引,此時將可能嘗試使用非聚集索引查找,如果返回的列沒有創建非聚集索引,此時會返回到數據頁中去獲取這些列的數據,即使表中存在聚集索引或者沒有,都會返回到表中或者聚集索引中去獲取數據。對于以上場景描述,如果表沒有創建聚集索引則稱為Bookmar Lookup,如果表中沒有聚集索引但是存在非聚集索引我們稱為RID Lookup??吹竭@里我們就會想法操作如此耗時,還要返回到基表中去獲取數據,所以才有了我們本節來移除以上三者來提高查詢性能。接下來我們一起來看看。

拋出Bookmark Lookup、RID Lookup、Key Lookup問題

我們首先創建如下表

USE TSQL2012 GOCREATE TABLE Sales.Orders ([orderid] INT,[shipaddress] VARCHAR(100),[shipcity] VARCHAR(100),[shipregion] VARCHAR(100))GO

接著進行查詢

USE TSQL2012GOSELECT orderid, shipaddress, shipregionFROM Sales.OrdersWHERE shipcity = '深圳'

sqlserver,聚焦移除

這個不用多講,沒添加任何索引,執行查詢計劃是全表掃描。接下來我們創建在orderid上創建聚集索引如下:

CREATE CLUSTERED INDEX idx_cls_orderid ON Sales.Orders(orderid)

我們再執行上述查詢

sqlserver,聚焦移除

此時我們創建了聚集索引,所以此時查詢走聚集索引,到這里我們看到情況由全表掃描轉換成了索引掃描。我們在查詢時一直是帶了查詢條件的,而對查詢條件我們未作任何操作,如果我們此時在查詢條件上創建了索引,此時查詢的性能又會得到一點改善。我們開始對查詢條件創建一個非聚集索引。

CREATE NONCLUSTERED INDEX idx_nc_shipcity ON Sales.Orders(shipcity)

我們再接著執行查詢

sqlserver,聚焦移除

我們觀察到對查詢條件創建了非聚集索引,查詢計劃會使用非聚集索引查找返回結果,但是對于shipaddress, shipcity, shipregion并不是索引的一部分,此時查詢引擎會返回到基表中得到這些數據再返回。這種行為就叫做Bookmark Lookup或者Key Lookup。下面我們就如本文標題一樣問題出現來解決問題,移除Bookmark Lookup或者Key Lookup。我們嘗試用兩種不同的方法來解決。

解決Bookmark Lookup、RID Lookup、Key Lookup問題

創建非聚集索引覆蓋索引

我們對查詢條件以及檢索列創建非聚集索引。

CREATE NONCLUSTERED INDEX idx_all_cover ON Sales.Orders(shipaddress,orderid,shipcity,shipregion)

sqlserver,聚焦移除

此時我們對檢索列創建了非聚集索引,此時將不會再到數據頁中獲取數據,而是從索引中直接返回,所以到這里我們算是移除了Key Lookup。但是此時觸發另外一個問題,執行查詢計劃走的卻是索引掃描,索引到底是什么呢?我們打個比方,一個索引相當于是數據庫中一個本書開始的索引,我們需要快速從書中查找到我們所需要的數據,這個時候書就是我們所說的表。索引掃描意味著要讀取表中的所有行,然后返回滿足條件的所有數據,當執行索引掃描時,所有行上葉子節點上的所有都會被掃描,這也就意味著索引上的所有行都會被檢索一遍而不是直接檢索表,和表掃描對比的話,表掃描是直接讀取表中數據,所以表掃描和索引掃描還是有一點點不同,而索引查找則是依賴于索引頁數據來定位滿足條件的所有行,索引查找僅僅只影響滿足條件以及頁上包含這些滿足條件的行,所以說索引查找更加高效。

上述我們稍微講解了下索引掃描和索引查找,而上述的問題是我們創建了非聚集索引,但是結果執行的查詢計劃是索引掃描,很是納悶,對于剛學索引小白的我來說,不知該如何是好,以為是緩存的緣故,清除各種緩存均不好使。于是開始胡思亂想是不是檢索列中數據有為NULL引起的,是不是檢索列數據重復引起的,嘗試了無數次,最終發現某一次居然好使。如下

CREATE NONCLUSTERED INDEX idx_cls_cover ON Sales.Orders(shipcity,orderid,shipaddress,shipregion)

sqlserver,聚焦移除

此時若我們將查詢條件進行如下修改。

USE TSQL2012GOSELECT orderid, shipaddress, shipregionFROM Sales.OrdersWHERE shipaddress = '深圳' GO

sqlserver,聚焦移除

到這里我們應該發現了,唯一的區別在于我們創建非聚集索引時的順序和查詢條件不同就會導致索引掃描和索引查找的轉換,那么到底什么時候才會執行索引查找呢?我們可以進行如下一般性總結:

索引查找的一般性結論:如果條件中包含WHERE或者ON的話,查詢條件必須是位于索引集合列中首位,此時索引查找將會被使用。

此時我們穿插一點內容,上述我們創建了覆蓋索引,我們來比較下覆蓋索引和默認情況下聚集索引查找的性能開銷。

覆蓋索引與默認聚集索引性能開銷比較

FROM Sales.Orders WITH(INDEX([PK_Orders]))WHERE orderid<11072goSELECT orderid, shipaddress, shipregionFROM Sales.Orders WITH(INDEX([idx_noncls_include_exceptorderid]))WHERE orderid<11072GO

sqlserver,聚焦移除

從上可知,覆蓋索引的開銷要比默認主鍵聚集索引性能開銷要好一點,同時我們可以看看如下二者IO代價。

sqlserver,聚焦移除

sqlserver,聚焦移除

通過上述覆蓋索引與默認聚集索引的對比,我們能夠有效的減少IO,這一點也是非常明確的,當然下面的INCLUDE索引對比也是另外一種好的方案。

sqlserver,聚焦移除

創建INCLUDE非聚集索引

USE TSQL2012GOCREATE NONCLUSTERED INDEX [ix_noncls_include] ON [TSQL2012].[Sales].[Orders] ( shipcity) INCLUDE (shipaddress, shipregion, orderid)

sqlserver,聚焦移除

至此我們用兩種方式來移除了Bookmark Lookup、RID Lookup、Key Lookup,通過使用索引和覆蓋索引。

既然有如上兩種方式,我們應該有所取舍,二者誰的性能更好呢?我們接下來比較上述二者的開銷差異。

比較移除Bookmark Lookup等兩種方式差異

USE TSQL2012GOSELECT orderid, shipaddress, shipcity, shipregionFROM Sales.Orders WITH(INDEX(idx_all_cover))WHERE shipcity = '深圳'GOSELECT orderid, shipaddress, shipcity, shipregionFROM Sales.Orders WITH(INDEX(ix_noncls_include))WHERE shipcity = '深圳'GO

sqlserver,聚焦移除

我們從上所知,二者開銷一樣,并未有什么區別,當然相信我們更傾向于的是將第二種方式作為解決方案。到這里算是基本結束了,但是還有一個小問題,我們在之前已經創建了orderid的聚集索引,后面在解決方案中我們也添加了orderid的非聚集索引,難道非得添加嗎,我們去掉試試看。

CREATE NONCLUSTERED INDEX idx_noncls_cover_exceptorderidON Sales.Orders(shipcity,shipaddress,shipregion)CREATE NONCLUSTERED INDEX idx_noncls_include_exceptorderidON Sales.Orders(shipcity) INCLUDE(shipaddress,shipregion)

去除orderid比較二者開銷差異:

USE TSQL2012GOSELECT orderid, shipaddress, shipregionFROM Sales.Orders WITH(INDEX([idx_noncls_cover_exceptorderid]))WHERE shipaddress = '深圳' GOSELECT orderid, shipaddress, shipregionFROM Sales.Orders WITH(INDEX([idx_noncls_include_exceptorderid]))WHERE shipaddress = '深圳' GO

sqlserver,聚焦移除

由上知,非聚集索引列不需要包含創建了聚集索引的列,那么事實到底是怎樣的呢?

結論:其實對于任何非聚集索引列都不需要包含創建了聚集索引的列,因為創建聚集索引的列是非聚集索引集合列的一部分,也就是說只要一個表上的列創建了聚集索引,那么非聚集索引集合列就包含了這個聚集索引。

總結

本節我們比較詳細就問題的拋出到問題的解決,從而來提高查詢性能,好了,到此結束,我們下節再會。簡短的內容,深入的理解

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,同時也希望多多支持VeVb武林網!


注:相關教程知識閱讀請移步到MSSQL教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品天天看| 日韩二区三区在线| 黄色成人在线播放| 欧美午夜精品久久久久久人妖| 7m精品福利视频导航| 日韩中文字幕视频在线| 91久久综合亚洲鲁鲁五月天| 久久久国产成人精品| 亚洲乱码一区av黑人高潮| 亚洲国内高清视频| 亚洲在线免费视频| 精品久久久久久久久久国产| 欧美成人精品激情在线观看| 日韩精品在线免费播放| 久久久人成影片一区二区三区观看| 亚洲欧美日韩图片| 日韩精品视频在线观看免费| 91亚洲精品一区二区| 久久久在线视频| 国产午夜精品久久久| 欧美影院在线播放| 91在线高清免费观看| www.日韩系列| 久热精品在线视频| 久久久久久久亚洲精品| 91免费看片在线| 国产亚洲精品久久久久久牛牛| 日韩欧美一区二区在线| 亚洲第一精品自拍| 欧美激情喷水视频| 成人久久一区二区三区| 精品亚洲一区二区三区在线播放| 在线成人激情黄色| 国产欧美精品一区二区三区-老狼| 国产精品丝袜白浆摸在线| 欧美一级大片在线观看| 欧美高清在线观看| 91中文字幕在线观看| 在线观看欧美日韩国产| 欧美一级成年大片在线观看| 国产一区二区三区久久精品| 久久久欧美精品| 亚洲人成网在线播放| 亚洲三级 欧美三级| 国产日韩欧美视频在线| 中文字幕精品国产| 91久久在线观看| 国产精品夜间视频香蕉| 久久精品视频中文字幕| 4438全国亚洲精品在线观看视频| 精品无人国产偷自产在线| 久久影视电视剧凤归四时歌| 亚洲精品福利在线观看| 亚洲精品av在线| 色综合久久中文字幕综合网小说| 久久久91精品国产一区不卡| 日本免费久久高清视频| 亚洲精品按摩视频| 伊人久久久久久久久久| 久久夜色精品亚洲噜噜国产mv| 久久99国产综合精品女同| 日韩精品中文字幕久久臀| 亚洲自拍av在线| 国产亚洲精品美女久久久久| 国产精品爽爽ⅴa在线观看| 国产区精品在线观看| 日韩欧美一区视频| 日韩在线播放视频| 在线成人中文字幕| 亚洲黄在线观看| 日韩av在线直播| 国产97人人超碰caoprom| 91精品国产91久久久久福利| 亚洲精品www久久久久久广东| 日韩亚洲欧美中文高清在线| 亚洲视频在线观看免费| 97色伦亚洲国产| 日韩av在线最新| 亚洲国产精品久久久久秋霞蜜臀| 日韩在线观看免费av| 97在线视频免费| 亚洲精品www| 亚洲综合日韩中文字幕v在线| 成人免费视频xnxx.com| 97人洗澡人人免费公开视频碰碰碰| 亚洲最新在线视频| 成人免费自拍视频| 亚洲精品视频中文字幕| 久久99久久亚洲国产| 欧美亚洲视频在线看网址| 亚洲福利视频专区| 国产成人亚洲综合91| 久久亚洲精品中文字幕冲田杏梨| 91精品啪在线观看麻豆免费| 欧美电影免费观看电视剧大全| 中文字幕日韩av综合精品| 97国产在线观看| 日韩在线一区二区三区免费视频| 国产精品99久久久久久www| 欧美午夜www高清视频| 91香蕉国产在线观看| 日韩中文字幕在线观看| 自拍偷拍亚洲在线| 久久久国产一区| 亚洲jizzjizz日本少妇| 久久夜色撩人精品| 日韩高清免费观看| 亚洲人成电影网站| 日韩av在线免播放器| 国产精品69精品一区二区三区| 欧美日韩电影在线观看| 国产999精品视频| 中文字幕日韩精品在线观看| 一区二区三区高清国产| 精品久久久久久久久中文字幕| 福利二区91精品bt7086| 亚洲欧美另类在线观看| 在线精品视频视频中文字幕| 91综合免费在线| 中文日韩在线观看| 91精品国产自产91精品| 欧美另类第一页| 亚洲美女性生活视频| 欧美日韩美女视频| 奇米影视亚洲狠狠色| 中文字幕久热精品在线视频| 亚洲视频777| 午夜精品国产精品大乳美女| 欧美性xxxxxxxxx| 日日摸夜夜添一区| 国产欧美欧洲在线观看| 欧美资源在线观看| 在线成人一区二区| 久热爱精品视频线路一| 国产免费一区二区三区在线观看| 欧美性猛交99久久久久99按摩| 中文字幕av一区中文字幕天堂| 欧美激情成人在线视频| 亚洲女人初尝黑人巨大| 日韩美女视频中文字幕| 国产精品专区第二| 精品久久久久久国产91| 久久久久久久激情视频| 日韩中文在线观看| 国产91热爆ts人妖在线| 一区二区三区美女xx视频| 国产suv精品一区二区三区88区| 国产精品久久久久久亚洲调教| 欧美色视频日本高清在线观看| 亚洲人成在线免费观看| 亚洲偷熟乱区亚洲香蕉av| 久久精品91久久香蕉加勒比| 日本成人精品在线| 日韩中文字幕在线播放| 久热99视频在线观看| 国内自拍欧美激情| 亚洲综合一区二区不卡| 欧美极品美女视频网站在线观看免费| 成人妇女淫片aaaa视频| 日韩成人激情影院| 欧美激情亚洲一区| 亚洲成人亚洲激情| 国产精品入口免费视频一| 欧美老女人性生活|