執行計劃緩存是sql server記憶體管理中非常重要的特性,這篇文章是巧用執行計劃緩存系列文章之四,探讨什麼是key lookup操作,如何從執行計劃緩存中發現key lookup問題,以及如何解決這個問題。
key lookup操作是指執行計劃通過表的索引查找字段列的書簽查找方式。key lookup發生在當查詢語句使用index seek(或者index scan)的同時,又需要查找index中沒有完全包含的額外字段列,這時sql server必須回過頭來擷取額外的字段列的值。通常情況下key lookup操作是通過表聚集索引來查找字段列的值,是以,可能會導緻昂貴的查詢性能開銷,在性能優化過程中,需要引起我們足夠的重視。
在性能優化過程中,執行計劃中的key lookup操作是我們優化的重點之一,那麼我們如何發現key lookup操作呢?本文介紹兩種方法:
執行計劃圖形展示
執行計劃緩存中查找
sql server用戶端工具ssms可以圖形化方式直覺的展示執行計劃圖形,我們可以通過這個直覺的做圖來發現key lookup操作。比如,我們有如下查詢語句,在執行之前,我們打開實際執行計劃采集開關(可以使用快捷鍵ctrl + m)。
語句執行完畢後,會有execution plan視窗,從這裡我們可以很輕易的看到key lookup事件操作,将滑鼠懸停在key lookup事件上,會有彈窗展示更為詳細的資訊。詳情參見如下截圖,我們可以看到key lookup的性能開銷為50%,占了整個查詢語句性能開銷的一半。開銷算是很高的了。
我們除了可以通過執行計劃圖形展示的方式來發現key lookup操作以外,我們還可以查找執行計劃緩存來讓key lookup操作無所遁形。比如,下面截圖中資訊是剛才執行語句的執行計劃緩存中key lookup操作的xml節點。
是以,我們隻需要搜尋執行計劃緩存,就可以找出哪些執行過的語句使用了key lookup操作,就可以針對性的進行性能優化。查找執行計劃緩存的方法如下:
比如,剛才的執行語句就被抓出來了,展示如下截圖:
從以上的分析,我們知道了key lookup對性能的影響,以及如何發現key lookup操作的語句,接下來的任務就是如何解決key lookup問題了。通常我們有如下方法:
删除不必要字段列
建立覆寫索引
這個解決方法很好了解,因為使用key lookup操作的目的就是為了查找select字句中的字段列,如果我們将業務不必要,或者可要可不需要的字段列删除的話,很可能sql server就不會再走key lookup操作了,是以也就解決了這個問題。一個非常典型的場景是,很多開發人員喜歡使用select * from操作。最好的方式是顯示羅列所有業務必須要使用的字段名字,而不是一股腦兒全部字段都查詢出來。
如果萬一,select中的所有字段都是你業務所必須的,無法删除的話,我們可以考試使用覆寫索引來解決key lookup問題,即建立索引的時候,使用include字句将select後的字段包含在其中(排除在on字句中字段,比如這裡的nationalidnumber字段列)。比如,上面的查詢語句,我們可以建立覆寫索引:
執行完畢後,再次執行該語句,檢視執行計劃,僅一個index seek,沒有key lookup操作,說明這個問題已經得到了解決。詳情參見以下截圖:
如果使用ssms檢視執行sql語句的實際執行計劃,xml 中indexscan節點的lookup屬性值為true,如下展示:
而從執行計劃緩存中擷取到的indexscan節點中lookup屬性值為1。如下展示:
是以,我們在分析執行計劃緩存中的key lookup操作的時候,需要檢查lookup的值是否是1,而不是檢查它是否為true。以下是ssms執行計劃中的xml節點,lookup屬性值為true,而在“執行計劃緩存中查找”章節中的截圖,我們知道lookup屬性值為1。
這篇文章讨論了在性能優化過程中經常要遇到的一個需要優化的點叫key lookup操作,以及我們如何發現key lookup,最後談到了兩種解決key lookup問題的方法。
<a href="https://www.sqlskills.com/blogs/jonathan/finding-key-lookups-inside-the-plan-cache/">finding key lookups inside the plan cache</a>