本文出處:http://www.cnblogs.com/wy123/p/6694933.html
第一次通過索引視圖優化SQL語句,以及遇到的一些問題,記錄一下。
語句分析
最近開發遞交過來一個查詢統計的SQL,說是性能有問題,原本執行需要4-5秒鍾,這個業務本身對性能要求又比較critical,期望是在1s之內 在用盡各種辦法之后(執行計划,統計信息,索引,改寫SQL,臨時表拆分),依然沒有實質性的改觀, 在觀察SQL本身的特點之后, 有以下幾個特點 1,查詢語句整體為多表join,但是每個表自身的數據並不是非常大,百萬級 2,查詢結果在主表上一個較大的時間范圍的數據進行Count的聚合操作 3,幾張表之間除了連接條件,主要是進行了一些比較復雜的邏輯運算(下面截圖可以看到,沒多少IO,CPU時間卻很高) 不過表的連接方式都是inner join,主要性能點就在於表關聯之間的Hash join之間的邏輯運算,參考下圖(是執行計划的一部分)
通過統計信息發現,該SQL語句的物理IO並不高,說明索引沒有什么問題,通過索引改善IO可能改善空間很有限 時間主要花費在SQL語句的編譯和的Hash join 運算 嘗試改寫借助SQL之后(純改寫SQL和借助臨時表拆分語句),發現依然很難繞過Hash join,主要是表之間的邏輯運算最為耗時 最后想到可以先將運算好的的數據物理存儲起來,然后改寫查詢的SQL語句完成等價的查詢, 避免每次查詢都做復雜的邏輯運算,應該可以有比較大的改善,於是就想到了索引視圖
創建索引視圖改寫SQL
在提取出來原始的查詢SQL,創建索引視圖,並在索引視圖上創建unique cluster index和合理的nocluster index 通過索引視圖改寫原始的查詢統計SQL語句, 改寫后的SQL語句是一個索引視圖替代原始的4張表,與另外一個物理表join,發現效率上沒有任何改善, 觀察改寫后的SQL語句的執行計划,發現跟原始SQL一樣,並沒有走索引視圖上的索引,或者說是用到索引視圖,一時間覺得好心塞,實在沒招了 執行計划依舊是長長的一大段,然后依舊是好幾個Hash Join.參考下圖,執行計划跟本文第一個截圖一模一樣
按道理,索引視圖固化結果集,並且根據情況做了過濾,結果集是原始查詢的一部分而已, 用同樣的查詢條件從索引視圖做查詢統計,走索引視圖代價肯定要比原始SQL低,通過強制不展開with(noexpand)提示,證實了這個推斷 如下是強制不展開索引視圖的統計信息,可以看到完全達到了預期的1S之內
當然索引視圖也不是沒有代價,在一定程度上犧牲了數據寫入的效率和冗余存儲,來換取查詢的效率 之前簡單介紹過索引視圖的一些特點 http://www.cnblogs.com/wy123/p/6041122.html
索引視圖被展開(expand)的原因分析
最關鍵的問題在於,沒有強制不展開索引視圖(with(noexpand)提示)的情況下,為什么沒有走索引視圖呢?
這個問題確實郁悶了一陣子,整個半天都在想這個問題,因為索引視圖本身用的就少,出現此問題更是一頭霧水,不過Google一下,還有一大把類似的問題 如下是在google的時候查到的,原文是英文,大概意思如下,非直譯。
索引視圖的匹配(查詢用索引視圖替代而不走原始的基礎表)是一個相當昂貴的操作,因此優化器試圖通過其他方式快速轉換(生成執行計划) 如果優化器產生了一個相對優化的執行計划,就可以盡早結束(不必繼續生成其他執行計划) 問題就在於:繼續生成其他執行計划的代價要大於已生成的執行計划的代價 聽起來有點別扭, 之前舉過這么一個例子,比如說是花3秒鍾找到一個相對優化的執行計划,這個執行計划完成SQL的執行需要2秒鍾 與花10秒鍾的時候找到一個最優化的執行計划,盡管這個執行計划完成SQL的執行可能只需要0.5秒鍾,雖然后者的執行計划更優,但整體代價更大 優化器的主要目標是盡快找到一個足夠好的執行計划(而非總是生成最好的執行計划)
使用索引視圖本身並不是一個昂貴的操作, 但是與潛在索引視圖中匹配邏輯查詢樹確實一個代價較大的行為,在查詢涉及的視圖在優化器優化之前已經被展開 因此優化器並不知道你的查詢是否未被了索引視圖,他看到的只是展開的查詢樹 這個通俗地講就是: 讓sqlserver知道,一個查詢,可以用索引視圖中的結果等價替代視圖邏輯中原始的基表,是一個代價較大的過程 因為SQL Server根據原始的基礎表,生成一種執行計划之后,就不去判斷是否可以用索引視圖做等價替代。
當然白皮書里有更詳細的介紹,里面索引視圖相關的一些邏輯實現和分析http://www.cs.cmu.edu/~natassa/courses/15-823/current/papers/vldb00.pdf
最后多逼逼一句: 上面的白皮書實在看不懂,只是Google出來說詳細信息請看這個參考資料, 這里只是從現象去推斷優化器在面對索引視圖的一些特性,了解到內在機制的一些特點,可能潛在的問題,以及對應的解決辦法