在前天發現使用「like '%'+@LastName+'%'」會讓執行計劃(Execution Plan)跑出索引搜尋(Seek)後,因為我還是無法確定這是否是有效的,鼓起勇氣在隔天中午寫了封信詢問公司的前輩Sky大大,終於在當天下午5點多,應該是很繁忙的Sky大回了信給我,肯定了我的測試,並且也幫我修正了一個小地方,而修正後的查詢指令(SQL Script)才真正的用到 Seek,信中指令如下:
use AdventureWorks go --繼續用前一篇的索引 create index icl_LastName_Title on Person.Contact(LastName, Title) include(ContactID, FirstName) go --等等要用的變數 declare @LastName nvarchar(50)='Adams' --原指令,和前一篇不同,當@LastName有輸入值時才搜尋"相同名稱" select ContactID, Title, LastName, FirstName from Person.Contact where (@LastName='' OR LastName=@LastName) and Title='Mr.'
執行計劃為,(索引掃描(scan))
STATISTICS IO 為,
資料表 'Contact'。掃描計數 1,邏輯讀取 134,實體讀取 0,讀取前讀取 0,LOB 邏輯讀取 0,LOB 實體讀取 0,LOB 讀取前讀取 0。
SQL Server Profiler 為,
--增加 like '%'+@LastName+'%' 的指令 select ContactID, Title, LastName, FirstName from Person.Contact where LastName like '%'+@LastName+'%' -- <--這邊 and (@LastName='' OR LastName=@LastName) and Title='Mr.'
執行計劃為,(變成索引搜尋(seek)了)
STATISTICS IO 為,(重點!邏輯讀取數沒變,還是134)
資料表 'Contact'。掃描計數 1,邏輯讀取 134,實體讀取 0,讀取前讀取 0,LOB 邏輯讀取 0,LOB 實體讀取 0,LOB 讀取前讀取 0。
SQL Server Profiler 為,
而上述 Profiler 側錄的結果,Duration 也沒有比較快,而且邏輯讀取數沒變,
所以在此可以斷定,我的修改沒有用XD!
不過薑是老的辣,Sky大拿掉一個地方後,一切豬羊變色! 請先看修改後的指令碼,
--Sky大修改後的指令 select ContactID, Title, LastName, FirstName from Person.Contact where LastName like @LastName+'%' and (@LastName='' OR LastName=@LastName) and Title='Mr.'
執行計劃為,
STATISTICS IO 為,(重點!邏輯讀取從134減少為3)
資料表 'Contact'。掃描計數 1,邏輯讀取 3,實體讀取 0,讀取前讀取 0,LOB 邏輯讀取 0,LOB 實體讀取 0,LOB 讀取前讀取 0。
SQL Server Profiler 為,
眼尖的人應該發現到了,
其實就是上一篇2.裡寫到的「like時不要用前面的'%'」,
(真是汗顏,自己寫的自己都忘了)
拿掉前面的 '%'+ 後,一切就像水到渠成,功能還是能用,索引終於發揮功效,Happy Ending!!
感謝Sky大的提點!謝謝!
沒有留言:
張貼留言