分享DB2 SQL查詢性能問題一例

同事在測試服務器上遇到了一個嚴重的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

相關文章
相關標籤/搜索