db2 v7 and beyond"

57
06/07/22 06/07/22 DB2 V7 and Beyond: Rick Egleston © DB2 V7 and Beyond: Rick Egleston © 2006 2006 1 DB2 V7 and Beyond: DB2 V7 and Beyond: How newer DB2 How newer DB2 capabilities can capabilities can simplify age-old coding simplify age-old coding challenges on Z/os challenges on Z/os machines machines

Upload: tess98

Post on 20-Jan-2015

190 views

Category:

Documents


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

11

DB2 V7 and Beyond:DB2 V7 and Beyond:

How newer DB2 How newer DB2 capabilities can simplify capabilities can simplify

age-old coding age-old coding challenges on Z/os challenges on Z/os

machinesmachines

Page 2: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

22

IBM focused on the applications IBM focused on the applications developers this time, not just the developers this time, not just the

administrators!administrators!

Newer features of DB2 can really Newer features of DB2 can really help:help:– Simplify programsSimplify programs– Enable granting of previously avoided Enable granting of previously avoided

user requestsuser requests– Improve reliability Improve reliability – Increase table availabilityIncrease table availability– Allow program features on the Allow program features on the

mainframe that users have become mainframe that users have become accustomed to on distributed platformsaccustomed to on distributed platforms

Page 3: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

33

DB2 V7 and Beyond:DB2 V7 and Beyond:

Mismatched Joins –Mismatched Joins – Now actually possible Now actually possible

Page 4: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

44

Joining Tables with Joining Tables with Mismatched Data Mismatched Data

TypesTypes In prior versions of DB2 this was a In prior versions of DB2 this was a

severe index killersevere index killer Example:Example:

Table A has CUSTOMER_NBR stored as Table A has CUSTOMER_NBR stored as CHAR(8) but it really only contains CHAR(8) but it really only contains numeric datanumeric dataTable B has the same column but Table B has the same column but stores it as an INTEGERstores it as an INTEGER

You want to join ‘emYou want to join ‘em

Page 5: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

55

Joining Tables with Joining Tables with Mismatched Data Mismatched Data TypesTypes The old ways:The old ways:

– Create a cross-reference table with both Create a cross-reference table with both columns columns

Maintenance problem and wastes spaceMaintenance problem and wastes space

– Put columns on both tables with both Put columns on both tables with both datatypesdatatypes

Confusing and wastes spaceConfusing and wastes space

– Open a cursor against A, fetch through it, Open a cursor against A, fetch through it, cycling a second cursor against B for each cycling a second cursor against B for each rowrow

Very inefficient and messy to codeVery inefficient and messy to code

Page 6: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

66

Joining Tables with Joining Tables with Mismatched Data Mismatched Data TypesTypes Newer ways:Newer ways:

– DB2 is much more tolerant now of DB2 is much more tolerant now of what is on the right side of the what is on the right side of the operator (=, <, > etc)operator (=, <, > etc) Most Scalar functions are allowedMost Scalar functions are allowed Concatenation is allowedConcatenation is allowed Mismatched lengths are allowed in Mismatched lengths are allowed in

many casesmany cases

Page 7: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

77

Joining Tables with Joining Tables with Mismatched Data Mismatched Data TypesTypes In our example of joining two tables with In our example of joining two tables with

mismatched datatypes, we can do some mismatched datatypes, we can do some conversionsconversions

WHERE A.CUST_NBR = WHERE A.CUST_NBR = SUBSTR(CHAR(DIGITS(B.CUST_NBR))),3,8SUBSTR(CHAR(DIGITS(B.CUST_NBR))),3,8))– DIGITS lets us extract the Integer as DIGITS lets us extract the Integer as

characterscharacters WHERE B.CUST_NBR = WHERE B.CUST_NBR =

INTEGER(A.CUST_NBR)INTEGER(A.CUST_NBR)

Page 8: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

88

Joining Tables with Joining Tables with Mismatched LengthsMismatched Lengths

This also was an index killer in prior This also was an index killer in prior versions of DB2 versions of DB2

Example:Example:Table A has CUSTOMER_NBR stored as Table A has CUSTOMER_NBR stored as CHAR(8) and CUSTOMER_LOC stored CHAR(8) and CUSTOMER_LOC stored as CHAR(4) as CHAR(4) Table B has one column with the two Table B has one column with the two combined CUST_LOC_NBR CHAR(12)combined CUST_LOC_NBR CHAR(12)

You want to join ‘emYou want to join ‘em

Page 9: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

99

Joining Tables with Joining Tables with Mismatched LengthsMismatched Lengths Again, we can use concatenations or Again, we can use concatenations or

