同事在測試服務器上遇到了一個嚴重的performance問題,請我幫忙(本人非專業DBA,只是相比同事多幹了兩年罷了)看看SQL調優和加index
此SQL是一個較複雜的查詢,inner join/left join了多個表,其中有幾個表的數據量都在百萬級以上。
我拿到手並沒多想,先看了SQL結構,沒什麼大問題。而後就跑了db2expln和db2advis,db2expln 也是顯示每一個表都走index了,沒有掃表的服務器
#### db2advis Recommending indexes... total disk space needed for initial set [ 682.400] MB total disk space constrained to [69886.654] MB Trying variations of the solution set. Optimization finished. 9 indexes in current solution [12511.0449] timerons (without recommendations) [6372.6714] timerons (with current solution) [49.06%] improvement
一看這不顯然Index不足或者有問題嘛,那就按着建議的Index和存在的Index對照着來嘗試嘍。
試了多個Index後發現最多才5%的提高,很鬱悶。但加到一個表的索引後發現timerons忽然反而升高了..並且我加的新索引並未被使用..oop
Recommending indexes... total disk space needed for initial set [ 660.656] MB total disk space constrained to [69886.654] MB Trying variations of the solution set. Optimization finished. 9 indexes in current solution [22776.0215] timerons (without recommendations) [22370.5879] timerons (with current solution) [1.78%] improvement
另:db2expln多了些不一樣的信息性能
Left Outer Nested Loop Join | Piped Inner | Access Table Name = XXXXXX ID = 599,4 | | Index Scan: Name = YYYYYY ID = 3 | | | Regular Index (Not Clustered) | | | Index Columns: | | | | 1: DELETED (Ascending) | | | | 2: OPPORTUNITY_ID (Ascending) | | | | 3: ASSIGNED_USER_ID (Ascending) | | | | 4: TYPE (Ascending) | | #Columns = 0 | | Compressed Table | | #Key Columns = 2 | | | Start Key: Inclusive Value | | | | 1: ? | | | | 2: ? | | | Stop Key: Inclusive Value | | | | 1: ? | | | | 2: ? | | Index-Only Access | | Index Prefetch: Sequential(99), Readahead | | Isolation Level: Uncommitted Read | | Lock Intents | | | Table: Intent None | | | Row : None | | Sargable Index Predicate(s) | | | #Predicates = 1 | | | Insert Into Integer Sorted Temp Table ID = t2 | | | | #Columns = 1 | | | | #Sort Key Columns = 1 | | | | | Key 1: (Ascending) | | | | Sortheap Allocation Parameters: | | | | | #Rows = 28490.000000 | | | | | Row Width = 20 | | | | Duplicate Elimination | Integer Sorted Temp Table Completion ID = t2 | List Prefetch Preparation | | Access Table Name = XXXXXX ID = 599,4 | | | #Columns = 1 | | | Compressed Table | | | RID List Fetch Scan | | | Fetch Using Prefetched List | | | | Prefetch: 105 Pages | | | Isolation Level: Uncommitted Read | | | Lock Intents | | | | Table: Intent None | | | | Row : None | | | Sargable Predicate(s) | | | | #Predicates = 3
優化器查找和使用索引受到了新Index的影響以至影響了性能。
查一下索引統計信息:測試
select substr(INDNAME,1,25) as INDNAME, FULLKEYCARD from syscat.indexes where tabname='XXXXXX' and tabschema='SCTID' # INDNAME FULLKEYCARD 1 YYYYYY -1 2 SSSSSS -1 3 XXXXXX(NEW) 3,844,196 4 ZZZZZZ -1
說明是統計信息有問題才致使的查詢性能問題..
在表上執行了RUNSTATS with indexes all後:fetch
# INDNAME FULLKEYCARD 1 YYYYYY 4,985,715 2 YYYYYY 4,985,715 3 YYYYYY 3,844,196 4 YYYYYY 4,684,818
再次執行db2avis優化
Recommending indexes... total disk space needed for initial set [ 802.328] MB total disk space constrained to [69986.213] MB Trying variations of the solution set. A better solution was found. Continuing search. Optimization finished. 10 indexes in current solution [5586.8818] timerons (without recommendations) [5165.5610] timerons (with current solution) [7.54%] improvement
獲得這個結果後詢問同事,原來他們前兩天剛作過數據移植,這個表的數據量差很少翻了一倍..可是以後應該是沒作過RUNSTATS或者reorg,重啓之類的操做..ui
好吧,此次獲得的經驗教訓就是下次遇到SQL性能問題,先查看錶的統計信息是否正確再研究如何優化索引,不能一發現查詢慢就先考慮優化索引。人仍是要多讀書..
但願本文能起到點拋磚引玉的做用吧。spa
參考:
低基數索引爲何會對性能產生負面影響code