同事在测试服务器上遇到了一个严重的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