日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

like语句百分号前置会使用到索引吗?

發(fā)布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 like语句百分号前置会使用到索引吗? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文轉(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腳本如下:

?View Code

表數(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ù)


同樣,我們使用上面講解聚集索引表時候的查詢語句

1 --非聚集索引查找 RID查找 2 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000' 3 --非聚集索引掃描 RID查找 4 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000%' 5 --非聚集索引掃描 RID查找 6 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '%銷售組1000' 7 --非聚集索引查找 RID查找 8 SELECT * FROM [dbo].[Department] WHERE [GroupName] LIKE '銷售組1000%'

因?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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。