substringssubstrings WHERE A.CUST_NBR = WHERE A.CUST_NBR = SUBSTR(CUST_LOC_NBR,5,8)SUBSTR(CUST_LOC_NBR,5,8)

AND A.CUST_LOC = AND A.CUST_LOC = SUBSTR(CUST_LOC_NBR,1,4)SUBSTR(CUST_LOC_NBR,1,4)

– This will split out the two componentsThis will split out the two components

WHERE B.CUST_LOC_NBR =WHERE B.CUST_LOC_NBR = A.CUST_LOC||A.CUST_NBRA.CUST_LOC||A.CUST_NBR

– This will put the two components togetherThis will put the two components together

Page 10: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1010

Joining Tables with Joining Tables with Mismatched Data Mismatched Data TypesTypes Remember a few things:Remember a few things:

– Always have the column you want to Always have the column you want to index on to the left of the operatorindex on to the left of the operator

– NEVER put a function on the left of NEVER put a function on the left of the operator if you want indexes to the operator if you want indexes to be usedbe used

– ALWAYS do an EXPLAIN, these tricks ALWAYS do an EXPLAIN, these tricks don’t work in every scenariodon’t work in every scenario

Page 11: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1111

DB2 V7 and Beyond:DB2 V7 and Beyond:

Nested Table Nested Table Expressions- Cool toy but Expressions- Cool toy but

are they usefulare they useful

Page 12: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1212

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions What is an NTE?What is an NTE?

– Treating a Select as if it were a tableTreating a Select as if it were a table

SELECT * SELECT *

FROM TABLE (FROM TABLE (

SELECT * FROM SELECT * FROM

TABLE_A A, TABLE_A A,

TABLE_B B)TABLE_B B)

Page 13: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1313

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions What good are they?What good are they?

– You can do GROUP BYs on the result You can do GROUP BYs on the result of another GROUP BY of another GROUP BY

– You can do incompatible JOINS on You can do incompatible JOINS on multiple tablesmultiple tables

– You can make the DBAs REALLY You can make the DBAs REALLY angry if you are not careful – we’ll angry if you are not careful – we’ll get to that get to that

Page 14: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1414

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions Let’s do it - Compounded Group By Let’s do it - Compounded Group By

– Get me the number of customers and total big bill amount Get me the number of customers and total big bill amount at each terminal that has at least 1000 bills > 500.00 eachat each terminal that has at least 1000 bills > 500.00 each

SELECT X.TERM, COUNT(*), SUM(X.TOTAL_AMT)SELECT X.TERM, COUNT(*), SUM(X.TOTAL_AMT) FROM TABLE (FROM TABLE ( SELECTSELECT TERMINAL, CUSTOMER, SUM(BILL_AMT), COUNT(*)TERMINAL, CUSTOMER, SUM(BILL_AMT), COUNT(*)

FROM TBL_BILLSFROM TBL_BILLS WHERE BILL_AMT > 500.00WHERE BILL_AMT > 500.00 GROUP BY TERMINAL, CUSTOMERGROUP BY TERMINAL, CUSTOMER HAVING COUNT(*) > 1000HAVING COUNT(*) > 1000 ) AS X(TERM, CUST, TOTAL_AMT, BILL_CNT)) AS X(TERM, CUST, TOTAL_AMT, BILL_CNT) GROUP BY TERMINALGROUP BY TERMINAL

Page 15: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1515

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions Let’s do it - Incompatible Joins Let’s do it - Incompatible Joins You need to join multiple tables,You need to join multiple tables,

– Two of the tables must be LEFT Two of the tables must be LEFT OUTER JOINED and then you want to OUTER JOINED and then you want to LEFT OUTER JOIN a third table to the LEFT OUTER JOIN a third table to the results of thisresults of this

– How do you do this???? How do you do this???? Nested Table Expressions Nested Table Expressions

Page 16: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1616

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressionsSelect * Select * FROM TBL_A aFROM TBL_A a left outer join tableleft outer join table ((

select * select * from tbl_b bfrom tbl_b b left outer join tbl_c c left outer join tbl_c c on b.customer_nbr = c.customer_nbron b.customer_nbr = c.customer_nbr ) As x ) As x on a.customer_loc = x.customer_loc on a.customer_loc = x.customer_loc

Page 17: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1717

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions Lets make a DBA angry!

– Actually, that’s not such a good idea, so lets look at a few things to keep in mind to avoid this

Be aware that NTEs use an area of DB2 called DSNDB07– This is a shared area used by sorts, NTEs,

materialized views and a lot of other things

– This can become a real problem if you are not careful, this area is NOT limitless!

Page 18: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1818

Real use for NTEs Real use for NTEs Nested Table Nested Table ExpressionsExpressions So, how Do we avoid causing problems?

