Download presentation
Presentation is loading. Please wait.
Published byGavin Blackburn Modified over 10 years ago
1
Practical SQL performance tuning, for developers and DBAs Kurt Struyf Competence Partners
2
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
3
Static SQL One SQL = One access path SELECT … FROM … WHERE NAME BETWEEN :HV1-LOW AND :HV1-HIGH AND FIRSTNAME BETWEEN :HV2-LOW AND :HV2-HIGH AND BIRTHDATE BETWEEN :HV3-LOW AND :HV3-HIGH AND ZIPCODE BETWEEN :HV4-LOW AND :HV4-HIGH Our table has 4 indexes : IX1 on NAME IX2 on FIRSTNAME IX3 on BIRTHDATE IX4 on ZIP CODE AT BIND TIME DB2 CHOOSES IX3 Step1 Step2 Step3 AT RUN TIME User only fills out a value for ZIP CODE Step4 AT RUN TIME DB2 USES IX3 which doesnt filter anything ONE SQL = ONE access path Step5
4
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
5
Index, Stage1, Stage2 DB2 RDS DM Index Stage1 Stage2
6
Indexable Keep it positive and simple! = : equal to > : larger then < : smaller then >= : larger then or equal to <= : smaller then or equal to LIKE IN BETWEEN MUST ALSO BE BOOLEAN DB2 RDS DM Index Stage1 Stage2
7
Matching columns is an indication of how well an index is used, - more matching columns better index use - always start with first index column - on = and on one IN you can continue Example: Index on (Name, Clientno, Salarycode) Predicate Matching --------------------- ------------- 1. Name = Smith AND Clientno = 20 AND Salarycode = 56 2. Name = Smith OR Clientno > 20 AND Salarycode = 56 3. Name IN (Smith, Doe) AND Clientno > 20 AND Salarycode = 56 Matching Columns Predicate Matching --------------------- ------------- 4. Name IN (Smith, Doe) AND Clientno IN (20,30) AND Salarycode > 0 5. Name <> Smith AND Clientno = 56 6. Clientno = 56 AND Salarycode = 0
8
Stage 1 Keep it positive and simple but no index! = : equal to > : larger then < : smaller then >= : larger then or equal to <= : smaller then or equal to LIKE IN BETWEEN DB2 RDS DM Index Stage1 Stage2 Keep it simple but not positive ! Keep it simple but not Boolean !
9
Stage 2 All the rest !! All functions such as –SUBSTR –CONCAT –CHAR() Mismatching data types –Colchar_6 = 1234567 Host variable checking –AND :HV1 = 5 Decryption Current date between col1 and col2 Sorting DB2 RDS DM Index Stage1 Stage2
10
In COBOL checking stage 3 NEVER (ab)use this! All DB2 columns that CAN be checked in SQL SHOULD be checked in SQL So BETTER a Stage2 predicate then NO predicate DB2 RDS DM Index Stage1 Stage2 IN COBOL
11
Index, Stage1, Stage2 DB2 RDS DM Index Stage1 Stage2
12
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
13
Sort impact Sort YES : at open cursor all rows are retrieved (e.g. 3000) fetch 20 rows to build first screen, user found his info and aborts RESULT : 2980 rows needless retrieved Sort NO : at fetch time first row retrieved fetch 20 rows to build first screen, user found his info and aborts RESULT : ONLY 20 rows retrieved from DB2, no sort cost
14
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
15
Select * SELECT * almost never to be used SELECT ONLY COLUMNS that are needed ! Reason : –Program maintenance –CPU cost per extra column –SORT file becomes bigger –Maybe not index only
16
Select * Even for : where… exists (select *…) Better where… exists (select 1…) Select …col5,… where col5= AB Better Select …AB… where col5= AB Select col1, col2…order by col2 Better Select col1…order by col2 if just for order by
17
Mismatching datatype Mismatching Datatypes Are Stage2 COL_char(6) = ABCDEF COL_dec = :hostvar-int COL_dec = decimal(:hostvar-integer) COL_int < 10.5 COL_int < integer(10.5) COL_int < 10 COL_dec = :hostvar-dec + 2 COL_dec = decimal(:hostvar-dec + 2) move hostvar-dec +2 to hostvar2-dec COL_dec = :hostvar2-dec
18
Other easy improvements :hv between col1 and col2 col1 >= :hv and col2 <= :hv Substr(name,1,2) = MI name like MI% But be careful for %MI% Substr(name,5,2) = MI denormalize V9 index on expression COL_date <> 9999-12-31 COL_date < 9999-12-31 COL_int <> 0 COL_int > 0 COL <> :hv COL in (,,,,, ) COL not 5
19
More easy improvements Col1=A or Col1= B Col1 in (A,B) Col1>= :hv1 and COL1<=:hv2 Col1 between :hv1 AND :hv2 Col1 >= :hv1 AND Col1 = :hv1 or (col1=:hv1 or Col1 >:hv1 and Col2 = :hv2 col1>:hv1 and col2 =:hv2) Col1 = :hva (always 5) Col1 = 5 :hv = 5 IN COBOL !!!
20
Even More easy improvements Col1 not between 10 and 50 …col 1 50… Existence checking select 1 from table where col1 =:hv fetch first 1 row only Col1 not in (A, B, C) if possible Col1 in (…the rest) will be cheaper even when list is bigger
21
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
22
Determine Access Path Optimization Service Center Newest generation of Visual explain Plan_table See next slide Might require some exercise Not everything in it DSN_statement_table Contains the Cost columns
23
DB2 Plan_table SELECT QBLOCKNO, PROGNAME, PLANNO, METHOD, TNAME, ACCESSTYPE, MATCHCOLS, ACCESSNAME, INDEXONLY, PREFETCH FROM PLAN_TABLE WHERE QUERYNO = 30303 ORDER BY QBLOCKNO, PLANNO ; QBLOCKNO PROGNAME PLANNO METHOD TNAME ACCESSTYPE MATCHCOLS ACCESSNAME INDEXONLY PREFETCH 1 DSNESM68 1 0 AATEHA1 I 2 AAX0EHA1 N 1 DSNESM68 2 1 AATEHB1 I 2 AAX0EHB1 N 1 DSNESM68 3 3 0 N Qblockno: indicates the number blocks necessary to resolve the query –General rule, more blocks = less performing Progname: represents the program/package name
24
Access path: planno, method Planno: the number of steps AND the sequence in which a query is resolved –General rule, more steps = less performing Method: expresses what kind of access is done –0 : First access –1 : Nested Loop Join –3 : extra sort needed Tname: table name to be accessed Access type : how that data is accessed …
25
DSN_Statement_Table Amongst others : COST_CATEGORY: A: Indicates that DB2 had enough information to make a cost estimate without using default values. B: Indicates that some condition exists for which DB2 was forced to use default values. PROCMS: The estimated processor cost, in milliseconds, for the SQL statement PROCSU: The estimated processor cost, in service units, for the SQL statement
26
Agenda One SQL, one access path Index, stage1, stage2 Sort impact SQL examples of sub optimal coding and its improvements Access path fields in the plan_table Other CPU saving techniques
27
Multi Row fetch Technique to save up to 60% of DB2 cpu Easy to use Fetches a rowset into an array Program can control size of rowset
28
Multi Row Fetch To be able to use this, the cursor should be DECLAREd for rowset positioning, for example: EXEC SQL DECLARE cursor-name CURSOR WITH ROWSET POSITIONING FOR SELECT column1,column2 FROM table-name; END-EXEC instead of EXEC SQL DECLARE cursor-name CURSOR FOR SELECT column1,column2 FROM table-name; END-EXEC Then you can FETCH multiple rows at-a-time from the cursor
29
Multi Row Fetch On the FETCH statement –the amount of rows requested can be specified for example: EXEC SQL FETCH NEXT ROWSET FROM cursor-name FOR :rowset-size ROWS INTO … END-EXEC instead of EXEC SQL FETCH cursor-name INTO … END-EXEC The rowset size can be defined as a constant or a variable, for example: 01 rowset-size PIC S9(09) COMP-5.
30
Multi Row fetch Do not use single and multiple row fetch for the same cursor in one program Be aware of compiler limits –elementary item : max. 16Mb –complete working storage : max 128 Mb Last FETCH on a rowset can be incomplete
31
Multi Row Fetch Performance results may differ: –< 5 rows : poor performance (worse than before) –10 – 100 rows : best performance –> 100 rows : no improvement anymore Following data is based upon treatment of 1 million rows (in seconds CPU). Via rowVia rowsetGain on DB2 in CPU seconds FETCH16610 (-60%) FETCH + UPDATE via row766610 (-15%) FETCH + UPDATE via rowset766016 (-35%)
32
Sequences Easy, fast and cheap way to generate unique numbers if : Holes are allowed The order isnt important Use : next value for yy.xxxxxxxx statement BASIC SYNTAX : CREATE SEQUENCE yy.xxxxxxxx START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE NO CYCLE CACHE 200;
33
Sequences Better response times Less cpu need
34
Questions ? Kurt.struyf@cp.be
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.