like语句百分号前置会使用到索引吗?
原文轉(zhuǎn)載至:https://www.cnblogs.com/lyhabc/p/3378753.html
like語句百分號前置會使用到索引嗎?
前幾天看了這篇文章:談SQL Server對like '%關(guān)鍵詞%' 處理時的索引利用問題
看完了之后,我很想知道這篇文章是不是臨時工寫的?還是網(wǎng)站的主人寫的,網(wǎng)站的主人的微博我都有關(guān)注(在微博里私信過)
是某個公司的DBA,這里先不管他是不是臨時工寫的,今天我也研究一下這個問題o(∩_∩)o
?
說明:我們說的走索引指的是:聚集索引查找、非聚集索引查找
而全表掃描、聚集索引掃描、非聚集索引掃描都不是走索引
?
而這里說的走索引跟全文搜索/全文索引沒有關(guān)系??SQLSERVER全文搜索
全文搜索/全文索引已經(jīng)是另外一種技術(shù)了
聚集索引表
SQL腳本如下:
表數(shù)據(jù)
聚集索引創(chuàng)建在GROUPNAME這個字段上,我們就查找GROUPNAME這個字段
如果看過我以前寫的文章的人肯定知道:查找只會出現(xiàn)在建立索引的時候的第一個字段(這里我就不再詳細(xì)敘述了)
1 --聚集索引查找 2 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000' 3 --聚集索引掃描 4 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000%' 5 --聚集索引掃描 6 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000' 7 --聚集索引查找 8 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000%'--------------------------------------------------------------------------
IO和時間統(tǒng)計(jì)
?View Code 1 (1 行受影響)LIKE '銷售組1000'2 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 3 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。3 4 SQL Server 執(zhí)行時間:5 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。6 7 SQL Server 執(zhí)行時間:8 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。9 10 (11 行受影響)LIKE '%銷售組1000%' 11 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 448 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 12 13 SQL Server 執(zhí)行時間: 14 CPU 時間 = 47 毫秒,占用時間 = 47 毫秒。 15 16 SQL Server 執(zhí)行時間: 17 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 18 19 (1 行受影響)LIKE '%銷售組1000' 20 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 448 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 21 22 SQL Server 執(zhí)行時間: 23 CPU 時間 = 47 毫秒,占用時間 = 40 毫秒。 24 25 SQL Server 執(zhí)行時間: 26 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 27 28 (11 行受影響)LIKE '銷售組1000%' 29 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 3 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 30 31 SQL Server 執(zhí)行時間: 32 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 33 34 SQL Server 執(zhí)行時間: 35 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。?
只有LIKE '銷售組1000'和LIKE '銷售組1000%'用到了查找
為什麼?我會在文中最后說明
非聚集索引表
SQL腳本如下:
我們drop掉剛才的department表
1 DROP TABLE [dbo].[Department]重新建立department表
?View Code非聚集索引依然建立在GROUPNAME這個字段上
?
表數(shù)據(jù)
同樣,我們使用上面講解聚集索引表時候的查詢語句
因?yàn)槭莝elect * 所以SQLSERVER需要到數(shù)據(jù)頁面去找其他的字段數(shù)據(jù),使用到RID查找
這里的結(jié)果跟聚集索引是一樣的
-------------------------------------------------------------------------------------------
IO和時間統(tǒng)計(jì)
?View Code 1 (1 行受影響) LIKE '銷售組1000'2 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 3 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。3 4 SQL Server 執(zhí)行時間:5 CPU 時間 = 0 毫秒,占用時間 = 62 毫秒。6 7 SQL Server 執(zhí)行時間:8 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。9 10 (11 行受影響)LIKE '%銷售組1000%' 11 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 92 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 12 13 SQL Server 執(zhí)行時間: 14 CPU 時間 = 16 毫秒,占用時間 = 17 毫秒。 15 16 SQL Server 執(zhí)行時間: 17 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 18 19 (1 行受影響)LIKE '%銷售組1000' 20 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 82 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 21 22 SQL Server 執(zhí)行時間: 23 CPU 時間 = 15 毫秒,占用時間 = 17 毫秒。 24 25 SQL Server 執(zhí)行時間: 26 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 27 28 (11 行受影響)LIKE '銷售組1000%' 29 表 'Department'。掃描計(jì)數(shù) 1,邏輯讀取 13 次,物理讀取 0 次,預(yù)讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預(yù)讀 0 次。 30 31 SQL Server 執(zhí)行時間: 32 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。 33 34 SQL Server 執(zhí)行時間: 35 CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。?
為什麼只有LIKE '銷售組1000'和LIKE '銷售組1000%'用到了查找???
如果閣下曾經(jīng)有看過我寫的
SQLSERVER聚集索引與非聚集索引的再次研究(上)
SQLSERVER聚集索引與非聚集索引的再次研究(下)
您就會知道在聚集索引頁面和非聚集索引頁面里都有一個KeyHashValue的字段
聚集索引頁面
非聚集索引頁面
?
當(dāng)使用?'%銷售組1000%'和'%銷售組1000'的時候,因?yàn)槭悄:ヅ?#xff08;百分號前置)
SQLSERVER不會去匹配hash值(KeyHashValue),直接掃描(SCAN)算了
但是使用'銷售組1000'和'銷售組1000%'的時候
'銷售組1000' :SQLSERVER能夠準(zhǔn)確匹配到唯一的一個hash值
'銷售組1000%':SQLSERVER會匹配與銷售組1000相同的hash值
與銷售組1000%匹配的記錄會有多個,所以邏輯讀取次數(shù)也會有多次
所以,'銷售組1000'和'銷售組1000%'能夠使用查找(SEEK)
總結(jié)
只有了解了SQLSERVER的內(nèi)部原理,才能夠明白更多
?
注意:我這里并沒有將非聚集索引掃描納入到“走索引”這個分類,如果將非聚集索引掃描納入到“走索引”這個分類里
那么我的朋友的文章就是對的,隨便加個非聚集索引,讓表掃描/聚集索引掃描變成非聚集索引掃描,就認(rèn)為是走索引
(雖然非聚集索引掃描比聚集索引掃描/表掃描快,IO少)
那么下面四個語句都是屬于走索引,沒有什么好討論的,我們討論的前提是在基礎(chǔ)表上不加任何東西,如果在做實(shí)驗(yàn)的過程中
隨便加個非聚集索引,然后走非聚集索引掃描就說走索引,那么這篇文章就沒有意義了,經(jīng)過再三斟酌,
我決定將“非聚集索引掃描”移出“走索引”這個分類,畢竟查找(SEEK)比掃描(SCAN)快
SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000'
SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000%'
SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000'
SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000%'
?
最最后,補(bǔ)充說一下
我們判斷一個執(zhí)行計(jì)劃的性能的好壞的標(biāo)準(zhǔn)是什么??
就是哪個執(zhí)行計(jì)劃的邏輯讀次數(shù)最少
Logical reads:包含該語句從內(nèi)存數(shù)據(jù)緩沖區(qū)中訪問的頁數(shù)和從物理磁盤讀取的頁數(shù)。
如果全表掃描/聚集索引掃描所使用的邏輯讀比聚集索引查找/非聚集索引查找使用的邏輯讀要少,
或者全表掃描比非聚集索引掃描使用的邏輯讀要少
那么SQLSERVER選擇全表掃描/聚集索引掃描這個執(zhí)行計(jì)劃就是好的
有些人為了讓SQLSERVER使用索引,不惜代價使用查詢提示,讓SQLSRVER去走索引,這樣是得不償失的
我們的最終目的是:減少邏輯讀次數(shù),不要為了索引而索引!!
當(dāng)然,我這里的實(shí)驗(yàn)環(huán)境跟各位的真實(shí)環(huán)境會有差別,不過“邏輯讀次數(shù)”這個標(biāo)準(zhǔn)無論是哪個環(huán)境都是一樣的!!
我說完了,謝謝大家o(∩_∩)o
?
physical reads:表示那些沒有駐留在內(nèi)存緩沖區(qū)中需要從磁盤讀取的數(shù)據(jù)頁。
Read-ahead reads是SQL Server為了提高性能而產(chǎn)生的預(yù)讀。
如有不對的地方,歡迎大家拍磚o(∩_∩)o
轉(zhuǎn)載于:https://www.cnblogs.com/mkl34367803/p/9124600.html
總結(jié)
以上是生活随笔為你收集整理的like语句百分号前置会使用到索引吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python文件分享(3为http.se
- 下一篇: JS 函数参数arguments对象(实