– Use Indexes, both inside and outside NTE– Use FETCH FIRST nnn ROWS ONLY

This limits the total rows returned, but not the rows on the inside SQL statement

– Carefully craft your select inside the NTE to return a controlled result

Don’t just join both tables and get an NTE with 100000 rows then select off two with the outer select

– If you are not sure you can control it, don’t use it Your scenario might be one to do the old way with a couple

of cursors

– Use EXPLAIN!

Page 19: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

1919

DB2 V7 and Beyond:DB2 V7 and Beyond:

Taming RIDLIST indexingTaming RIDLIST indexing

Page 20: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2020

Taming RIDLIST Taming RIDLIST processingprocessing What is it?What is it?

– Every row in a table has a Row Every row in a table has a Row Identifier (RID) which is used Identifier (RID) which is used internally by DB2internally by DB2

– Some SQL really could benefit from Some SQL really could benefit from two different Indexes, but DB2 can two different Indexes, but DB2 can only use one at a time… Until NOW!only use one at a time… Until NOW!

– At the simplest level, a RIDLIST At the simplest level, a RIDLIST index process is simply a join index process is simply a join between two index resultsbetween two index results

Page 21: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2121

Taming RIDLIST Taming RIDLIST processingprocessing How does it work?How does it work?

– DB2 scans one or more indexes and DB2 scans one or more indexes and creates a temporary result which creates a temporary result which consists of the RIDS of all rows consists of the RIDS of all rows qualifying for each indexqualifying for each index

– It uses these results to rescan It uses these results to rescan looking for the LEFT JOIN of all of the looking for the LEFT JOIN of all of the results (i.e.: rows from each that results (i.e.: rows from each that match ALL criteria)match ALL criteria)

– You then get the desired resultsYou then get the desired results

Page 22: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2222

Taming RIDLIST Taming RIDLIST processingprocessing Sounds good, how can this help?Sounds good, how can this help?

– Can undo the harm caused by Can undo the harm caused by having ‘OR’s mixed in with ‘AND’s having ‘OR’s mixed in with ‘AND’s on a tableon a table

– Allows a column in one table to be Allows a column in one table to be matched to multiple columns in a matched to multiple columns in a second tablesecond table

– Can make previously unworkable Can make previously unworkable SQL work decentlySQL work decently

Page 23: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2323

Taming RIDLIST Taming RIDLIST processingprocessing Here’s an exampleHere’s an example

– SELECT * SELECT * FROM TBL_CUST A, TBL_BILL BFROM TBL_CUST A, TBL_BILL B

WHERE A.CUST_NBR = :WS-CUSTWHERE A.CUST_NBR = :WS-CUST AND B.CUST_NBR = A.CUST_NBRAND B.CUST_NBR = A.CUST_NBR AND (A.CUST_LOC = B.LOC_1 ORAND (A.CUST_LOC = B.LOC_1 OR

A.CUST_LOC = B.LOC_2 ORA.CUST_LOC = B.LOC_2 OR A.CUST_LOC = B.LOC_3 ORA.CUST_LOC = B.LOC_3 OR

A.CUST_LOC = B.LOC_4 )A.CUST_LOC = B.LOC_4 )

This can create 4 RIDLISTS against TBL_BILL if each This can create 4 RIDLISTS against TBL_BILL if each “loc” column has an index on TBL B and avoid a scan“loc” column has an index on TBL B and avoid a scan– Previously this would be a tablespace scan against Previously this would be a tablespace scan against

TBL_BILLTBL_BILL

Page 24: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2424

Taming RIDLIST Taming RIDLIST processingprocessing That’s cool, how can this ever be That’s cool, how can this ever be

bad?bad?– DB2 may choose two indexes that DB2 may choose two indexes that

on their own would return a majority on their own would return a majority of the table, then JOIN them of the table, then JOIN them

– This may result in the equivalent of This may result in the equivalent of two or more full table scans, far two or more full table scans, far worse than using no indexes at allworse than using no indexes at all

Page 25: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2525

Taming RIDLIST Taming RIDLIST processingprocessing Example:Example:

– Table has 1250000 rowsTable has 1250000 rows Two separate indexes Two separate indexes

– CUST_NBR and BILL_DATECUST_NBR and BILL_DATE I ask for everything for a customer on a dateI ask for everything for a customer on a date

– The customer has 5000 total entries on the tableThe customer has 5000 total entries on the table– There are 60000 total rows for this dateThere are 60000 total rows for this date– This customer has 10 rows on the chosen dateThis customer has 10 rows on the chosen date– RIDLIST would get one result of 5k, another of 60k RIDLIST would get one result of 5k, another of 60k

and join them to get just 10 rowsand join them to get just 10 rows

Page 26: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2626

Taming RIDLIST Taming RIDLIST processingprocessing How do I know this has happened?How do I know this has happened?

– The only way to know for sure is EXPLAINThe only way to know for sure is EXPLAIN– Watch for is unexpected performance Watch for is unexpected performance

degradation after changes degradation after changes – If you change and/or rebind a program that If you change and/or rebind a program that

was bound on an earlier version of DB2 it may was bound on an earlier version of DB2 it may change access path, even on unchanged SQLchange access path, even on unchanged SQL

You change a report heading and now the program You change a report heading and now the program runs 20 minutes instead of 2…runs 20 minutes instead of 2…

The SQL looks good (no improper functions, has The SQL looks good (no improper functions, has index columns referenced etc) but it really runs bad index columns referenced etc) but it really runs bad ……

Page 27: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2727

Taming RIDLIST Taming RIDLIST processingprocessing What do I do about it?What do I do about it?

– See if you can add a column to one of the See if you can add a column to one of the indexes to eliminate the need for RIDLISTindexes to eliminate the need for RIDLIST

Check to see if you can add DATE to the Check to see if you can add DATE to the CUSTOMER index, if you can then do itCUSTOMER index, if you can then do it

– Rewrite the SQL to use a different index or Rewrite the SQL to use a different index or different criteriadifferent criteria

– Okay, none of that was possible, what Okay, none of that was possible, what now?now?

Put a Scalar function on the left of the = signPut a Scalar function on the left of the = sign– Remember that this kills indexingRemember that this kills indexing

AND DATE(BILL_DATE) = :WS-BILL-DATEAND DATE(BILL_DATE) = :WS-BILL-DATE

Page 28: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2828

DB2 V7 and Beyond:DB2 V7 and Beyond:

Difficult CICS PagingDifficult CICS Paging

Page 29: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

2929

Difficult CICS Paging:Difficult CICS Paging: Descending keys mixed in with Ascending keysDescending keys mixed in with Ascending keys

Users functional request: Users functional request: – A screen to view customer account invoice A screen to view customer account invoice

status – by selected Customer Accountstatus – by selected Customer Account– Have the ability to view “ALL” or just the Have the ability to view “ALL” or just the

“UNPAID” accounts“UNPAID” accounts– Ignore the ENTRY DATE in the sort if the Ignore the ENTRY DATE in the sort if the

screen is in “UNPAID” modescreen is in “UNPAID” mode– Smooth paging (i.e.: Page-Up goes to the Smooth paging (i.e.: Page-Up goes to the

previous page not the top of list)previous page not the top of list)– Dynamic (i.e.: paging keeps up with Dynamic (i.e.: paging keeps up with

database changes)database changes)– 15 lines of detail per page15 lines of detail per page

Page 30: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3030

Difficult CICS Paging:Difficult CICS Paging: Descending keys mixed in with Ascending keysDescending keys mixed in with Ascending keys

Users Want it Sorted by …Users Want it Sorted by …– Customer Loc Customer Loc AscendingAscending– Paid DatePaid Date Descending !!!Descending !!!– Entry Date Entry Date AscendingAscending

> Ignore in “UNPAID” mode> Ignore in “UNPAID” mode– Invoice NumberInvoice Number AscendingAscending

Page 31: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3131

Difficult CICS Paging:Difficult CICS Paging:The TableThe Table

CUSTOMER_ACCTCUSTOMER_ACCT CHAR(8)CHAR(8)

CUSTOMER_LOC CUSTOMER_LOC CHAR(4)CHAR(4)

PAID_DATEPAID_DATE DATEDATE

ENTRY_DATE ENTRY_DATE DATEDATE

INVOICE_NUMBERINVOICE_NUMBER CHAR(10)CHAR(10)

Page 32: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3232

Difficult CICS Paging:Difficult CICS Paging: Descending keys mixed in with Ascending keysDescending keys mixed in with Ascending keys

Older ways of solving this:Older ways of solving this:– Build a TSQ and use external SortBuild a TSQ and use external Sort

Very inefficient if result set is largeVery inefficient if result set is large Not dynamic unless you always rebuild TSQNot dynamic unless you always rebuild TSQ

– Have lots of ‘OR’s in parenthesis with Have lots of ‘OR’s in parenthesis with ‘AND’s‘AND’s

Most likely not indexable at allMost likely not indexable at all

– Have multiple cursors with slightly Have multiple cursors with slightly different WHERE clausedifferent WHERE clause

Not much fun to maintainNot much fun to maintain

– Tell ‘em noTell ‘em no Yeah right…..Yeah right…..

Page 33: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3333

Difficult CICS Paging:Difficult CICS Paging: Descending keys mixed in with Ascending keysDescending keys mixed in with Ascending keys

Newer ways to solve this:Newer ways to solve this:– ““Derived Columns”Derived Columns”

Use Case Statements and Scalar Use Case Statements and Scalar FunctionsFunctions

– ““Compound Keys”Compound Keys” Build Derived Columns and keys to work Build Derived Columns and keys to work

with themwith them

– Switches in the WHERE clauseSwitches in the WHERE clause

Page 34: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3434

Derived ColumnsDerived Columns

Can reverse a value to make an Can reverse a value to make an ascending sort result in descending ascending sort result in descending orderorder

Select Select

Digits(Days(‘9999-12-31’) – Days Digits(Days(‘9999-12-31’) – Days (Paid_Date))(Paid_Date))

More current dates will have lower values, More current dates will have lower values, sorting this ascending actually results in a sorting this ascending actually results in a descending sortdescending sort

Page 35: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3535

Derived ColumnsDerived ColumnsReversing Sort OrderReversing Sort Order

Paid DatePaid Date Derived Value Derived Value OrderOrder

2006-07-182006-07-18 00029195410002919541 11

2006-01-152006-01-15 00029197330002919733 22

2005-02-012005-02-01 00029200810002920081 33

2000-08-022000-08-02 00029217250002921725 44

We sort Ascending by Derived Value and We sort Ascending by Derived Value and the dates come out in Descending the dates come out in Descending order !!!order !!!

Page 36: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3636

Derived ColumnsDerived ColumnsSelectively ignoreSelectively ignore

In “UNPAID” mode we want to ignore In “UNPAID” mode we want to ignore Entry Date in sort orderEntry Date in sort order

CASECASE WHEN :WS-SCREEN-MODE = ‘U' WHEN :WS-SCREEN-MODE = ‘U' THEN '0001-01-01' THEN '0001-01-01'

ELSE ENTRY_DATEELSE ENTRY_DATE END CASEEND CASE

This causes the column always being ‘0001-This causes the column always being ‘0001-01-01’ in “UNPAID” mode, effectively 01-01’ in “UNPAID” mode, effectively ignoring itignoring it

Page 37: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3737

Difficult CICS PagingDifficult CICS PagingThe Select ClauseThe Select Clause

SelectSelect Digits(Days(‘9999-12-31’) – Days (Paid_Date)) Digits(Days(‘9999-12-31’) – Days (Paid_Date)) ,CASE,CASE

WHEN :WS-SCREEN-MODE = 'A' WHEN :WS-SCREEN-MODE = 'A' THEN '0001-01-01' THEN '0001-01-01' ELSE Entry_DateELSE Entry_DateEND CASEEND CASE

,Customer_Acct,Customer_Acct ,Customer_Loc ,Customer_Loc ,Paid_Date,Paid_Date ,Entry_Date ,Entry_Date ,Invoice_Number,Invoice_Number

Page 38: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3838

Difficult CICS PagingDifficult CICS PagingThe Order By The Order By

Order by Order by Customer Loc Customer Loc ,1,1 ,2 ,2 ,Invoice Number,Invoice NumberFETCH FIRST 16 ROWS ONLYFETCH FIRST 16 ROWS ONLY The 1 and 2 refer to the value in that position of The 1 and 2 refer to the value in that position of

the result set (i.e.: the first and second the result set (i.e.: the first and second columns).columns).

We will save off the 16We will save off the 16thth row as the forward row as the forward paging key. If we get +100 before then we are paging key. If we get +100 before then we are at EOFat EOF

Page 39: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

3939

Difficult CICS PagingDifficult CICS PagingThe WHERE clauseThe WHERE clause

WHERE CUSTOMER_ACCT = :WS-CUST-ACCTWHERE CUSTOMER_ACCT = :WS-CUST-ACCT AND CUSTOMER_LOC >= :WS-CUST-LOCAND CUSTOMER_LOC >= :WS-CUST-LOC AND CUSTOMER_LOC||AND CUSTOMER_LOC|| DIGITS(DAYS(‘9999-12-31’) – DIGITS(DAYS(‘9999-12-31’) –

DAYS(PAID_DATE))||DAYS(PAID_DATE))|| CHAR(DATE('0001-01-01') + CHAR(DATE('0001-01-01') + ((DAYS(ENTRY_DATE) - ((DAYS(ENTRY_DATE) - DAYS(DATE('0001-01-01'))) * DAYS(DATE('0001-01-01'))) * :WS-SCREEN-MODE-NUM) DAYS)||:WS-SCREEN-MODE-NUM) DAYS)|| INVOICE_NBR >= :WS-PAGING-KEYINVOICE_NBR >= :WS-PAGING-KEY AND (:WS-SCREEN-MODE = 'A' ORAND (:WS-SCREEN-MODE = 'A' OR DATE_PAID = '0001-01-01')DATE_PAID = '0001-01-01')

Page 40: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4040

Difficult CICS PagingDifficult CICS PagingThe Where clause – The Where clause –

Explained!Explained!

First lets start with the table’s First lets start with the table’s index:index:– We do want this to run efficientlyWe do want this to run efficiently

The table has 750000 rowsThe table has 750000 rows There are have 5000 customers across There are have 5000 customers across

150 locations150 locations

Lets look at the index on the table Lets look at the index on the table that will make this SQL workthat will make this SQL work

Page 41: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4141

Difficult CICS PagingDifficult CICS PagingThe WHERE clause - The WHERE clause -

Explained!Explained!ColumnColumn CardinalityCardinalityCUSTOMER_ACCTCUSTOMER_ACCT 50005000CUSTOMER_LOCCUSTOMER_LOC 150150INVOICE_NBRINVOICE_NBR 750000750000

• Invoice number would be a perfect key…Invoice number would be a perfect key…• But we don’t have it, we were given CUSTOMER_ACCTBut we don’t have it, we were given CUSTOMER_ACCT• It’s the third column in this index, indexes must be used It’s the third column in this index, indexes must be used

from the top down to work efficientlyfrom the top down to work efficiently• Remember that Cardinality assumes even distribution Remember that Cardinality assumes even distribution

(A perfect world)(A perfect world)• This is not a perfect world so it is only a good This is not a perfect world so it is only a good

approximation to gauge efficiencyapproximation to gauge efficiency• Cardinality becomes less significant further down an Cardinality becomes less significant further down an

index.index.

Page 42: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4242

Difficult CICS PagingDifficult CICS PagingThe Where Clause – The Where Clause –

Explained!Explained! Lets break it down …Lets break it down …

CUSTOMER_ACCT = :WS-CUST-ACCTCUSTOMER_ACCT = :WS-CUST-ACCT

This is our big performance helper, This is our big performance helper, without it our SQL would be horrifyingwithout it our SQL would be horrifying

It cuts our 750000 row table into around It cuts our 750000 row table into around 5000 eligible rows5000 eligible rows

Page 43: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4343

Difficult CICS PagingDifficult CICS PagingThe Where Clause – The Where Clause –

Explained!Explained! AND CUSTOMER_LOC >= :WS-CUST-LOCAND CUSTOMER_LOC >= :WS-CUST-LOC

This cuts the 5000 rows down to 33, well not This cuts the 5000 rows down to 33, well not really really – No one customer uses all 150 locations (they No one customer uses all 150 locations (they

probably use around 4 at most) probably use around 4 at most) – More realistically we are left with 125 or so rowsMore realistically we are left with 125 or so rows

If you remember back to the WHERE clause, If you remember back to the WHERE clause, this also appears in the big concatenationthis also appears in the big concatenation

This is not redundant, once you start using || This is not redundant, once you start using || and scalar functions, DB2 cannot use that and scalar functions, DB2 cannot use that criteria for indexingcriteria for indexing

Page 44: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4444

Difficult CICS PagingDifficult CICS PagingThe Where Clause – The Where Clause –

Explained!Explained! AND CUSTOMER_LOC||AND CUSTOMER_LOC|| DIGITS(DAYS(‘9999-12-31’) – DAYS(PAID_DATE))||\DIGITS(DAYS(‘9999-12-31’) – DAYS(PAID_DATE))||\This puts together the customer_loc with the inverted paid This puts together the customer_loc with the inverted paid

datedate

CHAR(DATE('0001-01-01') + CHAR(DATE('0001-01-01') + ((DAYS(ENTRY_DATE) - ((DAYS(ENTRY_DATE) - DAYS(DATE('0001-01-01'))) * DAYS(DATE('0001-01-01'))) * :WS-SCREEN-MODE-NUM) DAYS)||:WS-SCREEN-MODE-NUM) DAYS)||

This adds in the Entry_date in ‘ALL’ Mode (‘0001-01-01’ in This adds in the Entry_date in ‘ALL’ Mode (‘0001-01-01’ in “U”)“U”)

INVOICE_NBR >= :WS-PAGING-KEYINVOICE_NBR >= :WS-PAGING-KEY and Finally tacks on the invoice numberand Finally tacks on the invoice number

Page 45: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4545

Difficult CICS PagingDifficult CICS PagingThe Where Clause – The Where Clause –

Explained!Explained! The Working Storage KeyThe Working Storage Key

01 DATABASE-KEYS01 DATABASE-KEYS05 WS-PAGING-KEY 05 WS-PAGING-KEY PIC X(34)PIC X(34)05 FILLER REDEFINES WS-PAGING-KEY05 FILLER REDEFINES WS-PAGING-KEY 10 WS-KEY-LOC10 WS-KEY-LOC PIC X(04).PIC X(04). 10 WS-KEY-PDATE 10 WS-KEY-PDATE PIC X(10).PIC X(10). 10 WS-KEY-EDATE 10 WS-KEY-EDATE PIC X(10).PIC X(10). 10 WS-KEY-INVOICE10 WS-KEY-INVOICE PIC X(10).PIC X(10).

* “A”LL MODE OR “U”NPAID MODE* “A”LL MODE OR “U”NPAID MODE05 WS-SCREEN-MODE 05 WS-SCREEN-MODE PIC X(01).PIC X(01).

* 0 IF IN “U”PAID MODE, 1 IN “A”LL MODE* 0 IF IN “U”PAID MODE, 1 IN “A”LL MODE05 WS-SCREEN-MODE-NUM 05 WS-SCREEN-MODE-NUM `̀ PIC S9(04) COMP.PIC S9(04) COMP.

Page 46: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4646

Difficult CICS PagingDifficult CICS PagingBacking upBacking up

The page up cursor is the same thing with The page up cursor is the same thing with 2 tweaks2 tweaks– Order by DESCENDINGOrder by DESCENDING– <= and < instead of >= and >=<= and < instead of >= and >=

When they page up we will use the reverse When they page up we will use the reverse cursor to find the starting point for the new cursor to find the starting point for the new page page – It will begin with the row prior to first row on It will begin with the row prior to first row on

the current page (the last row on the prior the current page (the last row on the prior page)page)

We will use this value as the key for the We will use this value as the key for the page down cursor to actually build the page down cursor to actually build the pagepage

Page 47: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4747

Difficult CICS PagingDifficult CICS PagingThe WHERE clause - The WHERE clause -

UpUp

WHERE CUSTOMER_ACCT = :WS-CUST-ACCTWHERE CUSTOMER_ACCT = :WS-CUST-ACCT AND CUSTOMER_LOC <= :WS-CUST-LOCAND CUSTOMER_LOC <= :WS-CUST-LOC AND CUSTOMER_LOC||AND CUSTOMER_LOC|| DIGITS(DAYS(‘9999-12-31’) – DIGITS(DAYS(‘9999-12-31’) –

DAYS(PAID_DATE))||DAYS(PAID_DATE))|| CHAR(DATE('0001-01-01') + CHAR(DATE('0001-01-01') + ((DAYS(ENTRY_DATE) - ((DAYS(ENTRY_DATE) - DAYS(DATE('0001-01-01'))) * DAYS(DATE('0001-01-01'))) * :WS-SCREEN-MODE-NUM) DAYS)||:WS-SCREEN-MODE-NUM) DAYS)|| INVOICE_NBR < :WS-PAGING-KEYINVOICE_NBR < :WS-PAGING-KEY AND (:WS-SCREEN-MODE = 'A' ORAND (:WS-SCREEN-MODE = 'A' OR DATE_PAID = '0001-01-01')DATE_PAID = '0001-01-01')

Page 48: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4848

Difficult CICS PagingDifficult CICS PagingBacking upBacking up

We are on page 3 We are on page 3 – We feed Page 3, line 1 values into page up cursor We feed Page 3, line 1 values into page up cursor

We saved it in Linkage when page 3 was built last We saved it in Linkage when page 3 was built last program cycle program cycle

The very first time in we used low-valuesThe very first time in we used low-values– The page up cursor finds us Page 1, line 16 valueThe page up cursor finds us Page 1, line 16 value

Remember there is not a Line 16 on the screen, this Remember there is not a Line 16 on the screen, this line is for the paging process and is saved in Linkageline is for the paging process and is saved in Linkage

– We feed that into page down cursor and build page We feed that into page down cursor and build page 22

This ensures that pages are always full and changes This ensures that pages are always full and changes to the database are reflected as they happento the database are reflected as they happen

Prevents pages with missing top linesPrevents pages with missing top lines Makes first/last pages reliableMakes first/last pages reliable

Page 49: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

4949

Difficult CICS PagingDifficult CICS PagingIn ConclusionIn Conclusion

Remember performance, make sure the Remember performance, make sure the first variable item in the compound key is first variable item in the compound key is also stated as a >= (or <=) by itselfalso stated as a >= (or <=) by itself

Only put variable items in the compound Only put variable items in the compound key, if it is always the same value (ex: key, if it is always the same value (ex: Customer_Acct) put it in as an =Customer_Acct) put it in as an =

Do an EXPLAIN!, check your performanceDo an EXPLAIN!, check your performance Check your indexes, make sure there is Check your indexes, make sure there is

an index for at least one = and also the an index for at least one = and also the first variable itemfirst variable item

Page 50: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5050

DB2 V7 and Beyond:DB2 V7 and Beyond:

Ideas to make use of Ideas to make use of UNIONUNION

Page 51: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5151

Making Use of UNIONsMaking Use of UNIONs

A UNION can be used to replace A UNION can be used to replace multiple “OR” statementsmultiple “OR” statements– Remember that “OR”s are real index Remember that “OR”s are real index

killerskillers Avoiding them where possible is importantAvoiding them where possible is important

– We talked about RIDLISTs before but We talked about RIDLISTs before but the RIDLIST can’t help every SQLthe RIDLIST can’t help every SQL

UNIONS may be able to help some of theseUNIONS may be able to help some of these

Page 52: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5252

Making Use of UNIONsMaking Use of UNIONs

Assume we have a large Customer Assume we have a large Customer TableTable– It has an index on CUST_NBRIt has an index on CUST_NBR– It is a large table 1.5 million rowsIt is a large table 1.5 million rows– We need to extract all customers with We need to extract all customers with

Current Bills and certain Past Due BillsCurrent Bills and certain Past Due Bills We only want to list a customer onceWe only want to list a customer once

Page 53: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5353

Making Use of UNIONsMaking Use of UNIONs

SELECT * FROM TBL_CUSTOMERSELECT * FROM TBL_CUSTOMER WHERE CUST_NBR INWHERE CUST_NBR IN

( SELECT CUST_NBR ( SELECT CUST_NBR FROM TBL_CURR_BILLS) FROM TBL_CURR_BILLS) OR CUST_NBR IN OR CUST_NBR IN (SELECT CUST_NBR (SELECT CUST_NBR FROM TBL_PAST_DUE FROM TBL_PAST_DUE

WHERE PAST_DUE_DAYS < 30)WHERE PAST_DUE_DAYS < 30)

– The performance of this could be hideousThe performance of this could be hideous Even assuming the TBL_CURR_BILLS and TBL_PAST_DUE are Even assuming the TBL_CURR_BILLS and TBL_PAST_DUE are

smallsmall The presence of the OR really prevents any effective The presence of the OR really prevents any effective

indexingindexing

Page 54: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5454

Making Use of UNIONsMaking Use of UNIONs

It can be rewritten as a Union:It can be rewritten as a Union: SELECT CUST_NBR FROM TBL_CUSTOMERSELECT CUST_NBR FROM TBL_CUSTOMER WHERE CUST_NBR INWHERE CUST_NBR IN

( SELECT CUST_NBR ( SELECT CUST_NBR FROM TBL_CURR_BILLS) FROM TBL_CURR_BILLS)

UNION UNION SELECT CUST_NBR FROM TBL_CUSTOMERSELECT CUST_NBR FROM TBL_CUSTOMER WHERE CUST_NBR IN WHERE CUST_NBR IN

(SELECT CUST_NBR (SELECT CUST_NBR FROM TBL_PAST_DUE FROM TBL_PAST_DUE

WHERE PAST_DUE_DAYS < 30)WHERE PAST_DUE_DAYS < 30)

Page 55: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5555

Making Use of UNIONsMaking Use of UNIONs

The UNION will run each one as a The UNION will run each one as a separate SQL and can then index separate SQL and can then index CUST_NBRCUST_NBR

Then it will SORT/SUM them into Then it will SORT/SUM them into one resultone result– UNION ALL would eliminate the UNION ALL would eliminate the

SORT/SUM but would possibly return SORT/SUM but would possibly return duplicates if the customer had both duplicates if the customer had both a current and a <30 past due billa current and a <30 past due bill

Page 56: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5656

Making Use of UNIONsMaking Use of UNIONs

Places to consider a UNIONPlaces to consider a UNION– SQL that you have to use a lot of “OR”sSQL that you have to use a lot of “OR”s– SQL where you are trying to get the same SQL where you are trying to get the same

result set from conflicting criteriaresult set from conflicting criteria– Places where RIDLIST processing is being Places where RIDLIST processing is being

invoked but is performing poorlyinvoked but is performing poorly– UNION doesn’t have to be used against UNION doesn’t have to be used against

different tables, both Selects can be the different tables, both Selects can be the same tablesame table

Page 57: DB2 V7 And Beyond"

04/10/2304/10/23 DB2 V7 and Beyond: Rick Egleston © 200DB2 V7 and Beyond: Rick Egleston © 20066

5757

DB2 V7 and Beyond:DB2 V7 and Beyond:

Questions ?Questions ?