19.06.2013 Views

DB2 UDB for z/OS Version 8 Performance Topics - IBM Redbooks

DB2 UDB for z/OS Version 8 Performance Topics - IBM Redbooks

DB2 UDB for z/OS Version 8 Performance Topics - IBM Redbooks

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

ibm.com/redbooks<br />

Front cover<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong><br />

<strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong><br />

Evaluate the per<strong>for</strong>mance impact of<br />

major new functions<br />

Find out the compatibility mode<br />

per<strong>for</strong>mance implications<br />

Understand per<strong>for</strong>mance and<br />

availability functions<br />

Paolo Bruni<br />

Doracilio Fernandes de Farias Jr<br />

Yoshio Ishii<br />

Michael Parbs<br />

Mary Petras<br />

Tsumugi Taira<br />

Jan Vandensande


International Technical Support Organization<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

April 2005<br />

SG24-6465-00


Note: Be<strong>for</strong>e using this in<strong>for</strong>mation and the product it supports, read the in<strong>for</strong>mation in “Notices” on<br />

page xix.<br />

First Edition (April 2005)<br />

This edition applies to <strong>Version</strong> 8 of <strong>IBM</strong> Database 2 Universal Database <strong>for</strong> z/<strong>OS</strong> (program number<br />

5625-<strong>DB2</strong>).<br />

© Copyright International Business Machines Corporation 2005. All rights reserved.<br />

Note to U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule<br />

Contract with <strong>IBM</strong> Corp.


Contents<br />

Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi<br />

Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xv<br />

Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii<br />

Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix<br />

Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xx<br />

Summary of changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi<br />

April 2005, First Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi<br />

April 2005, First Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi<br />

May 2005, Second Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi<br />

November 2005, Third Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii<br />

January 2006, Fourth Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii<br />

June 2006, Fifth Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii<br />

October 2006, Sixth Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii<br />

August 2007, Seventh Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii<br />

September 2007, Eighth Update. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv<br />

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxv<br />

The team that wrote this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv<br />

Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxviii<br />

Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxviii<br />

Chapter 1. <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

1.1.1 Architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

1.1.2 Usability, availability, and scalability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

1.1.3 Data warehouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

1.1.4 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

1.1.5 Migration changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

Chapter 2. Per<strong>for</strong>mance overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

2.1 Overview of major impact items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.1.1 <strong>DB2</strong> catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.1.2 CPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.1.3 I/O time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

2.1.4 Virtual storage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

2.1.5 Real storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2.1.6 Compatibility mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2.1.7 New-function mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

2.2 CPU usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

2.3 DBM1 virtual storage mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

2.3.1 <strong>DB2</strong> structures above the bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

2.3.2 What are the implications of more storage? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

2.4 Real storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

2.5 Compatibility mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

2.5.1 64-bit addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

2.5.2 No more hiperpools and data spaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. iii


2.5.3 Increased number of deferred write, castout and GBP write engines. . . . . . . . . . 20<br />

2.5.4 EDM pool changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

2.5.5 Fast log apply . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

2.5.6 Multi-row operations with DRDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

2.5.7 IRLM V2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

2.5.8 Page-fixed buffer pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

2.5.9 Unicode parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.5.10 Optimizer enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.5.11 CF request batching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.6 New-function mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

2.6.1 Plans and packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.6.2 <strong>DB2</strong> catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.6.3 Precompiler NEWFUN option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.6.4 SUBSTRING function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

2.7 New installation default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

2.8 Recent z/<strong>OS</strong> releases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

2.8.1 Multilevel security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

2.8.2 DFSMShsm Fast Replication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

Chapter 3. SQL per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

3.1 Multi-row FETCH, INSERT, cursor UPDATE and DELETE . . . . . . . . . . . . . . . . . . . . . 31<br />

3.1.1 Example of usage of multi-row fetch in PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

3.1.2 Example of usage of multi-row insert in PL/I. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

3.1.3 Multi-row fetch/update and multi-row fetch/delete in local applications . . . . . . . . 33<br />

3.1.4 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

3.1.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

3.1.6 Recommendation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

3.2 Materialized query table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

3.2.1 Creating MQTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

3.2.2 Populating MQTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

3.2.3 Controlling query rewrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

3.2.4 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

3.2.5 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52<br />

3.2.6 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

3.3 Star join processing enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

3.3.1 Star schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

3.3.2 In memory work file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />

3.3.3 Sparse index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />

3.3.4 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

3.3.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

3.3.6 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

3.4 Stage 1 and indexable predicates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

3.4.1 New indexable predicates in V7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

3.4.2 More stage 1 and indexable predicates in V8. . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

3.4.3 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

3.4.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />

3.4.5 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />

3.4.6 Considerations on CASTing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />

3.5 Multi-predicate access path enhancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />

3.5.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74<br />

3.5.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

3.5.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

3.6 Multi-column sort merge join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77<br />

iv <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


3.6.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77<br />

3.6.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

3.6.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

3.7 Parallel sort enhancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

3.7.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80<br />

3.7.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82<br />

3.7.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

3.8 Table UDF improvement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

3.8.1 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

3.8.2 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

3.8.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

3.8.4 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

3.9 ORDER BY in SELECT INTO with FETCH FIRST N ROWS . . . . . . . . . . . . . . . . . . . . 86<br />

3.10 Trigger enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

3.10.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87<br />

3.10.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

3.10.3 Recommendation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

3.11 REXX support improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

3.11.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

3.11.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

3.11.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

3.12 Dynamic scrollable cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

3.12.1 Static scrollable cursor description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

3.12.2 Dynamic scrollable cursor description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

3.12.3 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97<br />

3.12.4 Test description and study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98<br />

3.12.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106<br />

3.12.6 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106<br />

3.13 Backward index scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107<br />

3.14 Multiple distinct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

3.14.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109<br />

3.14.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

3.14.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

3.15 Visual Explain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

3.15.1 Installation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112<br />

3.15.2 Visual Explain consistency query analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112<br />

3.15.3 Statistics Advisor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116<br />

3.15.4 Visual Explain and Statistics Advisor on MQTs . . . . . . . . . . . . . . . . . . . . . . . . 123<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127<br />

4.1 <strong>DB2</strong> CPU considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

4.1.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130<br />

4.1.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136<br />

4.1.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138<br />

4.2 Virtual storage constraint relief . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139<br />

4.2.1 The <strong>DB2</strong> pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

4.2.2 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

4.2.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156<br />

4.2.4 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156<br />

4.3 Monitoring DBM1 storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157<br />

4.4 Profiles do vary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

4.5 Buffer pool long term page fixing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169<br />

4.5.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170<br />

Contents v


4.5.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

4.5.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

4.6 IRLM V2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

4.6.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172<br />

4.6.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />

4.6.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />

4.7 Unicode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174<br />

4.7.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184<br />

4.7.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

4.7.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187<br />

4.8 Data encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188<br />

4.8.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190<br />

4.8.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190<br />

4.8.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191<br />

4.9 Row level security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191<br />

4.9.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195<br />

4.9.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198<br />

4.9.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198<br />

4.10 New CI size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199<br />

4.10.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200<br />

4.10.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

4.10.3 Striping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

4.10.4 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

4.11 <strong>IBM</strong> System z9 and MIDAWs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202<br />

4.12 Instrumentation enhancements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204<br />

4.12.1 Unicode IFCIDs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205<br />

4.12.2 Statistics enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205<br />

4.12.3 Lock escalation IFCID 337 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207<br />

4.12.4 Accounting enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208<br />

4.12.5 SQLCODE -905 new IFCID 173 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209<br />

4.12.6 Per<strong>for</strong>mance trace enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210<br />

4.12.7 Miscellaneous trace enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212<br />

4.13 Miscellaneous items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212<br />

4.13.1 <strong>DB2</strong> logging enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212<br />

4.13.2 Up to 65,041 open data sets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213<br />

4.13.3 SMF type 89 record collection enhancements . . . . . . . . . . . . . . . . . . . . . . . . . 213<br />

4.13.4 Lock avoidance enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214<br />

Chapter 5. Availability and capacity enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . 217<br />

5.1 System level point-in-time recovery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218<br />

5.1.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221<br />

5.1.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226<br />

5.1.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226<br />

5.2 Automated space management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226<br />

5.2.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229<br />

5.2.2 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229<br />

5.3 Online schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230<br />

5.3.1 Changing attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230<br />

5.3.2 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233<br />

5.4 Volatile table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246<br />

5.4.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246<br />

5.4.2 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246<br />

5.5 Index enhancements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246<br />

vi <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


5.5.1 Partitioned table space without index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247<br />

5.5.2 Clustering index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247<br />

5.5.3 Clustering index always . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247<br />

5.5.4 DPSI and impact on utilities and queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248<br />

5.6 Other availability enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256<br />

5.6.1 More online DSNZPARMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256<br />

5.6.2 Monitor long running UR back out. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256<br />

5.6.3 Monitor system checkpoints and log offload activity . . . . . . . . . . . . . . . . . . . . . . 256<br />

5.6.4 Improved LPL recovery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257<br />

5.6.5 Partitioning key update enhancement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257<br />

5.6.6 Lock holder can inherit WLM priority from lock waiter. . . . . . . . . . . . . . . . . . . . . 258<br />

5.6.7 Detecting long readers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258<br />

5.6.8 Explain a stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258<br />

5.6.9 PLAN_TABLE access via a <strong>DB2</strong> alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259<br />

5.6.10 Support <strong>for</strong> more than 245 secondary AUTHIDs . . . . . . . . . . . . . . . . . . . . . . . 260<br />

Chapter 6. Utilities. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261<br />

6.1 Online CHECK INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262<br />

6.1.1 Per<strong>for</strong>mance measurement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264<br />

6.1.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267<br />

6.1.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267<br />

6.2 LOAD and REORG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268<br />

6.2.1 LOAD with default per<strong>for</strong>mance measurement. . . . . . . . . . . . . . . . . . . . . . . . . . 268<br />

6.2.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269<br />

6.2.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269<br />

6.3 LOAD and UNLOAD delimited input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270<br />

6.3.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271<br />

6.3.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272<br />

6.4 RUNSTATS enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272<br />

6.4.1 General per<strong>for</strong>mance improvements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272<br />

6.4.2 DSTATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273<br />

6.4.3 Description of distribution statistics in V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273<br />

6.4.4 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275<br />

6.4.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280<br />

6.4.6 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280<br />

6.5 Cross Loader. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280<br />

6.5.1 Per<strong>for</strong>mance APAR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280<br />

Chapter 7. Networking and e-business . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281<br />

7.1 DDF enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283<br />

7.1.1 Requester database alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283<br />

7.1.2 Server location alias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283<br />

7.1.3 Member routing in a TCP/IP Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283<br />

7.1.4 DRDA allows larger query blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284<br />

7.1.5 <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285<br />

7.2 Multi-row FETCH and INSERT in DRDA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285<br />

7.2.1 Per<strong>for</strong>mance - Distributed host to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286<br />

7.2.2 Per<strong>for</strong>mance - Distributed client to Host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290<br />

7.3 WebSphere and the <strong>DB2</strong> Universal Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292<br />

7.3.1 Per<strong>for</strong>mance measurement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293<br />

7.3.2 <strong>DB2</strong> Universal Driver X/Open XA support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303<br />

7.3.3 Miscellaneous items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304<br />

7.4 ODBC enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306<br />

Contents vii


7.4.1 ODBC Unicode support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306<br />

7.4.2 ODBC long name support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306<br />

7.4.3 ODBC connection authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306<br />

7.4.4 ODBC support <strong>for</strong> 2 MB SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307<br />

7.4.5 SQLcancel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307<br />

7.5 XML support in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307<br />

7.5.1 XML extender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307<br />

7.5.2 XML publishing functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308<br />

7.5.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312<br />

7.5.4 Recommendation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312<br />

7.6 Enterprise Workload Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312<br />

7.6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312<br />

7.6.2 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313<br />

7.6.3 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316<br />

Chapter 8. Data sharing enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319<br />

8.1 CF request batching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321<br />

8.1.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321<br />

8.1.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325<br />

8.1.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325<br />

8.2 Locking protocol level 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325<br />

8.2.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328<br />

8.2.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331<br />

8.2.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331<br />

8.3 Change to IMMEDWRITE default BIND option. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332<br />

8.3.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332<br />

8.3.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333<br />

8.3.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333<br />

8.4 <strong>DB2</strong> I/O CI limit removed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333<br />

8.4.1 Per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333<br />

8.4.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335<br />

8.4.3 Recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335<br />

8.5 Miscellaneous items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336<br />

8.5.1 Impact on coupling facility. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336<br />

8.5.2 Improved LPL recovery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336<br />

8.5.3 Restart Light enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337<br />

8.5.4 Change to close processing <strong>for</strong> pseudo close . . . . . . . . . . . . . . . . . . . . . . . . . . 338<br />

8.5.5 Buffer pool long term page fixing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339<br />

8.5.6 Batched index page splits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339<br />

Chapter 9. Installation and migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341<br />

9.1 Unicode catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342<br />

9.1.1 Character conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342<br />

9.1.2 Unicode parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342<br />

9.1.3 <strong>DB2</strong> catalog changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344<br />

9.2 IVP sample programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346<br />

9.3 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350<br />

9.4 Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353<br />

9.4.1 Migration plan recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354<br />

9.4.2 Per<strong>for</strong>mance measurements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355<br />

9.5 Catalog consistency query DSNTESQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359<br />

Chapter 10. Per<strong>for</strong>mance tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363<br />

10.1 <strong>DB2</strong> Estimator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364<br />

viii <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


10.2 <strong>DB2</strong> Per<strong>for</strong>mance Expert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364<br />

10.3 Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366<br />

10.4 Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on z/<strong>OS</strong> . . . . . . . . . . . . . . . . . 367<br />

10.5 <strong>DB2</strong> Archive Log Accelerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367<br />

10.6 <strong>DB2</strong> Query Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368<br />

10.7 <strong>DB2</strong> SQL Per<strong>for</strong>mance Analyzer <strong>for</strong> z/<strong>OS</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369<br />

10.8 Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369<br />

10.9 <strong>DB2</strong> Data Archive Expert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370<br />

10.10 <strong>DB2</strong> Bind Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370<br />

10.11 <strong>DB2</strong> High Per<strong>for</strong>mance Unload. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370<br />

10.11.1 Per<strong>for</strong>mance measurements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance . . . . . . . . . . . . . . . . . . . . . . . . . 377<br />

A.1 Maintenance <strong>for</strong> <strong>DB2</strong> V8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378<br />

A.2 Maintenance <strong>for</strong> <strong>DB2</strong> V7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386<br />

A.3 Maintenance <strong>for</strong> z/<strong>OS</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390<br />

Appendix B. The DBM1 storage map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393<br />

B.1 <strong>DB2</strong> PE Storage Statistics trace and report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394<br />

Appendix C. SQL PA sample reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399<br />

C.1 <strong>DB2</strong> SQL PA additional reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400<br />

Appendix D. EXPLAIN and its tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407<br />

D.1 <strong>DB2</strong> EXPLAIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408<br />

D.1.1 DSN_PLAN_TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409<br />

D.1.2 DSN_STATEMNT_TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415<br />

D.1.3 DSN_FUNCTION_TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416<br />

D.1.4 DSN_STATEMNT_CACHE_TABLE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417<br />

Abbreviations and acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423<br />

Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425<br />

<strong>IBM</strong> <strong>Redbooks</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425<br />

Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426<br />

Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426<br />

How to get <strong>IBM</strong> <strong>Redbooks</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427<br />

Help from <strong>IBM</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427<br />

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429<br />

Contents ix


x <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figures<br />

2-1 Virtual storage growth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

3-1 Multi-row fetch reduces the trips across the API . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

3-2 Usage of multi-row fetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

3-3 Example of multi-row cursor update and delete. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34<br />

3-4 CPU time (class 1) <strong>for</strong> single-row and multi-row fetch . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

3-5 CPU time (class 1) <strong>for</strong> single-row and multi-row insert . . . . . . . . . . . . . . . . . . . . . . . 36<br />

3-6 Relationship between two special registers <strong>for</strong> MQTs. . . . . . . . . . . . . . . . . . . . . . . . 42<br />

3-7 Rules <strong>for</strong> query rewrite. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

3-8 Query rewrite example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44<br />

3-9 MQTs and short running queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

3-10 Increase of BIND cost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

3-11 Query rewrite <strong>for</strong> simple query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48<br />

3-12 Query rewrite <strong>for</strong> join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49<br />

3-13 Regrouping on MQT result. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

3-14 Expression® derivation example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />

3-15 Star schema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54<br />

3-16 In memory work file - Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />

3-17 Star join access path (be<strong>for</strong>e PQ61458) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58<br />

3-18 Sparse index on work file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

3-19 Sparse index <strong>for</strong> star join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

3-20 Sparse index per<strong>for</strong>mance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

3-21 Star join access path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

3-22 In memory work file - CPU reduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63<br />

3-23 Star join workload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64<br />

3-24 Analysis of Stage 1 and Stage 2 predicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66<br />

3-25 Example of mismatched numeric types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

3-26 Example of mismatched string types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68<br />

3-27 Mismatched numeric data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

3-28 Different lengths <strong>for</strong> string data type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70<br />

3-29 Access path graph in Visual Explain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73<br />

3-30 Better filter factor estimation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />

3-31 Access path improvements - Multi-column statistics . . . . . . . . . . . . . . . . . . . . . . . . . 76<br />

3-32 Mismatched data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78<br />

3-33 Query parallelism in V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

3-34 EXPLAIN example - Parallel sort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80<br />

3-35 Multiple table group by sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81<br />

3-36 Multiple table order by sort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82<br />

3-37 Table UDF - Cardinality option. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85<br />

3-38 Table UDF - Block fetch support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85<br />

3-39 SQL and BPOOL activity - Trigger 100 times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88<br />

3-40 CPU time when invoking the trigger 100 times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88<br />

3-41 SQL and BPOOL activity - Trigger with WHEN true only once . . . . . . . . . . . . . . . . . 89<br />

3-42 CPU time to invoke trigger but WHEN condition true once . . . . . . . . . . . . . . . . . . . . 90<br />

3-43 REXX support improvement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91<br />

3-44 DECLARE CURSOR syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

3-45 FETCH syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96<br />

3-46 Multiple DISTINCT per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

3-47 Explain of the old consistency query 31. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xi


3-48 Consistency query - 31 New . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116<br />

3-49 Starting to analyze a sample query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117<br />

3-50 Suggested RUNSTATS statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118<br />

3-51 Reason <strong>for</strong> RUNSTATS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118<br />

3-52 Saved queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119<br />

3-53 New suggested RUNSTATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119<br />

3-54 Statistical output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120<br />

3-55 Recollection of inconsistent statistics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

3-56 Conflicting statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

3-57 Statistics Advisor Plug-integrated with Visual Explain . . . . . . . . . . . . . . . . . . . . . . . 122<br />

3-58 Predefined default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122<br />

3-59 Conflict statistics threshold setup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123<br />

3-60 Explain without using an MQT table by Visual Explain . . . . . . . . . . . . . . . . . . . . . . 124<br />

3-61 Explain using an MQT table by Visual Explain . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125<br />

4-1 CPU workload summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131<br />

4-2 V7 vs. V8 Utility CPU measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132<br />

4-3 DBM1 virtual storage constraint relief (no data spaces nor hiper pools) . . . . . . . . . 140<br />

4-4 DBM1 below 2 GB virtual storage comparison <strong>for</strong> different workloads . . . . . . . . . . 149<br />

4-5 DBM1 user thread storage comparison <strong>DB2</strong> V7 vs. V8. . . . . . . . . . . . . . . . . . . . . . 152<br />

4-6 Real storage comparison <strong>DB2</strong> V7 vs. V8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155<br />

4-7 MVS storage overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161<br />

4-8 Sample RMF Monitor III STORF Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

4-9 DBM1 storage by time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167<br />

4-10 Thread-related storage by time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168<br />

4-11 Storage per thread by time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169<br />

4-12 CCSID conversion - Local application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176<br />

4-13 CCSID conversion - Remote application - 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177<br />

4-14 CCSID conversion - Remote application - 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178<br />

4-15 CCSID conversion - Local z/<strong>OS</strong> Universal Java Type 2 Driver . . . . . . . . . . . . . . . . 180<br />

4-16 CCSID conversion - Remote Prepare using Java Universal Type 4 Driver. . . . . . . 181<br />

4-17 CCSID conversion - Remote Prepare of SQL statement. . . . . . . . . . . . . . . . . . . . . 182<br />

4-18 CCSID conversion - Local Prepare using Universal Java Type 2 Driver . . . . . . . . . 182<br />

4-19 Conversion per<strong>for</strong>mance overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184<br />

4-20 Larger CI size impact on <strong>DB2</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201<br />

4-21 <strong>IBM</strong> System z9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203<br />

4-22 Table space scan with MIDAWs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204<br />

5-1 FRBACKUP PREPARE elapsed time vs. #volumes in the copy pool . . . . . . . . . . . 222<br />

5-2 FRBACKUP PREPARE elapsed time vs.#versions <strong>for</strong> 67 volume copy pool . . . . . 222<br />

5-3 BACKUP SYSTEM DATA ONLY measurement . . . . . . . . . . . . . . . . . . . . . . . . . . . 223<br />

5-4 BACKUP SYSTEM FULL measurement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224<br />

5-5 RESTORE SYSTEM measurement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225<br />

5-6 Sliding scale <strong>for</strong> 64 GB data sets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227<br />

5-7 Sliding scale <strong>for</strong> 16 GB data set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228<br />

5-8 CPU time be<strong>for</strong>e ALTER, after ALTER and after REORG. . . . . . . . . . . . . . . . . . . . 234<br />

5-9 INSERT CPU time be<strong>for</strong>e ALTER, after ALTER and after REORG . . . . . . . . . . . . 235<br />

5-10 SELECT elapsed and CPU time be<strong>for</strong>e and after ALTER INDEX add column . . . . 236<br />

5-11 FETCH CPU time - Alter index padded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237<br />

5-12 FETCH CPU time - Alter index not padded and rebind . . . . . . . . . . . . . . . . . . . . . . 238<br />

5-13 Query CPU overhead using NOT PADDED vs. PADDED index . . . . . . . . . . . . . . . 239<br />

5-14 Average index leaf pages and index getpages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240<br />

5-15 NOT PADDED index impact on utilities - Index VARCHAR(14) . . . . . . . . . . . . . . . 241<br />

5-16 NOT PADDED index impact on utilities - Index VARCHAR(1) . . . . . . . . . . . . . . . . 241<br />

5-17 NOT PADDED index impact on utilities - Index 4 columns VARCHAR(1). . . . . . . . 242<br />

xii <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


5-18 Rotate partition - Elapsed time comparison. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243<br />

5-19 Partition distribution be<strong>for</strong>e and after REORG REBALANCE . . . . . . . . . . . . . . . . . 244<br />

5-20 REORG REBALANCE elapsed time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245<br />

5-21 Load with 1 NPI vs. 1 DPSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249<br />

5-22 Load with 5 NPIs vs. 5 DPSIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250<br />

5-23 REORG with 1 NPI vs. 1 DPSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250<br />

5-24 REORG with 5 NPIs vs. 5 DPSIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251<br />

5-25 Rebuild index partition of PI, NPI and DPSI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252<br />

5-26 Rebuild index PI, NPI, and DPSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252<br />

5-27 Check index PI, NPI and DPSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253<br />

5-28 Runstats index PI, NPI and DPSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253<br />

6-1 CHECK INDEX SHRLEVEL REFERENCE and SHRLEVEL CHANGE . . . . . . . . . 262<br />

6-2 SHRLEVEL CHANGE vs. SHRLEVEL REFERENCE with FlashCopy . . . . . . . . . . 266<br />

6-3 SHRLEVEL CHANGE vs. SHRLEVEL REFERENCE w/o FlashCopy . . . . . . . . . . 267<br />

6-4 LOAD with default SORTKEYS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269<br />

6-5 Distribution statistics per<strong>for</strong>mance comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277<br />

7-1 Multi-row FETCH distributed <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8 . . . . . . . . . . . . . . . . . . . . . . . . . . 286<br />

7-2 Multi-row FETCH - Distributed host to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287<br />

7-3 Multi-row INSERT - Distributed host to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289<br />

7-4 Multi-row fetch - <strong>DB2</strong> client to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290<br />

7-5 Multi-row insert - <strong>DB2</strong> client to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291<br />

7-6 <strong>DB2</strong> Universal Type 2 Driver vs. legacy JDBC 2.0 Driver . . . . . . . . . . . . . . . . . . . . 294<br />

7-7 <strong>DB2</strong> Universal Type 2 Driver - Gateway <strong>DB2</strong> vs. <strong>DB2</strong> Universal Type 4 Driver . . . 295<br />

7-8 <strong>DB2</strong> Universal Type 2 Driver vs. <strong>DB2</strong> Universal Type 4 Driver . . . . . . . . . . . . . . . . 296<br />

7-9 JDK improvements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297<br />

7-10 JDBC .app/<strong>DB2</strong> Connect vs. JCC Type 4 - CMP workload. . . . . . . . . . . . . . . . . . . 297<br />

7-11 <strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - CMP workload. . . . . . . . . . . . . . . 298<br />

7-12 <strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - Servlet workload . . . . . . . . . . . . . 298<br />

7-13 JCC Type 4 vs. JCC Type 4 with <strong>DB2</strong> Connect. . . . . . . . . . . . . . . . . . . . . . . . . . . . 299<br />

7-14 JCC T4 configuration <strong>for</strong> balancing options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300<br />

7-15 JCC T2 and <strong>DB2</strong> Connect configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301<br />

7-16 Per<strong>for</strong>mance of JCC T4 vs. <strong>DB2</strong> Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302<br />

7-17 Servlet workload - Type 2 non-XA vs. Type 2 XA compliant driver . . . . . . . . . . . . . 303<br />

7-18 <strong>DB2</strong> Universal Driver - KEEPDYNAMIC YES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305<br />

7-19 XML extender decomposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308<br />

7-20 XML extender vs. SQL publishing functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311<br />

7-21 Composition by XML publishing functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311<br />

7-22 EWLM support with WAS/AIX and <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 . . . . . . . . . . . . . . . . . . . . . . . . 313<br />

7-23 Enterprise Workload Manager Control Center - Managed servers . . . . . . . . . . . . . 314<br />

7-24 Enterprise Workload Manager Control Center - Server topology . . . . . . . . . . . . . . 315<br />

7-25 EWLM control center - Service class statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315<br />

7-26 EWLM implementation cost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316<br />

9-1 Unicode conversion example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343<br />

9-2 Multi-row fetch support of DSNTEP4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347<br />

9-3 Multi-row fetch support of DSNTEP4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348<br />

9-4 Multi-row fetch support of DSNTIAUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349<br />

9-5 Multi-row support of DSNTIAUL comparing V7 with V8. . . . . . . . . . . . . . . . . . . . . . 350<br />

9-6 Migration times to CM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357<br />

9-7 Migration from CM to NFM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358<br />

9-8 Catalog consistency queries - Measurement results . . . . . . . . . . . . . . . . . . . . . . . . 361<br />

9-9 Catalog consistency queries - Measurement results . . . . . . . . . . . . . . . . . . . . . . . . 362<br />

10-1 <strong>DB2</strong> HPU vs. UNLOAD utility Case 1 through Case 5. . . . . . . . . . . . . . . . . . . . . . . 374<br />

10-2 <strong>DB2</strong> HPU vs. UNLOAD utility Case 6 through Parallel . . . . . . . . . . . . . . . . . . . . . . 374<br />

Figures xiii


xiv <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Tables<br />

2-1 Changed DSNZPARM default settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

2-2 z/<strong>OS</strong> release functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26<br />

3-1 Class 1 CPU time (sec.) to process 100,000 rows . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

3-2 Measurements <strong>for</strong> mismatched numeric data types . . . . . . . . . . . . . . . . . . . . . . . . . 70<br />

3-3 Static cursor declare and fetch specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

3-4 Read cursor - Static vs. dynamic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

3-5 Update cursor static vs. dynamic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101<br />

3-6 Multi-row FETCH static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104<br />

3-7 Multi-row FETCH dynamic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104<br />

3-8 Multi-row FETCH and UPDATE or DELETE static . . . . . . . . . . . . . . . . . . . . . . . . . 105<br />

3-9 Multi-row FETCH and UPDATE or DELETE dynamic . . . . . . . . . . . . . . . . . . . . . . . 106<br />

3-10 Access type and sort with backward index scan . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

3-11 Old consistency query 31. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113<br />

3-12 Consistency Query 31 New . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115<br />

3-13 Query using MQT table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123<br />

4-1 CM vs. NFM - Non-data sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133<br />

4-2 CM vs. NFM - Data sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134<br />

4-3 Accounting class 2 CPU time increase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

4-4 System storage configuration <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8 . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

4-5 Non-distributed DBM1 virtual storage comparison . . . . . . . . . . . . . . . . . . . . . . . . . 149<br />

4-6 Virtual storage comparison <strong>for</strong> CLI, JDBC, embedded SQL, and SQLJ workloads. 150<br />

4-7 <strong>DB2</strong> storage messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

4-8 Real storage comparison <strong>for</strong> CLI, JDBC, embedded SQL, and SQLJ workloads . . 154<br />

4-9 Long term page fix - non-data sharing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170<br />

4-10 Long term page fix - data sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170<br />

4-11 IRLM CPU - V2.1 vs. V2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />

4-12 <strong>DB2</strong> V7 - Sizes in KB (usable track size 48 KB <strong>for</strong> 3390) . . . . . . . . . . . . . . . . . . . . 199<br />

4-13 <strong>DB2</strong> V8 - Sizes in KB (usable track size 48 KB <strong>for</strong> 3390) . . . . . . . . . . . . . . . . . . . . 200<br />

4-14 I/O service time on ESS 800 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201<br />

4-15 Lock avoidance of overflow record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214<br />

5-1 Concurrent execution of BACKUP SYSTEM and IRWW workload . . . . . . . . . . . . . 224<br />

5-2 LOGAPPLY phase measurement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225<br />

5-3 NPI vs. DPSI SELECT COUNT query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254<br />

5-4 NPI vs. DPSI SELECT COUNT query parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . 254<br />

5-5 DPSI overhead. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255<br />

5-6 DPSI access path change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255<br />

6-1 Delimited Load and Unload CPU comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272<br />

6-2 Summary of RUNSTATS improvements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272<br />

6-3 RUNSTATS with DSTATS measurement data in V7. . . . . . . . . . . . . . . . . . . . . . . . 278<br />

6-4 RUNSTATS with DSTATS measurement data in V8. . . . . . . . . . . . . . . . . . . . . . . . 279<br />

7-1 <strong>DB2</strong> connect evaluation <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285<br />

7-2 <strong>DB2</strong> V8 with implicit multi-row FETCH vs. V7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288<br />

7-3 <strong>DB2</strong> V8 with explicit multi-row FETCH vs. V7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288<br />

7-4 Comparing the key points of the two solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302<br />

8-1 CF Request Batching - <strong>DB2</strong> PE extract (OLTP) . . . . . . . . . . . . . . . . . . . . . . . . . . . 322<br />

8-2 CF Request Batching - RMF extract (OLTP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322<br />

8-3 CF Request Batching - <strong>DB2</strong> PE extract (batch). . . . . . . . . . . . . . . . . . . . . . . . . . . . 323<br />

8-4 CF Request Batching - RMF extract (batch) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xv


8-5 CF Request Batching - <strong>DB2</strong> CPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324<br />

8-6 Protocol Level 2 - Statistics Report extract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328<br />

8-7 Protocol Level 2 - Accounting Report extract. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328<br />

8-8 Protocol Level 2 - RMF XCF Report extract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328<br />

8-9 Protocol Level 2 - RMF CF Activity Report extract . . . . . . . . . . . . . . . . . . . . . . . . . 329<br />

8-10 Protocol Level 2 - <strong>DB2</strong> PE Statistics Report extract . . . . . . . . . . . . . . . . . . . . . . . . 330<br />

8-11 Protocol Level 2 - RELEASE(DEALLOCATE) vs. RELEASE(COMMIT) . . . . . . . . . 330<br />

8-12 <strong>DB2</strong> I/O CI Limit Removal - Non-data sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334<br />

8-13 <strong>DB2</strong> I/O CI limit removal - Data sharing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334<br />

8-14 <strong>DB2</strong> I/O CI limit removal - Non-data sharing CPU . . . . . . . . . . . . . . . . . . . . . . . . . . 334<br />

8-15 <strong>DB2</strong> I/O CI limit removal - Data sharing CPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335<br />

9-1 <strong>DB2</strong> catalog growth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344<br />

9-2 Clist changes in the installation panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351<br />

9-3 Row counts <strong>for</strong> catalog tables - 698 MB catalog in V7 . . . . . . . . . . . . . . . . . . . . . . 355<br />

9-4 CATMAINT statistics in non-data sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356<br />

9-5 Queries 5 and 18 rewritten <strong>for</strong> better per<strong>for</strong>mance . . . . . . . . . . . . . . . . . . . . . . . . . 359<br />

9-6 Catalog consistency - Query 31. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360<br />

9-7 Catalog consistency - Query 33. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361<br />

9-8 Catalog consistency - Queries 35 and 36 from SDSNSAMP. . . . . . . . . . . . . . . . . . 361<br />

10-1 RECOVER and Archive Log Accelerator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368<br />

10-2 <strong>DB2</strong> HPU vs. UNLOAD utility. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371<br />

10-3 HPU output <strong>for</strong>mats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371<br />

10-4 Unload test cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372<br />

10-5 HPU V2.2 vs. <strong>DB2</strong> V8 UNLOAD utility. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372<br />

10-6 HPU V2.2 vs. <strong>DB2</strong> V8 DSNTIAUL (no multi-row) . . . . . . . . . . . . . . . . . . . . . . . . . . 375<br />

10-7 HPU V2.2 vs. <strong>DB2</strong> V8 DSNTIAUL (multi-row) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376<br />

A-1 <strong>DB2</strong> V8 per<strong>for</strong>mance-related APARs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378<br />

A-2 <strong>DB2</strong> V7 per<strong>for</strong>mance-related APARs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386<br />

A-3 z/<strong>OS</strong> <strong>DB2</strong> per<strong>for</strong>mance-related APARs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390<br />

B-1 DBM1 AND MVS STORAGE BELOW 2 GB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394<br />

B-2 DBM1 STORAGE ABOVE 2 GB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396<br />

B-3 REAL AND AUXILIARY STORAGE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397<br />

D-1 PLAN_TABLE columns by release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409<br />

D-2 PLAN_TABLE contents and brief history. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410<br />

D-3 EXPLAIN enhancements in DSN_STATEMNT_TABLE . . . . . . . . . . . . . . . . . . . . . 415<br />

D-4 DSN_FUNCTION_TABLE extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416<br />

D-5 Contents of DSN_STATEMNT_CACHE_TABLE. . . . . . . . . . . . . . . . . . . . . . . . . . . 419<br />

xvi <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Examples<br />

3-1 Insert 10 rows using host variable arrays <strong>for</strong> column values . . . . . . . . . . . . . . . . . . . 32<br />

3-2 COBOL array declaration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38<br />

3-3 Define a table as MQT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

3-4 Alter a table to MQT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

3-5 Explain <strong>for</strong> Q662 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50<br />

3-6 SQL text <strong>for</strong> Visual Explain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

3-7 RUNSTATS statement provided by the Statistics Advisor. . . . . . . . . . . . . . . . . . . . . 73<br />

3-8 Multiple table GROUP BY sort query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81<br />

3-9 Multiple table ORDER BY sort query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82<br />

3-10 User-defined table function (1/3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

3-11 User-defined table function (2/3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

3-12 User-defined table function (3/3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84<br />

3-13 Sample row trigger creation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86<br />

3-14 Read program of static cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98<br />

3-15 Read program of dynamic cursor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

3-16 Update program of static cursor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100<br />

3-17 Update program of dynamic cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101<br />

3-18 Multi-row FETCH program of a static scrollable cursor . . . . . . . . . . . . . . . . . . . . . . 103<br />

3-19 Multi-row FETCH program of a dynamic scrollable cursor . . . . . . . . . . . . . . . . . . . 103<br />

3-20 Multi-row FETCH program of a static scrollable cursor . . . . . . . . . . . . . . . . . . . . . . 104<br />

3-21 Multi-row FETCH program of a dynamic scrollable cursor . . . . . . . . . . . . . . . . . . . 105<br />

4-1 DBM1 Storage Statistics <strong>for</strong> a <strong>DB2</strong> V7 subsystem . . . . . . . . . . . . . . . . . . . . . . . . . 158<br />

4-2 DBM1 Storage Statistics <strong>for</strong> a <strong>DB2</strong> <strong>Version</strong> 8 subsystem . . . . . . . . . . . . . . . . . . . . 163<br />

4-3 DBM1 storage usage summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165<br />

4-4 <strong>DB2</strong> PE enhanced subsystem services reporting . . . . . . . . . . . . . . . . . . . . . . . . . . 205<br />

4-5 Enhances deadlock trace record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206<br />

4-6 DSNI031I - Lock escalation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208<br />

4-7 IFCID 173 DSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210<br />

6-1 Sample JCL of CHECK INDEX SHRLEVEL CHANGE . . . . . . . . . . . . . . . . . . . . . . 263<br />

6-2 Sample LOAD statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270<br />

6-3 LOAD DATA text <strong>for</strong>mat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271<br />

6-4 LOAD DATA binary <strong>for</strong>mat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271<br />

6-5 UNLOAD DATA in EBCDIC <strong>for</strong>mat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271<br />

6-6 UNLOAD DATA in ASCII <strong>for</strong>mat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271<br />

6-7 RUNSTATS statement in V7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276<br />

6-8 DSTATS tool in V7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276<br />

6-9 RUNSTATS with distribution statistics in V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276<br />

7-1 XML publishing example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309<br />

8-1 Sample -DISPLAY GROUP output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327<br />

9-1 DSNTIAUL with multi-row parameter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349<br />

C-1 SQL PA query description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400<br />

C-2 SQL PA index in<strong>for</strong>mation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400<br />

C-3 SQL PA query analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402<br />

C-4 SQL PA predicate analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405<br />

D-1 Creating DSN_STATEMENT_CACHE_TABLE. . . . . . . . . . . . . . . . . . . . . . . . . . . . 418<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xvii


xviii <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Notices<br />

This in<strong>for</strong>mation was developed <strong>for</strong> products and services offered in the U.S.A.<br />

<strong>IBM</strong> may not offer the products, services, or features discussed in this document in other countries. Consult<br />

your local <strong>IBM</strong> representative <strong>for</strong> in<strong>for</strong>mation on the products and services currently available in your area. Any<br />

reference to an <strong>IBM</strong> product, program, or service is not intended to state or imply that only that <strong>IBM</strong> product,<br />

program, or service may be used. Any functionally equivalent product, program, or service that does not<br />

infringe any <strong>IBM</strong> intellectual property right may be used instead. However, it is the user's responsibility to<br />

evaluate and verify the operation of any non-<strong>IBM</strong> product, program, or service.<br />

<strong>IBM</strong> may have patents or pending patent applications covering subject matter described in this document. The<br />

furnishing of this document does not give you any license to these patents. You can send license inquiries, in<br />

writing, to:<br />

<strong>IBM</strong> Director of Licensing, <strong>IBM</strong> Corporation, North Castle Drive Armonk, NY 10504-1785 U.S.A.<br />

The following paragraph does not apply to the United Kingdom or any other country where such provisions are<br />

inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS<br />

PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,<br />

INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,<br />

MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURP<strong>OS</strong>E. Some states do not allow disclaimer of<br />

express or implied warranties in certain transactions, there<strong>for</strong>e, this statement may not apply to you.<br />

This in<strong>for</strong>mation could include technical inaccuracies or typographical errors. Changes are periodically made<br />

to the in<strong>for</strong>mation herein; these changes will be incorporated in new editions of the publication. <strong>IBM</strong> may make<br />

improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time<br />

without notice.<br />

Any references in this in<strong>for</strong>mation to non-<strong>IBM</strong> Web sites are provided <strong>for</strong> convenience only and do not in any<br />

manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the<br />

materials <strong>for</strong> this <strong>IBM</strong> product and use of those Web sites is at your own risk.<br />

<strong>IBM</strong> may use or distribute any of the in<strong>for</strong>mation you supply in any way it believes appropriate without incurring<br />

any obligation to you.<br />

In<strong>for</strong>mation concerning non-<strong>IBM</strong> products was obtained from the suppliers of those products, their published<br />

announcements or other publicly available sources. <strong>IBM</strong> has not tested those products and cannot confirm the<br />

accuracy of per<strong>for</strong>mance, compatibility or any other claims related to non-<strong>IBM</strong> products. Questions on the<br />

capabilities of non-<strong>IBM</strong> products should be addressed to the suppliers of those products.<br />

This in<strong>for</strong>mation contains examples of data and reports used in daily business operations. To illustrate them<br />

as completely as possible, the examples include the names of individuals, companies, brands, and products.<br />

All of these names are fictitious and any similarity to the names and addresses used by an actual business<br />

enterprise is entirely coincidental.<br />

COPYRIGHT LICENSE:<br />

This in<strong>for</strong>mation contains sample application programs in source language, which illustrates programming<br />

techniques on various operating plat<strong>for</strong>ms. You may copy, modify, and distribute these sample programs in<br />

any <strong>for</strong>m without payment to <strong>IBM</strong>, <strong>for</strong> the purposes of developing, using, marketing or distributing application<br />

programs con<strong>for</strong>ming to the application programming interface <strong>for</strong> the operating plat<strong>for</strong>m <strong>for</strong> which the sample<br />

programs are written. These examples have not been thoroughly tested under all conditions. <strong>IBM</strong>, there<strong>for</strong>e,<br />

cannot guarantee or imply reliability, serviceability, or function of these programs. You may copy, modify, and<br />

distribute these sample programs in any <strong>for</strong>m without payment to <strong>IBM</strong> <strong>for</strong> the purposes of developing, using,<br />

marketing, or distributing application programs con<strong>for</strong>ming to <strong>IBM</strong>'s application programming interfaces.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xix


Trademarks<br />

The following terms are trademarks of the International Business Machines Corporation in the United States,<br />

other countries, or both:<br />

<strong>Redbooks</strong> (logo) ®<br />

<strong>Redbooks</strong> (logo)<br />

eServer<br />

z/Architecture®<br />

z/<strong>OS</strong>®<br />

zSeries®<br />

z9<br />

AIX®<br />

CICS®<br />

<strong>DB2</strong> Connect<br />

<strong>DB2</strong> Universal Database<br />

<strong>DB2</strong>®<br />

DFSMS<br />

DFSMSdss<br />

DFSMShsm<br />

DFSORT<br />

DRDA®<br />

xx <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

DS8000<br />

Enterprise Storage Server®<br />

Enterprise Workload Manager<br />

FlashCopy®<br />

Footprint®<br />

FICON®<br />

Geographically Dispersed Parallel<br />

Sysplex<br />

GDPS®<br />

<strong>IBM</strong>®<br />

IMS<br />

MQSeries®<br />

MVS<br />

MVS/ESA<br />

MVS/XA<br />

OMEGAMON®<br />

<strong>OS</strong>/390®<br />

The following terms are trademarks of other companies:<br />

Parallel Sysplex®<br />

QMF<br />

<strong>Redbooks</strong>®<br />

RACF®<br />

RAMAC®<br />

RETAIN®<br />

REXX<br />

RMF<br />

S/360<br />

S/390®<br />

System z<br />

System z9<br />

System/390®<br />

Tivoli®<br />

TotalStorage®<br />

WebSphere®<br />

SAP R/3, SAP, and SAP logos are trademarks or registered trademarks of SAP AG in Germany and in several<br />

other countries.<br />

Oracle, JD Edwards, PeopleSoft, Siebel, and TopLink are registered trademarks of Oracle Corporation and/or<br />

its affiliates.<br />

Java, Java Naming and Directory Interface, JDBC, JDK, JVM, and all Java-based trademarks are trademarks<br />

of Sun Microsystems, Inc. in the United States, other countries, or both.<br />

Expression, Windows NT, Windows, and the Windows logo are trademarks of Microsoft Corporation in the<br />

United States, other countries, or both.<br />

UNIX is a registered trademark of The Open Group in the United States and other countries.<br />

Linux is a trademark of Linus Torvalds in the United States, other countries, or both.<br />

Other company, product, and service names may be trademarks or service marks of others.


Summary of changes<br />

This section describes the technical changes made in this update of the book. This update<br />

may also include minor corrections and editorial changes that are not identified.<br />

Summary of changes<br />

<strong>for</strong> SG24-6465-00<br />

<strong>for</strong> <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

as created or updated on September 26, 2007.<br />

April 2005, First Edition<br />

The revisions of this First Edition, first published on April 11, 2005, reflect the changes and<br />

additions described below.<br />

April 2005, First Update<br />

Changed in<strong>for</strong>mation<br />

► Figure 4-2 on page 132, corrected text from reocover to recover<br />

► Figure 4-16 on page 181, corrected the direction of arrows<br />

► Removed the non supported message DSNB360I from “Detecting long-running readers”<br />

on page 207.<br />

► Table 5-3 on page 254, corrected Elapsed % from +73% to +186%.<br />

► Figure 5-7 on page 228, corrected title and caption from MB to GB.<br />

► Removed an incorrect chart on Check Index on 10 partitions just be<strong>for</strong>e 6.1.2,<br />

“Conclusion” on page 267.<br />

► Figure 7-3 on page 289, corrected text in the title from 10,000 to 100,000<br />

► Figure 7-9 on page 297, corrected TPCIP to TCP/IP<br />

► Figure 7-18 on page 305, corrected tops to tps<br />

Added in<strong>for</strong>mation<br />

► Added ITR definition under Figure 7-17 on page 303.<br />

May 2005, Second Update<br />

Changed in<strong>for</strong>mation<br />

► Clarified the CPU % regression on DRDA workloads in 2.1.6, “Compatibility mode” on<br />

page 13.<br />

► Clarified partition pruning in 5.5.1, “Partitioned table space without index” on page 247.<br />

► Updated measurements and text <strong>for</strong> Table 5-3 and Table 5-4 on page 254 on NPI v. DPSI<br />

queries.<br />

► Corrected some text in 5.2, “Automated space management” on page 226 and updated<br />

Figure 5-7 on page 228.<br />

► Updated status of some APARs in Table A-1 on page 378 and Table A-2 on page 386.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xxi


Added in<strong>for</strong>mation<br />

The following APARS have been added to Table A-1 on page 378:<br />

► PQ99658 (IFCID 225 in Class 1 Statistics)<br />

► PK04076 (SORTKEYS not activated <strong>for</strong> LOAD with one index)<br />

► PK05360 (hybrid join with local multi-row support<br />

► PK01510 and PK03469 <strong>for</strong> RUNSTATS<br />

November 2005, Third Update<br />

Changed in<strong>for</strong>mation<br />

► Updated the <strong>DB2</strong> Estimator Web site at 10.1, “<strong>DB2</strong> Estimator” on page 364.<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added PTF UK06848 <strong>for</strong> APAR PQ99482 <strong>for</strong> QMF <strong>for</strong> TSO/CICS 8.1 support of multi-row<br />

fetch and insert at the end of 3.1, “Multi-row FETCH, INSERT, cursor UPDATE and<br />

DELETE” on page 31.<br />

► Added an important note at the end of 4.3, “Monitoring DBM1 storage” on page 157 to<br />

mention the changes provided by APAR PQ99658 to the availability of virtual storage<br />

diagnostic record IFCID 225.<br />

► Added section 4.11, “<strong>IBM</strong> System z9 and MIDAWs” on page 202.<br />

► Added a note at the end of 5.2, “Automated space management” on page 226 to mention<br />

the pre<strong>for</strong>matting enhancement provided by APAR PK05644.<br />

► Added a note at the end of 6.2, “LOAD and REORG” on page 268 to mention that with<br />

APAR PK04076 LOAD sort is avoided <strong>for</strong> LOAD SHRLEVEL NONE if data is sorted and<br />

only one index exists.<br />

► Added the in<strong>for</strong>mational APAR II14047 f on the use of DFSORT by <strong>DB2</strong> utilities at 6.2.3,<br />

“Recommendations” on page 269.<br />

► Added JDBC .app/<strong>DB2</strong> Connect vs. JCC Type 4 - Servlet workload and the<br />

measurements of Figure 7-10 on page 297.<br />

► Added JCC Type 4 vs. JCC Type 4 with <strong>DB2</strong> Connect measurements of Figure 7-13 on<br />

page 299.<br />

► Added in<strong>for</strong>mation on maintenance in 7.6, “Enterprise Workload Manager” on page 312.<br />

► Added Figure 7-26 on page 316 with EWLM measurements.<br />

► The following APARS have been added to Table A-1 on page 378:<br />

– PQ99707, per<strong>for</strong>mance improvement <strong>for</strong> JCC clients<br />

– PK05644, pre<strong>for</strong>matting change<br />

– PK09268, column processing improvement<br />

– PK12389 SQL enhancements in compatibility mode<br />

► The following APARS, related to EWLM support in z/<strong>OS</strong>, have been added to Table A-3 on<br />

page 390:<br />

– OA07196<br />

– OA07356<br />

– OA12005<br />

xxii <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


January 2006, Fourth Update<br />

Changed in<strong>for</strong>mation<br />

► Updated the APAR in<strong>for</strong>mation “User thread storage comparison” on page 151.<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added PTF status.<br />

June 2006, Fifth Update<br />

Changed in<strong>for</strong>mation<br />

► Updated the APAR in<strong>for</strong>mation “User thread storage comparison” on page 151.<br />

► Updated 5.6.6, “Lock holder can inherit WLM priority from lock waiter” on page 258.<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added new APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance” on page 377.<br />

October 2006, Sixth Update<br />

Changed in<strong>for</strong>mation<br />

► Clarified the scope of improvements at 3.11, “REXX support improvements” on page 90.<br />

► Updated the paragraph on FREQVAL on page 274 to show the correct parameter<br />

NUMCOLS instead of COLUMN.<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added a reference to data sharing in<strong>for</strong>mation at Chapter 8, “Data sharing enhancements”<br />

on page 319.<br />

► Added a reference to Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on z/<strong>OS</strong> in new<br />

section 10.4, “Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on z/<strong>OS</strong>” on page 367.<br />

► Added new APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance” on page 377.<br />

August 2007, Seventh Update<br />

Changed in<strong>for</strong>mation<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added a Note box to the RUNSTATS option on page 274 to show how to avoid collecting<br />

FREQVAL values.<br />

► Added new APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance” on page 377.<br />

Summary of changes xxiii


► Added reference to June 15, 2007 <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SUP tape in Appendix A.1,<br />

“Maintenance <strong>for</strong> <strong>DB2</strong> V8” on page 378.<br />

September 2007, Eighth Update<br />

This is likely to be the last update. Change bars identify the changed or added areas by this<br />

update. Change bars from previous updates have been removed.<br />

Changed in<strong>for</strong>mation<br />

► Updated text on JCC T4 concentrator in the section JCC Type 4 vs. JCC Type 4 with <strong>DB2</strong><br />

Connect - IRWW workload at page 301.<br />

► Updated status of several APARs in Appendix A, “Summary of per<strong>for</strong>mance maintenance”<br />

on page 377.<br />

Added in<strong>for</strong>mation<br />

► Added in<strong>for</strong>mation on new APARs in Appendix A, “Summary of per<strong>for</strong>mance<br />

maintenance” on page 377.<br />

xxiv <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Preface<br />

<strong>IBM</strong>® DATABASE 2 Universal Database Server <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 (<strong>DB2</strong> V8 or V8 throughout<br />

this <strong>IBM</strong> <strong>Redbooks</strong> publication) is the twelfth and largest release of <strong>DB2</strong> <strong>for</strong> MVS. It brings<br />

synergy with the zSeries® hardware and exploits the z/<strong>OS</strong> 64-bit virtual addressing<br />

capabilities. <strong>DB2</strong> V8 offers data support, application development, and query functionality<br />

enhancements <strong>for</strong> e-business, while building upon the traditional characteristics of availability,<br />

exceptional scalability, and per<strong>for</strong>mance <strong>for</strong> the enterprise of choice.<br />

Key improvements enhance scalability, application porting, security architecture, and<br />

continuous availability. Management <strong>for</strong> very large databases is made much easier, while<br />

64-bit virtual storage support makes management simpler and improves scalability and<br />

availability. This new version breaks through many old limitations in the definition of <strong>DB2</strong><br />

objects, including SQL improvements, schema evolution, longer names <strong>for</strong> tables and<br />

columns, longer SQL statements, enhanced Java and Unicode support, enhanced utilities,<br />

and more log data sets.<br />

This book introduces the major per<strong>for</strong>mance and availability changes as well as the<br />

per<strong>for</strong>mance characteristics of many new functions. It helps you understand the per<strong>for</strong>mance<br />

implications of migrating to <strong>DB2</strong> V8 with considerations based on laboratory measurements.<br />

It provides the type of in<strong>for</strong>mation needed to start evaluating the per<strong>for</strong>mance impact of <strong>DB2</strong><br />

V8 and its capacity planning needs.<br />

Notice that in this document <strong>DB2</strong> refers to the z/<strong>OS</strong> member of the <strong>DB2</strong> family of products.<br />

We have specified the full name of the products whenever the reference was ambiguous.<br />

This book concentrates on the per<strong>for</strong>mance aspects of <strong>DB2</strong> V8, <strong>for</strong> a complete picture of V8<br />

functions and more details on them, refer to the documentation listed at the Web site:<br />

http://www.ibm.com/software/data/db2/zos/index.html<br />

The team that wrote this book<br />

This book was produced by a team of specialists from around the world working at the<br />

International Technical Support Organization, San Jose Center.<br />

Paolo Bruni is a <strong>DB2</strong> In<strong>for</strong>mation Management Project Leader at the International Technical<br />

Support Organization, San Jose Center. He has authored several <strong>Redbooks</strong>® about <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> and related tools, and has conducted workshops and seminars worldwide. During<br />

Paolo’s many years with <strong>IBM</strong>, in development, and in the field, his work has been mostly<br />

related to database systems.<br />

Doracilio Fernandes de Farias Jr is a Systems Analyst with Bank of Brazil since 1999. He<br />

has provided <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> support on installation, customization, migration, and per<strong>for</strong>mance<br />

in a very large data sharing complex. Doracilio has extensive experience with per<strong>for</strong>mance<br />

analysis, both at system and subsystem level, and logical and physical database design.<br />

Yoshio Ishii is a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> Consultant at Lawrence Consulting, an <strong>IBM</strong> business partner<br />

company providing strategic IT consulting services, education and mentoring <strong>for</strong> <strong>IBM</strong> <strong>DB2</strong><br />

and WebSphere® software. Yoshio has been working as DBA, per<strong>for</strong>mance analyst <strong>for</strong> data<br />

warehouse, and instructor <strong>for</strong> "<strong>DB2</strong> Per<strong>for</strong>mance <strong>for</strong> Applications" since 2003. Be<strong>for</strong>e<br />

becoming a Consultant in 1999, he had been working <strong>for</strong> <strong>IBM</strong> <strong>for</strong> 30 years. He has previously<br />

co-authored the book <strong>DB2</strong> <strong>Version</strong> 4 Data Sharing Per<strong>for</strong>mance <strong>Topics</strong>, SG24-4611.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. xxv


Michael Parbs is a <strong>DB2</strong> Specialist with <strong>IBM</strong> Global Services A/NZ, from Canberra, Australia.<br />

He has over 15 years experience with <strong>DB2</strong>, primarily on the <strong>OS</strong>/390® plat<strong>for</strong>m. Be<strong>for</strong>e joining<br />

<strong>IBM</strong> Global Services A/NZ he worked in the public sector in Australia, as a DBA and a <strong>DB2</strong><br />

Systems Programmer. Michael’s main areas of expertise are data sharing and distributed<br />

processing, but his skills include database administration and <strong>DB2</strong> per<strong>for</strong>mance and tuning.<br />

Michael has co-authored the redbooks: <strong>DB2</strong> <strong>for</strong> MVS/ESA <strong>Version</strong> 4 Data Sharing<br />

Implementation, SG24-4791, <strong>DB2</strong> <strong>UDB</strong> Server <strong>for</strong> <strong>OS</strong>/390 and z/<strong>OS</strong> <strong>Version</strong> 7 Presentation<br />

Guide, SG24-6121, and <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever Wanted to Know,<br />

... and More, SG24-6079.<br />

Mary Petras is a Senior Software Engineer at the Silicon Valley Lab, where she is currently a<br />

<strong>DB2</strong> Tools Technical Support Specialist working with <strong>DB2</strong> Tool customers. She studied<br />

Mathematics at Pratt Institute, School of Engineering and Science, in Brooklyn, New York,<br />

and the University of Connecticut in Storrs. Her areas of expertise include <strong>DB2</strong> data sharing<br />

and per<strong>for</strong>mance and tuning. Mary has previously co-authored the redbooks: <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong><br />

<strong>OS</strong>/390 <strong>Version</strong> 6 Per<strong>for</strong>mance <strong>Topics</strong>, SG24-5351, and <strong>DB2</strong> Per<strong>for</strong>mance Expert <strong>for</strong> z/<strong>OS</strong><br />

<strong>Version</strong> 2, SG24-6867-01.<br />

Tsumugi Taira is a Project Leader with NIWS Co, Ltd. in Japan, a company specialized in<br />

advanced services in the Web/Server Business System Field, joint venture between <strong>IBM</strong><br />

Japan and Nomura Research Institute. Tsumugi has six years of experience in <strong>DB2</strong> <strong>for</strong> AIX®<br />

administration, and is currently on a one year assignment to the <strong>IBM</strong> Silicon Valley Lab, <strong>DB2</strong><br />

<strong>for</strong> z/<strong>OS</strong> Per<strong>for</strong>mance Department, where she has worked on system set up, tuning and<br />

recovery utilities. Her areas of expertise include ESS operations, Tivoli Storage Manager,<br />

fault tolerant systems, and backup and recovery solutions. Tsumugi has co-authored the<br />

recent book Disaster Recovery with <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-6370.<br />

Jan Vandensande is an IT consultant and teacher at Jeeves Consulting Belgium, an <strong>IBM</strong><br />

business partner. He has over 20 years of experience in the database management field.<br />

Be<strong>for</strong>e joining Jeeves Consulting in 1995, Jan worked as an IMS and <strong>DB2</strong> system<br />

administrator in the financial sector. His areas of expertise include backup and recovery, data<br />

sharing, and per<strong>for</strong>mance. Jan has previously co-authored the book <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and<br />

<strong>OS</strong>/390 <strong>Version</strong> 7 Per<strong>for</strong>mance <strong>Topics</strong>, SG24-6129.<br />

A photo of the team is in Figure 1.<br />

xxvi <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 1 Left to right: Yoshio, Tsumugi, Mary, Doracilio, Paolo, Jan and Michael<br />

Special thanks to the members of the <strong>DB2</strong> Per<strong>for</strong>mance Department, Silicon Valley Lab, and<br />

their manager Catherine Cox, <strong>for</strong> providing measurements data and continued support during<br />

this project.<br />

Thanks to the following people <strong>for</strong> their contributions to this project:<br />

Rich Conway<br />

Emma Jacobs<br />

Bob Haimowitz<br />

Sangam Racherla<br />

International Technical Support Organization<br />

Jeff Berger<br />

Patrick Bossman<br />

John Campbell<br />

Gene Fuh<br />

James Guo<br />

Akiko Hoshikawa<br />

Koshy John<br />

Gopal Krishnam<br />

Ching Lee<br />

Dave Levish<br />

Chan-hua Liu<br />

Roger Miller<br />

Manvendra Mishra<br />

Todd Munk<br />

Ka C Ng<br />

Mai Nguyen<br />

Jim Pickel<br />

Terry Purcell<br />

Jim Ruddy<br />

Akira Shibamiya<br />

Don Smith<br />

Preface xxvii


Hugh Smith<br />

Jim Teng<br />

John Tobler<br />

Yoichi Tsuji<br />

Steve Turnbaugh<br />

Frank Vitro<br />

Jay Yothers<br />

Maryela Weihrauch<br />

Dan Weis<br />

Chung Wu<br />

David Zhang<br />

<strong>IBM</strong> Silicon Valley Laboratory<br />

Bart Steegmans<br />

<strong>IBM</strong> Belgium<br />

Norbert Heck<br />

<strong>IBM</strong> Germany<br />

Martin Packer<br />

<strong>IBM</strong> UK<br />

Richard Corrihons<br />

<strong>IBM</strong> France<br />

Become a published author<br />

Join us <strong>for</strong> a two- to seven-week residency program! Help write an <strong>IBM</strong> <strong>Redbooks</strong> publication<br />

dealing with specific products or solutions, while getting hands-on experience with<br />

leading-edge technologies. You'll team with <strong>IBM</strong> technical professionals, Business Partners<br />

and/or customers.<br />

Your ef<strong>for</strong>ts will help increase product acceptance and customer satisfaction. As a bonus, you<br />

will develop a network of contacts in <strong>IBM</strong> development labs, and increase your productivity<br />

and marketability.<br />

Find out more about the residency program, browse the residency index, and apply online at:<br />

ibm.com/redbooks/residencies.html<br />

Comments welcome<br />

Your comments are important to us!<br />

We want our <strong>Redbooks</strong> to be as helpful as possible. Send us your comments about this or<br />

other <strong>Redbooks</strong> in one of the following ways:<br />

► Use the online Contact us review book <strong>for</strong>m found at:<br />

ibm.com/redbooks<br />

► Send your comments in an e-mail to:<br />

redbook@us.ibm.com<br />

► Mail your comments to:<br />

xxviii <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


<strong>IBM</strong> Corporation, International Technical Support Organization<br />

Dept. QXXE Building 80-E2<br />

650 Harry Road<br />

San Jose, Cali<strong>for</strong>nia 95120-6099<br />

Preface xxix


xxx <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 1. <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

1<br />

<strong>Version</strong> 8 of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> is the largest release ever shipped, including <strong>Version</strong> 1, which<br />

became generally available in 1985. In this chapter we briefly describe the major<br />

enhancements available with <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8. This represents an introduction to<br />

all functions, not just those related to per<strong>for</strong>mance.<br />

For a more inclusive list, more details, and current in<strong>for</strong>mation always refer to the Web site:<br />

http://www.ibm.com/software/data/db2/zos/index.html<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 1


1.1 Overview<br />

1.1.1 Architecture<br />

<strong>IBM</strong> <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 (<strong>DB2</strong> V8 or V8 throughout this publication) includes dozens<br />

of changes in SQL, improving <strong>DB2</strong> family consistency in many cases, and leading the way in<br />

others. Many limits our customers faced are no longer a restriction at all: Using 64-bit virtual<br />

memory addressing, providing longer table and column names, allowing 2 MB SQL<br />

statements, 4,096 partitions, and three times the log space.<br />

Key per<strong>for</strong>mance enhancements deliver better family consistency and allow you to execute<br />

functions faster. Being able to make database changes without an outage, such as adding a<br />

partition, is a breakthrough <strong>for</strong> availability. Improvements in Java functions, and consistency<br />

and integration with WebSphere, make z/<strong>OS</strong> a better plat<strong>for</strong>m <strong>for</strong> Java. Expansions to<br />

security allow <strong>for</strong> row level granularity, helping with security issues of Web-related<br />

applications. Many of these enhancements also strengthen key vendor applications like<br />

PeopleSoft®, SAP®, and Siebel®.<br />

Major improvements include:<br />

► Virtual storage constraint relief<br />

► Unicode support<br />

► Automated prior point-in-time recovery<br />

► Multi-row fetch, insert<br />

► Multiple DISTINCT clauses<br />

► Lock contention avoidance via volatile tables<br />

► Use of index <strong>for</strong> backwards searches<br />

► Transparent ROWID<br />

► Create deferred index enhancement<br />

► Longer table names<br />

► Providing DSTATS functionality inside RUNSTATS<br />

► Converting column type<br />

► Altering the CLUSTER option<br />

► Adding columns to an index<br />

► Index-only access path <strong>for</strong> VARCHAR<br />

► Changing the number of partitions<br />

► Data-partitioned secondary indexes<br />

► Control Center enhancement<br />

► DRDA enhancements<br />

In this section we group the enhancements into categories based on the area of impact on<br />

your applications. These categories are:<br />

► Architecture<br />

► Usability, availability, and scalability<br />

► Data warehouse<br />

► Per<strong>for</strong>mance<br />

► System level point-in-time backup and recovery<br />

The most important enhancements to the <strong>DB2</strong> architecture are:<br />

► 64-bit virtual storage<br />

This enhancement utilizes zSeries 64-bit architecture to support 64-bit virtual storage.<br />

The zSeries 64-bit architecture allows <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> to move portions of various<br />

storage areas above the 2-GB bar:<br />

2 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


– Buffer pools and buffer pool control blocks<br />

– EDM pool (DBDs and dynamic statement cache)<br />

– Sort pool<br />

– RID pool<br />

– Castout buffers<br />

– Compression dictionaries<br />

A large address space of up to 264 bytes (16 exabytes) can now be defined <strong>for</strong> DBM1 and<br />

IRLM address spaces. DBM1 replaces hiper spaces and data spaces with buffer pools. As<br />

a result, managing virtual storage becomes simpler, and the scalability, availability, and<br />

per<strong>for</strong>mance improves as your real storage requirements and number of concurrent users<br />

increase. IRLM can support large numbers of locks.<br />

► Schema evolution<br />

As 24x7 availability becomes more critical <strong>for</strong> applications, the need grows <strong>for</strong> allowing<br />

changes to database objects while minimizing the impact on availability. Online schema<br />

evolution allows <strong>for</strong> table, index, and table space attribute changes while maximizing<br />

application availability. For example, you can change column types and lengths, add<br />

columns to an index, add, rotate, or rebalance partitions, and specify which index (the<br />

partitioning index or non-partitioning index) you want to use as the clustering index.<br />

► <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC<br />

Organizations increasingly require access to data residing in multiple sources in multiple<br />

plat<strong>for</strong>ms throughout the enterprise. More and more companies are buying applications<br />

rather than database management systems, as database selection is being driven by<br />

interoperability, price per<strong>for</strong>mance, and scalability of the server plat<strong>for</strong>m. The Universal<br />

Driver <strong>for</strong> SQLJ and JDBC provides an open and consistent set of database protocols to<br />

access data on the Linux®, UNIX®, Windows®, and z/<strong>OS</strong> plat<strong>for</strong>ms.<br />

Tools and applications can be developed using a consistent set of interfaces regardless of<br />

the plat<strong>for</strong>m where the data resides. End users can integrate their desktop tools and other<br />

applications in a consistent manner with whichever databases (or multiple databases<br />

concurrently) are in the enterprise. The objective of this enhancement is to implement<br />

<strong>Version</strong> 3 of the Open Group DRDA Technical Standard. It eliminates the need <strong>for</strong><br />

gateways, improves desktop per<strong>for</strong>mance, and provides a consistent set of database<br />

protocols accessing data from a z/<strong>OS</strong> server as well as UNIX and Windows servers.<br />

► Unicode support<br />

Architectural changes to <strong>DB2</strong> V8 enhance the <strong>DB2</strong> support <strong>for</strong> Unicode with SQL in<br />

Unicode, Unicode in the <strong>DB2</strong> catalog and the ability to join Unicode, ASCII and EBCDIC<br />

tables. This means that you can manage data from around the world in the same SQL<br />

statement. <strong>DB2</strong> now converts any SQL statement to Unicode be<strong>for</strong>e parsing, and as a<br />

result, all characters parse correctly.<br />

► <strong>DB2</strong> Connect and DRDA<br />

<strong>DB2</strong> Connect and DRDA remain the cornerstone <strong>for</strong> <strong>DB2</strong> distributed processing, and V8<br />

has many enhancements in this area. Enhancements in <strong>DB2</strong> V8 remove roadblocks to<br />

per<strong>for</strong>mance and <strong>DB2</strong> family compatibility by providing support <strong>for</strong> Common Connectivity<br />

and standardizing database connection protocols based on the Open Group Technical<br />

Standard DRDA <strong>Version</strong> 3.<br />

1.1.2 Usability, availability, and scalability<br />

The main enhancements related to usability, availability, and scalability are:<br />

► Online schema evolution<br />

You can change data and indexes with minimal disruption.<br />

Chapter 1. <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 3


– Column data type changes can be done without losing data availability to data and<br />

indexes. In V5 you could increase the size of VARCHAR columns, the changes in V8<br />

allow you to extend numeric and character columns and to change between CHAR and<br />

VARCHAR.<br />

– Indexes can have columns added, and VARCHAR columns changed from padded to<br />

non padded.<br />

► Partitioning<br />

Several partitioning enhancements are included in <strong>DB2</strong> V8 that are useful in almost all real<br />

life environments.<br />

– Online partitioning changes<br />

You can add a new partition to an existing partitioned table space and rotate partitions.<br />

– More partitions<br />

This enhancement increases the maximum number of partitions in a partitioned table<br />

space and index space past the current maximum of 254. The new maximum number<br />

of partitions is 4,096. The DSSIZE and page size determine the maximum number of<br />

possible partitions.<br />

– Data-partitioned secondary indexes<br />

V8 introduces data-partitioned secondary indexes to improve data availability during<br />

partition level utility operations (REORG PART, LOAD PART, RECOVER PART) and<br />

facilitate more complex partition level operations (roll on/off part, rotate part) introduced<br />

by Online Schema Evolution. The improved availability is accomplished by allowing the<br />

secondary indexes on partitioned tables to be partitioned according to the partitioning<br />

of the underlying data.<br />

There is no BUILD2 phase component to REORG SHRLEVEL CHANGE when all<br />

secondary indexes are partitioned, nor is there contention between LOAD PART jobs<br />

executing on different partitions of a table space. A data-partitioned secondary index is<br />

most useful when the query has predicates on both the secondary index columns and<br />

the partitioning columns.<br />

– Separation of partitioning and clustering<br />

Partitioning and clustering were bundled together in versions prior to V8. Now you can<br />

have a partitioned table space without an index and can cluster the data on any index.<br />

These changes may be able to eliminate one index (since you are no longer required to<br />

have a partitioning index) and reduce random I/O (since you can now define any index<br />

as the clustering index).<br />

► System level point-in-time backup and recovery<br />

The system level point-in-time recovery enhancement provides the capability to recover<br />

the <strong>DB2</strong> system to any point-in-time, irrespective of the presence of uncommitted units of<br />

work, in the shortest amount of time. This is accomplished by identifying the minimum<br />

number of objects that should be involved in the recovery process, which in turn reduces<br />

the time needed to restore the data and minimizes the amount of log data that needs to be<br />

applied.<br />

For larger <strong>DB2</strong> systems with more than 30,000 tables, this enhancement significantly<br />

improves data recovery time, which in turn results in considerably shorter system<br />

downtime.<br />

► BACKUP and RESTORE SYSTEM<br />

These two new utilities provide system level backup, and system level point-in-time<br />

recovery. They activate new functionality available with the new z/<strong>OS</strong> V1R5<br />

DFSMShsm, which allows a much easier and less disruptive way <strong>for</strong> fast volume-level<br />

backup and recovery to be used <strong>for</strong> disaster recovery and system cloning.<br />

4 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► REORG utility enhancements<br />

The REORG utility is enhanced to allow you to specify that only partitions placed in Reorg<br />

Pending state should be reorganized. You do not have to specify the partition number or<br />

the partition range. You can also specify that the rows in the table space or the partition<br />

ranges being reorganized should be evenly distributed <strong>for</strong> each partition range when they<br />

are reloaded. Thus, you do not have to execute an ALTER INDEX statement be<strong>for</strong>e<br />

executing the REORG utility. You can specify DISCARD with SHRLEVEL CHANGE. You<br />

can avoid the BUILD2 phase during online REORG by using the new data-partitioned<br />

secondary indexes.<br />

► Online Check Index utility<br />

The new SHRLEVEL CHANGE option specifies that applications can read from and write<br />

to the index, table space, or partition that is to be checked. This option uses techniques<br />

which allow access to the index during almost all of the CHECK process. The processing<br />

is per<strong>for</strong>med on a copy of the data and can use FlashCopy® to obtain a copy in a matter of<br />

seconds.<br />

► Create index dynamic statement invalidation<br />

Create index now invalidates the cached statements associated with the base table<br />

contained in the dynamic statement cache without draining active statements.<br />

► Automatic space management<br />

Many IT people in DB installations consider this a very valuable feature. It potentially<br />

eliminates one of the main causes of failure where rapid growth was not anticipated.<br />

► Minimize impact of creating deferred indexes<br />

Indexes created as deferred are ignored by the <strong>DB2</strong> optimizer.<br />

► LOB ROWID transparency<br />

This enhancement includes the capability of hiding the ROWID column from DML and<br />

DDL. This way, applications, running on other plat<strong>for</strong>ms, that do not have a ROWID data<br />

type can avoid the special code to handle ROWID and use the same code path <strong>for</strong> all<br />

plat<strong>for</strong>ms.<br />

► Longer table and column names<br />

Architectural changes to <strong>DB2</strong> V8 expand the <strong>DB2</strong> catalog and SQL with support <strong>for</strong> long<br />

names (tables and other names up to 128 bytes, column names up to 30 bytes). Support<br />

<strong>for</strong> longer string constants (up to 32,704 bytes), longer index keys (up to 2,000 bytes), and<br />

longer predicates (up to 32,704 bytes) makes <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> compatible with other<br />

members of the <strong>DB2</strong> family.<br />

► SQL statements extended to 2 MB<br />

Complex SQL coding, SQL procedures, and generated SQL, as well as compatibility with<br />

other plat<strong>for</strong>ms and conversions from other products, have required the extension of the<br />

SQL statements in <strong>DB2</strong>. <strong>DB2</strong> V8 extends the limit on the size of an SQL statement to 2<br />

MB.<br />

► Multiple DISTINCT clauses in SQL statements<br />

This enhancement allows the DISTINCT keyword to appear in multiple column functions<br />

with different expressions. For example, <strong>DB2</strong> V8 now allows:<br />

SELECT SUM(DISTINCT C1), AVG(DISTINCT C2) FROM T1<br />

► More open data sets<br />

With <strong>DB2</strong> V8 and z/<strong>OS</strong> 1.5, a <strong>DB2</strong> subsystem can have up to 65,041 open data sets,<br />

instead of 32,767 in V7. This enhancement also reduces the amount of virtual storage<br />

used by <strong>DB2</strong> below the 16 MB line, as MVS control blocks related to dynamically allocated<br />

Chapter 1. <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 5


1.1.3 Data warehouse<br />

1.1.4 Per<strong>for</strong>mance<br />

data sets are requested above the 16 MB line. When those open data sets (or partitions)<br />

are compressed, the compression dictionary is loaded above the 2 GB bar.<br />

► More log data sets<br />

The maximum number of active log data sets per log copy is increased from 31 to 93. The<br />

maximum number of archive log volumes recorded in the BSDS is increased from 1,000 to<br />

10,000 per log copy. If this limit is exceeded, there is a wrap around, and the first entry<br />

gets overwritten .<br />

► CI size larger than 4 KB<br />

<strong>DB2</strong> V8 introduces support <strong>for</strong> CI sizes of 8, 16, and 32 KB. This is valid <strong>for</strong> user-defined<br />

and <strong>DB2</strong>-defined table spaces. The new CI sizes relieve some restrictions on backup,<br />

concurrent copy, and the use of striping, as well as provide the potential <strong>for</strong> reducing<br />

elapsed time <strong>for</strong> large table space scans.<br />

The most important enhancements specifically affecting the data warehouse applications are:<br />

► More tables in joins<br />

In <strong>DB2</strong> V7 the number of tables in the FROM clause of a SELECT statement can be 225<br />

<strong>for</strong> a star join. However, the number of tables that can be joined in other types of join is 15.<br />

<strong>DB2</strong> V8 allows 225 tables to be joined in all types of joins.<br />

► Sparse index and in-memory work files <strong>for</strong> star join<br />

The star join implementation in <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> potentially has to deal with a large<br />

number of work files, especially <strong>for</strong> a highly normalized star schema that can involve many<br />

snowflakes, and the cost of the sorting of these work files can be very expensive. <strong>DB2</strong> V8<br />

extends the use of a sparse index (a dynamically built index pointing to a range of values)<br />

to the star join work files and adds a new optional function of data caching on star join<br />

work files. The decision to use the sparse index is made based on the estimation of the<br />

cost of the access paths available.<br />

► Common table expression and recursive SQL<br />

<strong>DB2</strong> V8 introduces the common table expression and recursive SQL function, which<br />

extends the expressiveness of SQL and lets users derive the query result through<br />

recursion. It is also a convenient way <strong>for</strong> users to express complex queries, since using<br />

common table expressions instead of views saves both users and the system the work of<br />

creating and dropping views.<br />

► Materialized query tables<br />

This enhancement provides a set of functions that allows <strong>DB2</strong> applications to define,<br />

populate, and make use of materialized query tables. Large data warehouses definitely<br />

benefit from MQTs <strong>for</strong> queries against objects in an operational data store.<br />

However several other changes to improve optimization techniques, improve statistics <strong>for</strong><br />

optimization, and better analysis of the access path, listed under per<strong>for</strong>mance, also benefit<br />

warehousing applications. Even more additions that add to warehousing applications are<br />

enhancements to the ability to use indexes, the new DSTATS option of RUNSTATS, the new<br />

Visual Explain, and the online schema changes.<br />

The main <strong>DB2</strong> V8 improvements related to per<strong>for</strong>mance are:<br />

► Multi-row INSERT and FETCH<br />

6 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


With this SQL enhancement, a single FETCH can be used to retrieve multiple rows of<br />

data, and an INSERT can insert one or more rows into a table. This reduces the number of<br />

times the application and database must switch control. It can also reduce the number of<br />

network trips required <strong>for</strong> multiple fetch or insert operations <strong>for</strong> distributed requests. For<br />

some applications, this can help per<strong>for</strong>mance dramatically.<br />

► RUNSTATS improvements<br />

The improvements <strong>for</strong> RUNSTATS are related to the following areas:<br />

– Code optimization<br />

The changes have produced up to a 40% reduction in the execution time of a<br />

RUNSTATS TABLESPACE.<br />

– Distribution statistics<br />

This enhancement adds new functionality of calculating frequencies <strong>for</strong> non-leading<br />

and non-indexed columns to RUNSTATS. The relevant catalog tables are updated with<br />

the specified number of highest frequencies and optionally with the specified number of<br />

lowest frequencies. The new functionality also optionally collects multi-column<br />

cardinality <strong>for</strong> non-indexed column groups and column groups of non-leading index<br />

columns, and updates the catalog.<br />

– Fast-cached SQL statement invalidation<br />

This enhancement adds new functionality of allowing UPDATE NONE and REPORT<br />

NO keywords to be used on the same RUNSTATS utility execution. This causes the<br />

utility to only invalidate statements in the dynamic statement cache without any data<br />

access or computation cost.<br />

► Host variables’ impact on access paths<br />

The enhancement allows <strong>for</strong> a new BIND option, REOPT(ONCE). It allows you to<br />

re-optimize an SQL dynamic statement based on the host variable value, the first time it is<br />

executed. After that, the statement is stored in the dynamic statement cache.<br />

► Index only access <strong>for</strong> VARCHAR<br />

This enhancement removes the key padding associated with VARCHAR index columns.<br />

This allows the use of these columns to satisfy the results of queries that can use index<br />

only access.<br />

► Backward index scan<br />

The backward index chain has been introduced with Type 2 indexes. However, only in V7<br />

did <strong>DB2</strong> start to exploit the backward index chain <strong>for</strong> MIN and MAX functions. In V8, <strong>DB2</strong><br />

extends this functionality with the capability <strong>for</strong> backward index scans. This allows <strong>DB2</strong> to<br />

avoid more sorts and allows customers to define fewer indexes.<br />

► Local SQL cache issues and short prepare<br />

This enhancement reduces the cost of a short prepare.<br />

► Multiple IN values<br />

This enhancement causes the <strong>DB2</strong> optimizer to make a wiser choice when considering<br />

index usage on single table SQL queries that involve large numbers of IN list items.<br />

► Dynamic statement cache statement ID in EXPLAIN<br />

This enhancement allows the <strong>DB2</strong> EXPLAIN statement to report the chosen access path<br />

of an SQL statement currently in the dynamic statement cache (DSC).<br />

► Locking improvements<br />

The most important improvements in locking:<br />

– Reduced lock contention on volatile tables<br />

Chapter 1. <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 7


Volatile (or cluster) tables, used primarily by ERP vendors like SAP, are tables that<br />

contain groups (or clusters) of rows which logically belong together. Within each<br />

cluster, rows are meant to be accessed in the same sequence every time. Lock<br />

contention occurs when <strong>DB2</strong> chooses different access paths <strong>for</strong> different applications<br />

operating on the same cluster table. In the absence of support <strong>for</strong> cluster tables in <strong>DB2</strong>,<br />

users have to either change system-wide parameters that affect all tables, or change<br />

statistics <strong>for</strong> each such table to ease the lock contention.<br />

Cluster tables are referred to as volatile tables in <strong>DB2</strong>. Adding a new keyword,<br />

VOLATILE, to the CREATE TABLE and ALTER TABLE statements signifies to <strong>DB2</strong><br />

which tables should be treated as volatile tables. For volatile tables, index access is<br />

chosen whenever possible, regardless of the efficiency of the available indexes. That<br />

is, a table scan is not chosen in preference to an inefficient index.<br />

– CF lock propagation reduction<br />

In a data sharing environment, this enhancement allows parent L-locks to be granted<br />

locally without invoking global contention processing. Thereby, locking overhead due to<br />

false contention is reduced. As a result, <strong>DB2</strong> data sharing per<strong>for</strong>mance is enhanced.<br />

Per<strong>for</strong>mance benefit varies depending on factors such as commit interval, thread<br />

reuse, and number of tables accessed in a commit interval, if the SQL processing is<br />

read-only or update.<br />

– Several other lock enhancements, including overflow lock avoidance, skip uncommitted<br />

inserts, and drain lock on partition key update.<br />

► Instrumentation enhancements<br />

<strong>DB2</strong> V8 comes with numerous enhancements to the Instrumentation Facility Interface.<br />

The most important are:<br />

– Package level accounting<br />

– Accounting roll-up <strong>for</strong> DDF and RRSAF threads<br />

– Long-running reader tracking<br />

– Lock escalation trace record<br />

– Full SQL statement text trace record<br />

– PREPARE attributes are also traced<br />

– More high water marks in the statistics record<br />

– Secondary authorization IDs via READS<br />

– Storage 64-bit support as well as READS support<br />

– Temporary space usage<br />

– Auditing <strong>for</strong> multilevel security<br />

– Option <strong>for</strong> EBCDIC or Unicode data<br />

1.1.5 Migration changes<br />

Migration is allowed exclusively from <strong>DB2</strong> V7 subsystems. The migration SPE must have<br />

been applied and started. The migration process has been changed and now consists of<br />

three distinct steps or phases:<br />

1. Compatibility mode (CM): This is the first phase, during which the user per<strong>for</strong>ms all the<br />

tests needed to make sure all the applications run without problems with the new version.<br />

Fallback to V7 in case of problems is allowed.<br />

2. Enabling-new-function mode (ENFM): During this typically short (usually one hour)<br />

second phase, the user converts the <strong>DB2</strong> catalog and directory to a new <strong>for</strong>mat by using<br />

online REORG executions. No fallback to <strong>DB2</strong> V7 is allowed once this phase is entered.<br />

3. New-function mode (NFM): This is the target third and final phase, where all new V8<br />

functions are available.<br />

8 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 2. Per<strong>for</strong>mance overview<br />

2<br />

Scalability, availability, and per<strong>for</strong>mance are key reasons to choose <strong>DB2</strong> as your premier<br />

enterprise database server. These reasons are mandatory criteria <strong>for</strong> <strong>DB2</strong> in order to allow<br />

growth and be able to exploit (in a balanced manner) increasing processor speed, larger<br />

central storage and faster I/O devices. However, two major inhibitors slowed down growth <strong>for</strong><br />

some leading edge users. These inhibitors were the size of virtual storage available per<br />

address space and the persistent difference in speed between processors and disks’ service<br />

time.<br />

The 2 GB virtual memory size, dictated by the 31-bit MVS architecture, was an inhibitor to<br />

growth <strong>for</strong> the DBM1 address space where many <strong>DB2</strong> throughput-related pools were<br />

acquired. This limited addressing capability in turn reduced the size of the buffer pools that<br />

could be assigned <strong>for</strong> accessing data. The theoretical limit <strong>for</strong> the virtual buffer pools is 1.6<br />

GB, but realistically, <strong>for</strong> most high-end customers, it is less than 800 MB, regardless of the<br />

availability of real storage. <strong>DB2</strong> V7 customers, needing a larger buffer pool, likely use data<br />

space buffer pools, and are able to use 10 to 20 GB.<br />

The architectural solution <strong>DB2</strong> V8 provides is to adopt the 64-bit z/<strong>OS</strong> architecture and<br />

remove the major storage inhibitors. Both the DBM1 and IRLM address spaces now run in<br />

64-bit addressing and take advantage of new 64-bit instructions of the zSeries architecture.<br />

This allows <strong>DB2</strong> to move several storage pools above the 2 GB bar and provides customers<br />

virtual storage constraint relief. In turn, this allows exploitation of the processor speed and<br />

usage of the real storage size of the largest systems.<br />

Savvy users are cautious about changing long-established capacity rules and will ask you<br />

pertinent questions similar to the following ones:<br />

► What is the impact of the new architecture in terms of CPU and I/O utilization?<br />

► How is the virtual storage layout changing? What is still below the 2 GB bar, and what has<br />

moved above the bar?<br />

► How can I make sure I have enough real storage to support my workload today, and<br />

tomorrow?<br />

► What else needs to be done to take advantage of the architecture?<br />

► What new DSNZPARMs affect my real storage consumption?<br />

► What old DSNZPARM default settings may have changed to affect storage and CPU<br />

considerations?<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 9


In this chapter we anticipate the answers to these questions. The details are spread across<br />

the remainder of this book. More complete answers will be provided when available from the<br />

experiences of a larger population of V8 users.<br />

This chapter contains:<br />

► Overview of major impact items<br />

► CPU usage<br />

► DBM1 virtual storage mapping<br />

► Real storage<br />

► Compatibility mode<br />

► New-function mode<br />

► New installation default values<br />

► Recent z/<strong>OS</strong> releases<br />

10 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


2.1 Overview of major impact items<br />

2.1.1 <strong>DB2</strong> catalog<br />

2.1.2 CPU<br />

There is a tremendous amount of new function available in <strong>DB2</strong> V8. Like any release, there<br />

are things you really like and things you like less. And the things you like come at some cost.<br />

In this chapter we present a realistic perspective of <strong>DB2</strong> V8 <strong>for</strong> you: The good and the not so<br />

good. Certainly, adding new function implies adding instructions, and it becomes more and<br />

more difficult to contain the increase in path length. The per<strong>for</strong>mance department at Silicon<br />

Valley Lab, along with <strong>DB2</strong> development, tries to minimize the overhead you can incur with<br />

each new release. This is especially true with V8 because of the large amount of additional<br />

code.<br />

It is important that you are aware of the effect <strong>DB2</strong> V8 has on components of <strong>DB2</strong>, such as<br />

<strong>DB2</strong> catalog, CPU growth, virtual storage, real storage, compatibility mode, and new-function<br />

mode. The more educated and in<strong>for</strong>med you are be<strong>for</strong>e migrating to <strong>DB2</strong> V8, the easier the<br />

planning becomes. The migration is simplified by avoiding known pitfalls. The migration goal<br />

is a smooth and successful implementation and you can concentrate on exploiting the new<br />

functions.<br />

Important: Remember that you can only migrate to <strong>DB2</strong> V8 from <strong>DB2</strong> V7. It is possible to<br />

migrate to <strong>DB2</strong> V7 from <strong>DB2</strong> V5 by a skip release migration. However, skip release<br />

migration is not generally supported, including migration to V8.<br />

We now begin to discuss the components of <strong>DB2</strong> V8.<br />

In <strong>DB2</strong> V8, much of the character data in the <strong>DB2</strong> catalog changes to the Unicode encoding<br />

scheme. This does not mean you have to change all your EBCDIC or ASCII data to Unicode.<br />

The catalog conversion to Unicode allows you to support Unicode object names and literals.<br />

But it does require that you, be<strong>for</strong>e migrating to <strong>DB2</strong> V8, implement z/<strong>OS</strong> Conversion<br />

Services <strong>for</strong> your environment, and this requires an IPL.<br />

Most character columns in the <strong>DB2</strong> catalog are converted to Unicode VARCHAR(128), and<br />

there is typically a 1 to 10% increase in the space used. If you have any user-defined indexes<br />

defined on the catalog, you may want to drop them be<strong>for</strong>e V8. Afterwards, you can redefine<br />

these indexes and specify them as NOT PADDED. If you do not drop these indexes, the<br />

default is PADDED and these user-defined indexes grow considerably, since many columns in<br />

the index grow often from 10 to 128 bytes. For this reason, <strong>DB2</strong> V8 allows variable length<br />

keys (VARCHAR(128)) in an index.<br />

We anticipate that there may be some growth in the size of the <strong>DB2</strong> catalog once you migrate.<br />

However, it really depends on a number of factors. Some installations never or infrequently<br />

per<strong>for</strong>m a reorganization of the <strong>DB2</strong> catalog. For them, the difference in size after migration<br />

may be negligible. For those who REORG on a regular basis, they can see up to a 10%<br />

increase in the size of the <strong>DB2</strong> catalog.<br />

For details regarding the effect of Unicode on the <strong>DB2</strong> catalog and directory, refer to 9.1.2,<br />

“Unicode parsing” on page 342.<br />

In the past, as you migrated from one release of <strong>DB2</strong> to the next, the typical increase was not<br />

more than a 5% CPU cost. In fact, staying under 5% has been the target of <strong>DB2</strong> development.<br />

We estimate that there is four times more code in V8 than in V7, and some CPU increase is<br />

Chapter 2. Per<strong>for</strong>mance overview 11


2.1.3 I/O time<br />

2.1.4 Virtual storage<br />

experienced. But this is not the main reason, since the developers have worked hard to keep<br />

the same path length when executing the <strong>DB2</strong> functions. The main reasons are that the<br />

instructions now deal with possibly large variable length names and that 64-bit mode<br />

instructions often take more time to execute than in 31-bit mode, and there is a need <strong>for</strong> a lot<br />

of expansion of instructions from the 24 and 31-bit type.<br />

<strong>DB2</strong> V8 contains many new features in the areas of availability, scalability, and portability from<br />

other plat<strong>for</strong>ms, such as family consistency, user productivity, and other features. For those<br />

applications not taking advantage of <strong>DB2</strong> V8 per<strong>for</strong>mance features, an increase in CPU time<br />

is anticipated to support all of these new features.<br />

As you examine the different measurements in this book reported in 4.1, “<strong>DB2</strong> CPU<br />

considerations” on page 129, you see that there is fluctuation in CPU cost depending on the<br />

different types of workloads tested. The CPU ranges vary but generally the additional CPU<br />

cost is between 0 and 10%. Of course, we think that eventually you make changes to your<br />

applications and subsystem to take advantage of those new features that ultimately reduce<br />

the CPU cost and hopefully result even in a CPU reduction.<br />

There is only good news here:<br />

► No change in I/O times <strong>for</strong> 4 KB pages.<br />

► Significant sequential I/O time improvement <strong>for</strong> those table spaces with greater than 4 KB<br />

page sizes, as soon as the larger CI sizes are utilized in new-function mode. See 4.10,<br />

“New CI size” on page 199.<br />

► <strong>DB2</strong> V8 removes the limit of 180 CIs per I/O <strong>for</strong> list prefetch and castout I/O requests. See<br />

8.4, “<strong>DB2</strong> I/O CI limit removed” on page 333.<br />

► Compression, with the dictionaries now above the bar, is even more widely applicable, and<br />

can help in reducing I/O.<br />

By far the biggest impact in <strong>DB2</strong> V8 <strong>for</strong> per<strong>for</strong>mance is related to the introduction of the 64-bit<br />

architecture. The reason <strong>for</strong> moving to 64-bit architecture is that leading edge customers were<br />

running into virtual storage constraint problems. For more in<strong>for</strong>mation on this problem, see<br />

the article on <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> Storage Management by John Campbell and Mary Petras at:<br />

http://www.idug.org/idug/member/journal/mar00/storage.cfm<br />

The <strong>DB2</strong> V8 implementation of 64-bit virtual storage is good news <strong>for</strong> installations that had<br />

virtual storage constraint problems in the past. Many of them had to rearrange and reduce the<br />

main <strong>DB2</strong> storage consumers to avoid running into out-of-storage conditions; this new<br />

configuration may not have been as optimal from a per<strong>for</strong>mance point of view. However, you<br />

had no choice but to reduce storage utilization to avoid these out-of-storage conditions.<br />

<strong>DB2</strong> has moved several critical pools above the 2 GB bar, and left some below. Now in <strong>DB2</strong><br />

V8, with many main storage areas moving above the 2 GB bar, a possibility exists to enlarge<br />

these storage areas, which in turn, can result in much better per<strong>for</strong>mance. However, be<br />

careful when looking at thread storage. Most of the thread storage still remains below the bar,<br />

including the application’s local dynamic statement cache, so carefully monitor thread-related<br />

storage.<br />

One observation to note is that both the DBM1 and IRLM address spaces exploit 64-bit virtual<br />

addressing. The other <strong>DB2</strong> address spaces, DIST, MSTR and SPAS, do not yet exploit this<br />

technology.<br />

12 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


2.1.5 Real storage<br />

<strong>DB2</strong> V8 extends upon its improvements in storage management and has also increased<br />

some defaults. All of these changes do not eliminate completely short-on-storage conditions.<br />

You still need to proactively monitor your storage utilization; keep running your <strong>DB2</strong> PE<br />

storage statistics reports and watch your storage utilization over time.<br />

You can experience some real storage growth usage when you migrate from <strong>DB2</strong> V7 to V8.<br />

The growth is due to a number of factors, the most important is 64-bit addressability, Unicode,<br />

long names support and long key support. The 64-bit instructions are inherently longer than<br />

31-bit counterparts; this effect can increase the size of control blocks that store pointers by a<br />

factor of two. Longer names require larger definitions and space.<br />

You need to make sure that the buffer pools are 100% backed by real storage. <strong>DB2</strong> uses an<br />

LRU or FIFO scheme to reclaim pages. As a result, if the oldest pages are paged out to disk,<br />

the paging impact on the system would be significant. In the zSeries architecture, if the buffer<br />

pool is not backed by main storage, the pages would be stored in and out of auxiliary storage<br />

(that is, disks), since there is no configurable expanded storage to provide some hierarchy of<br />

buffering. Expanded storage is not exploited by z/<strong>OS</strong> in the z/Architecture® modeI. It is wise<br />

to prevent excessive paging to auxiliary storage. Use RFM Monitor II and III to monitor the<br />

real storage frames and auxiliary frames used by the <strong>DB2</strong> address spaces. It is very<br />

important to keep in mind that your <strong>DB2</strong> subsystem should not page.<br />

Important: Ensure the buffer pools are backed up by sufficient real storage.<br />

2.1.6 Compatibility mode<br />

Once you commit to migrating to <strong>DB2</strong> V8, the first stop you make is compatibility mode (CM).<br />

As soon as you are in CM, there is no new function. Well, there is actually some new function;<br />

to start with, <strong>DB2</strong> is running in 64-bit mode already, however, there is no new function which<br />

can preclude a fall back to V7. It is not officially documented what is available in CM, and it is<br />

subject to change with maintenance. During this phase, you can test the functionality of<br />

existing applications to ensure they run without problems. Only during this phase can you<br />

revert back to <strong>DB2</strong> V7, so once you make the commitment to proceed to the next two stops,<br />

enabling-new-function mode (ENFM) and new-function mode (NFM), there is no turning back.<br />

You will probably remain in CM <strong>for</strong> a short period of time until you are com<strong>for</strong>table that it is<br />

safe to move <strong>for</strong>ward. If you have several <strong>DB2</strong>-interconnected subsystems, DRDA or<br />

otherwise, migrate all systems to CM be<strong>for</strong>e migrating any system to NFM.<br />

Keep in mind that transition among the modes in a data sharing group is an instantaneous<br />

group wide event; it is not possible to have some members in a data sharing group in one<br />

mode while others are in a different mode. All members of a data sharing group are in the<br />

same mode.<br />

Note: Customers typically stay in CM mode <strong>for</strong> a period of several weeks to a few months.<br />

What we have measured in CM:<br />

► The measurements of the CPU time per commit <strong>for</strong> non-distributed IRWW workload have<br />

shown a slight increase of 4% in accounting CPU time between <strong>DB2</strong> V7 and <strong>DB2</strong> V8 CM.<br />

The IRWW workload is described in <strong>DB2</strong> <strong>for</strong> MVS/ESA <strong>Version</strong> 4 Data Sharing<br />

Per<strong>for</strong>mance <strong>Topics</strong>, SG24-4611. However, there is a considerable decrease in total CPU<br />

time <strong>for</strong> the DBM1 address space (about 20%).<br />

► Other workloads have a different behavior.<br />

Chapter 2. Per<strong>for</strong>mance overview 13


► The per<strong>for</strong>mance benchmarks <strong>for</strong> non-data sharing and data sharing environments have<br />

shown slight differences.<br />

► For the online transaction distributed workload, the increase in CPU can be up to 20% with<br />

an ITR reduction up to 12%. Batch DRDA can take advantage of multi-row fetch, so it can<br />

even show an improvement of 20%.<br />

For details on these results, see Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

2.1.7 New-function mode<br />

After you have run in CM <strong>for</strong> the appropriate length of time determined by your needs, you<br />

decide when it is time to get to the next step which is enabling-new-function mode (ENFM).<br />

You run a job to do so, and now you are ready to enable new-function mode (NFM). ENFM<br />

affects the changes to the catalog, including adding long name support to the catalog,<br />

converting to Unicode, changing system-defined indexes to not-padded, and changing the<br />

page size <strong>for</strong> some of the catalog table spaces to 8 KB, 16 KB, and so on. Once this job is<br />

started, you cannot fallback to <strong>DB2</strong> V7 or to <strong>DB2</strong> V8 CM; the capability to fallback is removed<br />

and en<strong>for</strong>ced once you enable new function mode.<br />

While you are in ENFM, you cannot begin to use any new function yet, but you are no longer<br />

in CM either.<br />

We recommend you consider a minimum amount of changes as you flow through the<br />

migration path to NFM. Be sure to start with the same DSNZPARM settings, and then slowly<br />

begin making changes to your environment one parameter at a time. Similarly, when you<br />

finally reach NFM, slowly begin exploiting some of the new features. This slow path is the best<br />

path <strong>for</strong> risk mitigation and to evaluate the per<strong>for</strong>mance impact of the new features.<br />

A measurement of the IRWW non-data sharing workload has shown no significant difference<br />

in CPU time between CM and no new function NFM.<br />

Coexistence with data sharing<br />

Data sharing coexistence exists only in CM. Coexistence means having both V7 and V8 CM<br />

subsystems in a single data sharing group. ENFM is a group wide event since it affects a<br />

single catalog. As soon as you enable new-function mode on one of the members, it occurs<br />

<strong>for</strong> all of the members in the group.<br />

<strong>DB2</strong> catalog and directory<br />

Once the <strong>DB2</strong> catalog and directory are converted to V8 mode, the size of these structures<br />

can be slightly affected. Many existing VARCHAR columns are altered to VARCHAR(128).<br />

Since most of the columns that are being changed are already VARCHAR, the effect should<br />

be minimal. The maximum length is changing, and not the data that is already there. Some<br />

columns are changed from CHAR(8) to VARCHAR(24). The columns that used to be CHAR<br />

and are changed to VARCHAR get bigger by two bytes. The system-defined catalog indexes,<br />

since they are NOT PADDED, may actually get smaller.<br />

Some catalogs rarely get reorganized, so <strong>for</strong> those that do not, there may be a reclaiming of<br />

space. As a result, it is possible when you migrate to NFM that the size of the catalog may be<br />

slightly reduced.<br />

Typically, we experienced a small amount of <strong>DB2</strong> catalog and directory growth, but not more<br />

than 10%.<br />

14 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


2.2 CPU usage<br />

The most common question is “What did you experience in terms of CPU per<strong>for</strong>mance<br />

impact?”. In any release of <strong>DB2</strong>, what the new features cost is a concern. This release<br />

contains a dramatic amount of new function, and because of that, you may experience an<br />

increase in CPU cost. Since <strong>DB2</strong> V8 deals with much longer names, and exploits 64-bit<br />

addressing, CPU utilization can increase even if instruction path length does not change. The<br />

number of instructions may not change, but because each instruction is now a 64-bit<br />

instruction instead of a 31-bit instruction, it can be more expensive to execute.<br />

This release also has a number of new SQL functions which usually increases path lengths.<br />

Normally, the target is less than 5% CPU increase from release to release. In V8 the target is<br />

less than 10%.<br />

The assumption, when measuring the CPU regression, is that you do not change the<br />

application to take advantage of any new function. Obviously, once you do rewrite the<br />

application to take advantage of new function, you may even experience a decrease in CPU<br />

time.<br />

When looking at the percent increase in CPU cost, there can be a lot of deviation depending<br />

on a number of different factors, such as:<br />

► Type of workload<br />

– Online<br />

– Batch<br />

– DRDA transaction<br />

– Batch running in DRDA<br />

– Data warehouse<br />

► Characteristics of the workload<br />

– Static or dynamic<br />

– Fetch intensive<br />

– Update intensive<br />

– A combination of the two<br />

– Simple SQL<br />

– Complex query<br />

► Data sharing or a non-data sharing environment<br />

► JDBC or CLI ODBC<br />

► Utilities execution<br />

► Commit frequency and options<br />

There are actions that you can take to mitigate any CPU overhead and we discuss these<br />

actions in the book. One obvious task is to rebind all plans and packages after you migrate.<br />

Once you are in CM, if you rebind, <strong>DB2</strong> re-establishes fast column processing and your<br />

application also exploits more efficient access paths, already available under CM, that can<br />

possibly improve CPU costs.<br />

Once you are running in NFM, you can take advantage of more optimization enhancements<br />

after rebind.<br />

For more about new access paths, refer to Chapter 3, “SQL per<strong>for</strong>mance” on page 29.<br />

Another optional item of interest to reduce CPU time is the long term page fixing which can be<br />

specified at the buffer pool level; this feature can be enabled in compatibility mode. An<br />

Chapter 2. Per<strong>for</strong>mance overview 15


application that can have great potential benefit is one using a buffer pool with a poor read hit<br />

ratio and lots of I/O. Writes also benefit from page fixing.<br />

We explore this topic in more detail in Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on<br />

page 127.<br />

There are new functions in <strong>DB2</strong> V8 where we experienced a decrease in CPU cost. We use<br />

two new functions at the SQL level to minimize the CPU impact of migrating to <strong>DB2</strong> V8:<br />

Multi-row insert and multi-row fetch. These new functions require application changes, but<br />

can offset an increase in CPU cost of an insert intensive or fetch intensive application and are<br />

worth exploring <strong>for</strong> those applications that apply. You will find a discussion of multi-row insert<br />

and multi-row fetch in Chapter 3, “SQL per<strong>for</strong>mance” on page 29.<br />

For those applications that were are virtual storage-constrained with V7, there are a number<br />

of areas <strong>for</strong> possible CPU improvements. One is, if you are using data space buffer pools or<br />

hiperpools with V7, once you migrate to <strong>DB2</strong> V8, <strong>DB2</strong> replaces these pools with buffer pools<br />

residing above the 2 GB bar, and fewer instructions are needed <strong>for</strong> their management. If your<br />

system can use real storage <strong>for</strong> bigger buffer pools, I/O can be reduced and this results in<br />

CPU savings, especially <strong>for</strong> those applications using a lot of synchronous I/O <strong>for</strong> critical batch<br />

processes.<br />

If you are using DSNZPARMs MINSTOR and/or CONTSTOR to contract and minimize thread<br />

storage consumption, and thread storage consumption is not the major consumer below the 2<br />

GB DBM1 storage, you can reset them to free up much needed virtual storage <strong>for</strong> other use<br />

and gain back the CPU overhead of running these processes.<br />

You can find more in<strong>for</strong>mation on buffer pools, MINSTOR and CONTSTOR in Chapter 4,<br />

“<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

Warning: When doing per<strong>for</strong>mance measurements between different releases of <strong>DB2</strong>,<br />

make sure you take a look at the whole picture. An increase in class 2 CPU time may be<br />

offset by a reduction in SRB or TCB time in the <strong>DB2</strong> address spaces. We recommend you<br />

take both sets of numbers into account when doing comparisons since the CPU time may<br />

now be charged to the application owning TCB and less to one of the <strong>DB2</strong> address spaces.<br />

The in<strong>for</strong>mation needed to do a proper analysis would be spread across accounting and<br />

statistics reports.<br />

2.3 DBM1 virtual storage mapping<br />

The limitation of virtual storage in the DBM1 address space prior to V8 is a serious problem<br />

and one of the primary reasons customers cite as their motivation <strong>for</strong> moving to <strong>DB2</strong> V8.<br />

Virtual storage is not something you can buy; it is inherent in the software product’s<br />

architecture. Prior to <strong>DB2</strong> V8, the amount of virtual storage available is limited by the 31-bit<br />

addressing scheme which equates to an address space capable of addressing limited to 2<br />

GB.<br />

If you have been virtual storage-constrained, you have most likely done one or more of the<br />

following to get some storage relief:<br />

► Moved your virtual pools to data spaces<br />

► Used the data space extension of the EDM pool <strong>for</strong> the (global) dynamic statement cache<br />

► Used DSNZPARMs CONTSTOR and MINSTOR if using long running threads to minimize<br />

thread-related storage<br />

16 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► Reduced the number of objects using compression to minimize the number of<br />

compression dictionaries<br />

2.3.1 <strong>DB2</strong> structures above the bar<br />

In <strong>DB2</strong> V8 the data space buffer pool, data space lookaside pool, and hiper pools have been<br />

eliminated. Many elements have moved above the 2 GB bar, including the virtual buffer pools<br />

and their control blocks. Here are some areas now located above the 2 GB bar:<br />

► Buffer pools<br />

► Buffer pool control blocks<br />

► Compression dictionaries<br />

► EDM pool components <strong>for</strong> DBDs and dynamic statement cache<br />

► Sort pool<br />

► RID lists<br />

What does this mean <strong>for</strong> the application? You need to examine the extra storage gained and<br />

decide what to do with it. The application may improve with larger buffer pools and since<br />

these reside above the 2 GB bar, it may be the vehicle that reduces execution time to the<br />

application. Or you may decide to enlarge the EDM pool or Sort pool.<br />

If you were using the DSNZPARM CONTSTOR and MINSTOR to contract thread storage,<br />

and thread storage is not critical, you can now consider turning this off, eliminating the CPU<br />

overhead usage attributed to storage contraction.<br />

If you are a heavy user of compression, you benefit from making more storage available<br />

below the bar.<br />

2.3.2 What are the implications of more storage?<br />

2.4 Real storage<br />

Are you able to expand the number of active threads? It depends on the storage footprint <strong>for</strong><br />

threads. How many additional threads can be supported varies by workload and depends on<br />

various factors such as:<br />

► Duration of the thread<br />

► SQL workload<br />

► BIND parameters RELEASE<br />

If you have already exploited the virtual storage constraint relief recommendations above, the<br />

added benefit when you migrate to <strong>DB2</strong> V8 can possibly result in additional virtual storage<br />

relief. If you have not done anything, the added benefit should be higher. To summarize, this<br />

added virtual storage relief can help customers currently experiencing virtual storage<br />

constraint problems in <strong>DB2</strong> V7. But, if you are currently monitoring storage closely, then plan<br />

to continue monitoring in V8.<br />

If IRLM is a significant consumer of ECSA, you can consider decreasing ECSA, since the<br />

IRLM no longer has its locks in ECSA.<br />

A key message is you must have the real storage to fully back increased storage use;<br />

otherwise, you risk paging that adversely affects per<strong>for</strong>mance. Remember that expanded<br />

storage no longer exists in this environment, and there<strong>for</strong>e, any paging goes directly to disk;<br />

the effect can be immediately significant.<br />

Chapter 2. Per<strong>for</strong>mance overview 17


Because you can significantly increase the size of the buffer pools; theoretically, you can<br />

dramatically reduce the number of synchronous I/Os and there<strong>for</strong>e reduce the elapsed time<br />

<strong>for</strong> most transactions. This can significantly improve batch per<strong>for</strong>mance, especially <strong>for</strong> those<br />

workloads where the number of synchronous I/Os is high. As a result, <strong>DB2</strong> V8 can provide a<br />

good real memory versus I/O trade-off. However, you need to monitor real storage usage.<br />

In general, we have experienced an increase of up to 10-20% in real storage going to <strong>DB2</strong> V8<br />

when keeping constant all the possible real storage requirements. If you are close to fully<br />

exploiting your real storage, it is safer to verify the exact usage with RMF reports and<br />

review the virtual storage definitions, including the new default values, in order to contain the<br />

demand on real storage.<br />

2.5 Compatibility mode<br />

Once you migrate to CM, presumably there is no new V8 function available. Well, actually<br />

there is no new function that would preclude a fallback. But new function is introduced. There<br />

are several changes you have absolutely no control over that automatically occur behind the<br />

scenes. The list below, compiled during this project, gives you an idea of what is available, but<br />

by no means can be considered precise or constant, because it is subject to change with<br />

maintenance:<br />

► 64-bit addressing <strong>for</strong> DBM1 and IRLM address spaces<br />

► Increased number of deferred write, castout and global buffer pool write engines<br />

► EDM pool changes<br />

► Fast log apply default<br />

► Multi-row operations with DRDA<br />

► IRLM locks in private storage<br />

► Unicode parser<br />

► Most of the optimizer enhancements<br />

► Lock avoidance in singleton SELECT with CURRENT DATA YES<br />

► 180 CI limit removal <strong>for</strong> list prefetch and castout read<br />

► Ability to page fix buffer pools <strong>for</strong> long term<br />

► SMF 89 improvement<br />

► Data sharing IMMEDIATE WRITE default change<br />

► All the enhancements provided by utilities, except <strong>for</strong> BACKUP and RECOVER SYSTEM<br />

2.5.1 64-bit addressing<br />

These situations and their per<strong>for</strong>mance implications are discussed in this section.<br />

When you migrate to <strong>DB2</strong> V8 in CM, the DBM1 and IRLM address spaces immediately start<br />

to use 64-bit addressing. You no longer have the option to allow either address space to run<br />

using 31-bit addressing. Applications on the other hand happily run as be<strong>for</strong>e; there is<br />

absolutely no need to make changes to the application, unless of course, you want to take<br />

advantage of new features.<br />

Figure 2-1 shows the virtual storage layout <strong>for</strong> the different address spaces. Notice the IRLM<br />

and DBM1 address spaces use 64-bit virtual addressing, where DDF, MSTR, SPAS and the<br />

user-defined application program remain as be<strong>for</strong>e.<br />

Also, it is important to realize that the storage <strong>for</strong> 64-bit is not drawn to scale; the DBM1 and<br />

IRLM address space have a huge amount of virtual storage, 8 billion times the other address<br />

spaces.<br />

18 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


16 EB<br />

2 GB<br />

64-bit summary<br />

64-bit AS<br />

31-bit AS<br />

Figure 2-1 Virtual storage growth<br />

<strong>DB2</strong> code<br />

2.5.2 No more hiperpools and data spaces<br />

Buffer pool<br />

RID pool<br />

Sort pool<br />

BP ctl blks<br />

Compr dict<br />

Castout buf<br />

DBD, DSC<br />

<strong>DB2</strong> code<br />

Locks<br />

IRLM code<br />

<strong>DB2</strong> code<br />

User pgm/st proc MSTR DBM1 IRLM DDF<br />

In <strong>DB2</strong> V8 CM, there are no longer hiperpools and buffer pools in data spaces; if they existed<br />

prior to the migration, they automatically revert to buffer pools. <strong>DB2</strong> automatically reallocates<br />

the buffer pool sizes based on the original virtual buffer pools and the hiperpools or buffer<br />

pools in data spaces. For example, if BP4 consisted of 4,000 virtual buffer pool pages and<br />

20,000 hiperpool pages, then after the migration, BP4 contains 24,000 pages in a buffer pool.<br />

These buffer pools are automatically allocated and reside above the 2 GB bar. <strong>DB2</strong> no longer<br />

uses the terminology virtual pool and instead uses buffer pool. The total buffer pool storage<br />

must never exceed the real storage available <strong>for</strong> buffers. There are also reasonableness<br />

checks <strong>for</strong> 1 terabyte of storage <strong>for</strong> a single buffer pool and <strong>for</strong> the sum of all buffer pools. Not<br />

only do the buffer pools reside above the bar, but so do the corresponding buffer pool control<br />

blocks.<br />

Important: If you are using a large number of hiper pools with V7, review the buffer pool<br />

definitions be<strong>for</strong>e your <strong>DB2</strong> V8 migration. Make sure you have adequate real storage, and<br />

also adjust the thresholds of the new buffer pools, especially if they are not defined in<br />

percentages. When in doubt, use the V8 defaults.<br />

An important per<strong>for</strong>mance consideration here is to make sure you have enough real storage<br />

to back these entities. If you do not, you can encounter severe per<strong>for</strong>mance penalties <strong>for</strong><br />

paging; since expanded storage no longer exists, you page to DASD.<br />

One immediate benefit of having one type of buffer pool is simplification, and you also have<br />

immediate virtual storage constraint relief. This factor alone can move you toward increasing<br />

the number of threads, but since the thread-related storage stays below the bar, we do not<br />

recommend this type of change so soon after migrating to CM without verification.<br />

Chapter 2. Per<strong>for</strong>mance overview 19


The possible increase in thread footprint in migrating to V8 is currently estimated to be<br />

between 30% and 70%. This is based on the laboratory measurements thus far.<br />

For more in<strong>for</strong>mation on the buffer pools in <strong>DB2</strong> V8 and related per<strong>for</strong>mance implications,<br />

refer to Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

2.5.3 Increased number of deferred write, castout and GBP write engines<br />

As the storage constraints are lifted, the workload may increase. As a result, <strong>DB2</strong> increases<br />

the maximum number of deferred write, castout and GBP write engines from 300 to 600. This<br />

increase should alleviate engine not available conditions.<br />

For more in<strong>for</strong>mation on these write engines and their per<strong>for</strong>mance implications, refer to<br />

Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

2.5.4 EDM pool changes<br />

One of the largest virtual storage consumers is usually the EDM pool. With <strong>DB2</strong> V7 some<br />

virtual storage relief was provided by the capability to move part of the EDM pool to a data<br />

space. Further enhancements are provided by <strong>DB2</strong> V8.<br />

In this section we discuss:<br />

► Dynamic statement cache<br />

► DBD cache<br />

► Plans, packages and DBDs<br />

For more in<strong>for</strong>mation on the EDM pool and its per<strong>for</strong>mance implications, refer to Chapter 4,<br />

“<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

Dynamic statement cache<br />

In <strong>DB2</strong> V7 dynamic statements are cached in the dynamic statement cache only if the<br />

DSNZPARM CACHEDYN is turned on. In <strong>DB2</strong> V8 caching is enabled by default (new install)<br />

and the dynamic statement cache is moved above the 2 GB bar. This can provide additional<br />

storage relief to the DBM1 address space in case a data space was not used.<br />

DBD cache<br />

In addition, a new DBD cache is created <strong>for</strong> the storage of DBDs and also allocated above the<br />

2 GB bar. Segregating the DBDs from the EDM pool relieves contention from other objects in<br />

the EDM pool. <strong>DB2</strong> V8 can support more and larger DBDs adding to <strong>DB2</strong> V8’s scalability.<br />

Plans, packages, and DBDs<br />

Plans, packages, and DBDs are all stored in the directory. There is minimal per<strong>for</strong>mance<br />

overhead running in CM because <strong>DB2</strong> plans, packages, and DBDs are different between V7<br />

and V8. This overhead can be alleviated <strong>for</strong> plans and packages by rebinding them. We<br />

recommend rebinding anyway to take advantage of V8 access path improvements, avoid<br />

conversions and enable faster processing.<br />

Important: Rebind plans and packages once you are com<strong>for</strong>table with CM.<br />

If you can live with the overhead during CM and cannot rebind twice, then rebind once you<br />

are in NFM.<br />

20 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


2.5.5 Fast log apply<br />

Once you migrate to <strong>DB2</strong> V8 CM, the new default <strong>for</strong> fast log apply (FLA) is 100 MB. This<br />

should have a minimal effect on DBM1 storage. FLA is used by the RECOVER utility, during<br />

restart of a failed <strong>DB2</strong>, or when RESTORE SYSTEM is used. The storage is allocated when<br />

needed and released when the FLA phase is complete.<br />

When multiple RECOVER utility jobs are run in parallel, <strong>DB2</strong> can take advantage of FLA <strong>for</strong><br />

up to 10 concurrent jobs, each utilizing 10 MB.<br />

The default value <strong>for</strong> FLA at restart is always 100 MB, even if you explicitly specify 0 in the<br />

DSNTIPL panel or in the DSNZPARM LOGAPSTG.<br />

During RESTORE SYSTEM, a new utility with <strong>DB2</strong> V8, the default value <strong>for</strong> FLA (if<br />

LOGAPSTG is not zero) is 500 MB.<br />

For more in<strong>for</strong>mation on FLA and its per<strong>for</strong>mance implications, refer to Chapter 4, “<strong>DB2</strong><br />

subsystem per<strong>for</strong>mance” on page 127 and Chapter 5, “Availability and capacity<br />

enhancements” on page 217.<br />

2.5.6 Multi-row operations with DRDA<br />

2.5.7 IRLM V2.2<br />

<strong>DB2</strong> V8 CM automatically exploits multi-row fetch when you use a remote client that uses<br />

block-fetching in a distributed application. The DDF address space uses multi-row fetch to<br />

build the blocks of data to be sent to the client. This implies you do not have to change the<br />

application to take advantage of this tremendous per<strong>for</strong>mance enhancement. We have<br />

experienced per<strong>for</strong>mance improvements in these client applications in <strong>DB2</strong> V8 CM.<br />

For more in<strong>for</strong>mation on the multi-row fetch operations with DRDA, refer to Chapter 7,<br />

“Networking and e-business” on page 281.<br />

The IRLM address space also changes with <strong>DB2</strong> V8 and supports 64-bit virtual addressing.<br />

The IRLM is able to support more concurrent locks. PC=YES is now en<strong>for</strong>ced when you<br />

migrate to <strong>DB2</strong> V8. The ECSA usage (PC=NO) capability can still be specified, but is no<br />

longer used by V8. There<strong>for</strong>e, the ECSA previously used <strong>for</strong> IRLM, if you used PC=NO, could<br />

now be available <strong>for</strong> use by other applications.<br />

Important: If you used PC=NO, review your ECSA usage, since potentially there can be<br />

less of a need <strong>for</strong> ECSA with IRLM V2.2.<br />

Real storage <strong>for</strong> IRLM locks increases significantly, since they have doubled in size. For more<br />

in<strong>for</strong>mation on the IRLM in 64-bit mode, refer to Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on<br />

page 127.<br />

2.5.8 Page-fixed buffer pools<br />

<strong>DB2</strong> V8 introduces a new buffer pool parameter called PGFIX which allows you to choose to<br />

fix buffer pools in real storage. Be<strong>for</strong>e reading or writing a page, <strong>DB2</strong> must fix the page in real<br />

storage in order to per<strong>for</strong>m the I/O. In <strong>DB2</strong> V8, with this new buffer pool option, you can<br />

decide to permanently page fix an entire buffer pool. The option to page fix a buffer pool is<br />

available in CM, but is not automatically enabled.<br />

Chapter 2. Per<strong>for</strong>mance overview 21


2.5.9 Unicode parser<br />

Important: Consider setting the page fixing option <strong>for</strong> buffer pools with a poor read hit ratio<br />

and lots of I/O. Balance this setting against the need <strong>for</strong> real storage in the rest of the<br />

system.<br />

For more in<strong>for</strong>mation on page fixing and its per<strong>for</strong>mance implications, refer to Chapter 4,<br />

“<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

<strong>DB2</strong> must convert all SQL to Unicode since all SQL statements are now parsed in Unicode<br />

UTF-8 <strong>for</strong>mat. This conversion is generally per<strong>for</strong>med by <strong>DB2</strong> invoking z/<strong>OS</strong> Conversion<br />

Services. In addition, the EBCDIC metadata stored in the catalog is converted to Unicode in<br />

CM. After you enable NFM, the metadata is stored in Unicode and the conversion is not<br />

necessary.<br />

If you are using an SBCS code page, the conversion is done directly by <strong>DB2</strong>. If you have a<br />

more complicated code page, then <strong>DB2</strong> invokes z/<strong>OS</strong> Conversion Services.<br />

For more in<strong>for</strong>mation on the Unicode parser and its per<strong>for</strong>mance implications, refer to<br />

Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on page 127.<br />

2.5.10 Optimizer enhancements<br />

Once you migrate to <strong>DB2</strong> V8 CM, you can choose to rebind your application plans and<br />

packages to possibly get improvements based on the optimizer enhancements to access<br />

paths. For example, fast column processing is re-enabled if you rebind, and your application<br />

can take advantage of the new stage 1 and indexable predicates.<br />

For more in<strong>for</strong>mation on application rebinds, refer to Chapter 4, “<strong>DB2</strong> subsystem<br />

per<strong>for</strong>mance” on page 127.<br />

2.5.11 CF request batching<br />

A new function in z/<strong>OS</strong> V1.4 and CF level 12, called CF request batching, is the ability to allow<br />

multiple pages to be registered to the CF with a single operation. <strong>DB2</strong> V8 takes advantage of<br />

this feature in <strong>DB2</strong> V8 during the actions of registering and writing multiple pages to a GBP<br />

and reading multiple pages from a GBP during castout processing. This new feature really<br />

allows <strong>for</strong> more efficient traffic across the links to and from the CF, and can result in a<br />

reduction of CF processing times and costs associated with data sharing <strong>for</strong> some workloads.<br />

For more in<strong>for</strong>mation on CF request batching, refer to Chapter 8, “Data sharing<br />

enhancements” on page 319.<br />

2.6 New-function mode<br />

The per<strong>for</strong>mance comparisons are generally dependent on the particular workload.<br />

Preliminary measurements in non-data sharing and non-DRDA environments indicate no<br />

significant difference in CPU time overhead in CM versus NFM.<br />

However, in data sharing, the story is much improved. If you are interested in the per<strong>for</strong>mance<br />

impact of a <strong>DB2</strong> V7 application migrated to V8 without any application change and significant<br />

configuration change, there can be a noticeable reduction in V8 overhead going from CM to<br />

22 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


NFM in data sharing because some data sharing-related enhancements are automatically<br />

taken advantage of in NFM. Most of the improvement can be attributed to the new locking<br />

protocol level 2. For more in<strong>for</strong>mation on improvements in NFM <strong>for</strong> data sharing<br />

environments, see Chapter 8, “Data sharing enhancements” on page 319.<br />

The real per<strong>for</strong>mance difference in NFM comes from the ability to exploit new functions not<br />

available in CM, <strong>for</strong> example, materialized query tables.<br />

2.6.1 Plans and packages<br />

2.6.2 <strong>DB2</strong> catalog<br />

There is overhead in NFM <strong>for</strong> plans, packages, and DBDs. The representations of these<br />

objects are different between <strong>DB2</strong> V7 and V8. The costs come from having to re<strong>for</strong>mat control<br />

structures to match the release and in converting between EBCDIC and Unicode.<br />

Once you are in NFM, <strong>DB2</strong> BIND and REBIND write plans and packages to the <strong>DB2</strong> catalog<br />

and directory in Unicode.<br />

Whenever <strong>DB2</strong> accesses plans, packages, or DBDs that are not in <strong>DB2</strong> V8 <strong>for</strong>mat, <strong>DB2</strong> must<br />

expend some extra CPU to convert them into <strong>DB2</strong> V8 <strong>for</strong>mat. This is always true in CM, but<br />

continues to be true even in NFM. In order <strong>for</strong> the plan or package to reside in the catalog in<br />

<strong>DB2</strong> V8 <strong>for</strong>mat, but most important, to enable all <strong>DB2</strong> functions, you just do a rebind or a bind.<br />

Important: To get around any re<strong>for</strong>matting costs and enable <strong>DB2</strong> V8 functions (such as<br />

NOT PADDED and index only access, the additional ability to use indexes, MQTs, IS NOT<br />

DISTINCT, and more), rebind your plans and packages in V8 NFM.<br />

When you migrate to NFM, the catalog changes from EBCDIC to Unicode. The conversions<br />

happen in ENFM, and it is an important difference <strong>for</strong> a few customers. A few customers stay<br />

in ENFM, even though all catalog tables are in Unicode. Some may fall back from NFM to<br />

ENFM. The other significant difference is the capability of running during ENFM.<br />

Important: Once you are in NFM, the collating sequence of the <strong>DB2</strong> catalog changes<br />

since the catalog is now converted to Unicode. You may get different results when using<br />

range predicates against the <strong>DB2</strong> catalog.<br />

Other incompatibilities are described in the Premigration activities section of the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong><br />

z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide, GC18-7418-02.<br />

For instance, In NFM, an identifier that was valid in <strong>DB2</strong> V7 might be flagged as too long in<br />

<strong>DB2</strong> V8 and you receive message DSNH107I (during precompilation) or SQLCODE -107<br />

(otherwise).<br />

The first 128 code points of Unicode match the ASCII code page, so the ordering is different<br />

when you use an ORDER BY in an SELECT against the catalog.<br />

2.6.3 Precompiler NEWFUN option<br />

Whenever a plan or package, whose last BIND was prior to <strong>DB2</strong> V8 NFM, is rebound, <strong>DB2</strong><br />

converts the EBCDIC to Unicode be<strong>for</strong>e proceeding. This is always true in CM, and continues<br />

to be true even in NFM. To alleviate this cost, the plan or package must be bound with a<br />

DBRM produced by the precompiler using NEWFUN(YES). The default <strong>for</strong> NEWFUN<br />

switches to YES from NO <strong>for</strong> the precompiler once you switch to NFM.<br />

Chapter 2. Per<strong>for</strong>mance overview 23


You can keep the DBRMs in EBCDIC <strong>for</strong>mat if you use NEWFUN(NO), but you cannot use<br />

any new functions.<br />

2.6.4 SUBSTRING function<br />

Once you go into ENFM and beyond, you can use the new V8 SUBSTRING built-in function,<br />

which is character-based. The old V7 SUBSTR function continues to be byte-based. <strong>DB2</strong> V8,<br />

with APAR PQ88784, introduces a number of new “character-based” functions rather than the<br />

older “byte-based” functions. Some code pages have special characters that can now result in<br />

more than one byte in Unicode, so you may get different results using SUBSTRING. Make<br />

sure you use the right substring function to get the correct results.<br />

Several new functions are added and several existing functions are enhanced to allow the<br />

processing of character data in more of a "character-based" than "byte-based" manner. The<br />

new functions are:<br />

► CHARACTER_LENGTH<br />

► P<strong>OS</strong>ITION<br />

► SUBSTRING<br />

The changed functions are:<br />

► CHAR<br />

► CLOB<br />

► DBCLOB<br />

► GRAPHIC<br />

► INSERT<br />

► LEFT<br />

► LOCATE<br />

► RIGHT<br />

► VARCHAR<br />

► VARGRAPHIC<br />

The new and changed functions allow you to specify the code unit in which the strings should<br />

be processed. That is, CODEUNITS determines how to interpret a character string.<br />

2.7 New installation default values<br />

In this section, we list the changes that have taken place to the default values of several buffer<br />

pool threshold settings in <strong>DB2</strong> V8. These new values are the result of system per<strong>for</strong>mance<br />

tuning work done by the <strong>DB2</strong> Development Per<strong>for</strong>mance Department in SVL, and<br />

considerations related to a more general applicability of those values. They are applied to<br />

your system if you are doing a new install of <strong>DB2</strong> and select not to specify the values yourself.<br />

If you are migrating to V8, and your parameter values are specified as the old defaults, then<br />

you should consider changing to the new values <strong>for</strong> improved per<strong>for</strong>mance and availability,<br />

particularly CACHEDYN and CHKFREQ.<br />

We also list the new DSNZPARM default values. These are changes to the defaults in the<br />

installation CLIST <strong>for</strong> <strong>DB2</strong> V8 which affect your definitions if you are just letting the panels<br />

assume defaults. If this is the case, and you want to compare per<strong>for</strong>mance across V7 and V8<br />

in compatibility mode, you might want to review the new values and set them back to the old<br />

defaults, at least <strong>for</strong> the initial period.<br />

24 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


New buffer pool threshold values<br />

For the ALTER BUFFERPOOL statement, the initial default <strong>for</strong> the deferred write thresholds<br />

are:<br />

► DWQT — buffer pool deferred write threshold as a percentage of the total virtual pool size.<br />

The new value is 30%. The default is decreased from the old value of 50%.<br />

► VDWQT — buffer pool vertical deferred write threshold as a percentage of the total virtual<br />

pool size.<br />

The new value is 5%. The default is decreased from the old value of 10%.<br />

For the ALTER GROUPBUFFERPOOL statement the initial default <strong>for</strong> the deferred write<br />

thresholds are:<br />

► CLASST — threshold <strong>for</strong> the class castout to disk as a percentage of the size of the data<br />

entries in the group pool.<br />

The new value is 30%. The default is decreased from the old value of 50%.<br />

► GBPOOLT — threshold <strong>for</strong> the class castout as a percentage of the size percentage of the<br />

total virtual pool size.<br />

The new value is 5%. The default is decreased from the old value of 10%.<br />

► GBPCHKPT — default <strong>for</strong> the GBP checkpoint interval in minutes.<br />

The new value is 4 minutes. The default is decreased from the old value of 8 minutes.<br />

Changes to default parameter values<br />

Table 2-1 summarizes the old and new DSNZPARM default values, sorted by PANEL ID.<br />

Table 2-1 Changed DSNZPARM default settings<br />

Macro Parameter Old value New value Panel Description<br />

DSN6FAC TCPKPALV ENABLE 120 sec. DSNTIP5 TCP/IP keepalive<br />

DSN6SYSP LOBVALA 2048 KB 10240 KB DSNTIP7 Storage value by user<br />

DSN6SPRM CACHEDYN NO YES DSNTIP8 Cache <strong>for</strong> dynamic SQL<br />

DSN6ARV BLKSIZE 28672 24576 DSNTIPA Archive log block size<br />

DSN6FAC IDTHTOIN 0 120 DSNTIPB Idle thread timeout<br />

DSN6SPRC SPRMINT 180 120 DSNTIPC DDF idle thread interval time out<br />

DSN6SPRM EDMDBDC N/A 102400 KB DSNTIPC EDM DBD cache<br />

DSN6SPRM EDMPOOL 7312 KB 32768 KB DSNTIPC EDM pool size<br />

DSN6SPRM EDMSTMTC N/A 102400 KB DSNTIPC EDM statement cache<br />

DSN6SYSP CONDBAT 64 10000 DSNTIPE Max number of remote connected<br />

users<br />

DSN6SYSP CTHREAD 70 200 DSNTIPE Max number of users<br />

DSN6SYSP IDBACK 20 50 DSNTIPE Max number of batch connections<br />

DSN6SYSP IDFORE 40 50 DSNTIPE Max number of TSO connections<br />

DSN6SYSP MAXDBAT 64 200 DSNTIPE Max number of remote active<br />

users<br />

Chapter 2. Per<strong>for</strong>mance overview 25


Macro Parameter Old value New value Panel Description<br />

DSN6SYSP CHKFREQ 50000 500000 DSNTIPL Checkpoint log records frequency<br />

DSN6SYSP SYSPLOGD NO 5 DSNTIPL BACKODUR multiplier<br />

DSN6SYSP ACCUMACC N/A 10 DSNTIPN New with V8<br />

Accounting accumulation <strong>for</strong> DDF<br />

DSN6SYSP SMFSTST YES(1,3,4,5) YES(1,3,4,5,6) DSNTIPN SMF classes <strong>for</strong> STATISTICS<br />

DSN6SPRM AUTHCACH 1024 3072 DSNTIPP Cache <strong>for</strong> plan authorization<br />

DSN6SYSP LOGAPSTG 0 100 MB DSNTIPL Storage <strong>for</strong> log apply<br />

DSN6FAC CMTSTAT ACTIVE INACTIVE DSNTIPR DDF threads<br />

DSN6SPRM DSMAX 3000 10000 DSNTIPR Maximum open data sets<br />

DSN6SYSP EXTSEQ NO YES DSNTIPR Extended security<br />

N/A Function not available in <strong>DB2</strong> V7.<br />

2.8 Recent z/<strong>OS</strong> releases<br />

<strong>DB2</strong>’s growing synergy with z/<strong>OS</strong> continues and <strong>DB2</strong> V8 is no exception. New z/<strong>OS</strong> versions<br />

provide additional functionality and per<strong>for</strong>mance improvements. The table below illustrates<br />

some of the new features and improvements made to z/<strong>OS</strong> as it pertains to <strong>DB2</strong>.<br />

Table 2-2 z/<strong>OS</strong> release functionality<br />

z/<strong>OS</strong><br />

version<br />

Functionality<br />

1.3 Minimum required level <strong>for</strong> <strong>DB2</strong> V8.<br />

Ongoing support <strong>for</strong> 64-bit virtual addressing<br />

Interface to RMF monitor III <strong>for</strong> obtaining per<strong>for</strong>mance data on capacity consumption<br />

End of service March 31, 2005<br />

1.4 z990 compatibility<br />

CF request batching<br />

WLM-managed batch initiator enhancements<br />

z/<strong>OS</strong> Conversion Services enhancements<br />

Support of Debug Tool <strong>for</strong> <strong>DB2</strong> stored procedures<br />

RACROUTE REQUEST=VERIFY abends allow <strong>DB2</strong> applications to tell RACF® to<br />

issue a return and reason code instead of an abend <strong>for</strong> certain types of situations<br />

1.5 64-bit virtual storage enhancements<br />

Multilevel security<br />

Improved backup and recovery of <strong>DB2</strong> data<br />

Improved per<strong>for</strong>mance <strong>for</strong> DFSORT<br />

Extended self-optimization of WebSphere applications<br />

WLM virtual 64-bit support<br />

SMF buffer constraint relief<br />

I/O management enhancements<br />

Number of open data sets increased<br />

<strong>DB2</strong> nested stored procedures WLM enhancement<br />

Scrollable and multiline panel fields in ISPF<br />

Sysplex per<strong>for</strong>mance enhancements<br />

High level assembler V1R5<br />

RACF <strong>DB2</strong> V8 support<br />

26 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


z/<strong>OS</strong><br />

version<br />

2.8.1 Multilevel security<br />

Functionality<br />

1.6 64-bit virtual storage enhancements<br />

WLM virtual 64-bit support<br />

Support <strong>for</strong> zSeries application assist processor<br />

Requires a zSeries server (z800, z890, z900, z990)<br />

Increased scale up to 24 engines in a single z/<strong>OS</strong> image<br />

Improved availability of TCP/IP networks across a sysplex<br />

Sysplex per<strong>for</strong>mance enhancements<br />

Sysplex autonomics - automated recovery enhancements<br />

Improved multilevel security<br />

1.7 Security Server (RACF) improvements: Support is planned <strong>for</strong> mixed-case passwords.<br />

Scalability enhancements to include:<br />

► Sequential and EXCP data sets larger than 64K tracks, in addition to existing<br />

support <strong>for</strong> extended <strong>for</strong>mat sequential data sets larger than 64K tracks.<br />

► More than 255 extents per VSAM component.<br />

► XRC and Geographically Dispersed Parallel Sysplex (GDPS®) to allow log data<br />

managed by the System Logger to be replicated to a remote location.<br />

z/<strong>OS</strong> V1.5 adds (and z/<strong>OS</strong> V1.6 improves) support <strong>for</strong> multilevel security on the zSeries.<br />

Many organizations such as government agencies and financial institutions have stringent<br />

security requirements and only allow access to in<strong>for</strong>mation based on the person’s need to<br />

know, or clearance level. Multilevel security is designed to prevent individuals from accessing<br />

unauthorized in<strong>for</strong>mation and declassifying in<strong>for</strong>mation. <strong>DB2</strong> V8 is the first version of <strong>DB2</strong><br />

that supports multilevel security.<br />

For more in<strong>for</strong>mation on multilevel security, see Chapter 4, “<strong>DB2</strong> subsystem per<strong>for</strong>mance” on<br />

page 127 and the recent book, z/<strong>OS</strong> Multilevel Security and <strong>DB2</strong> Row-level Security<br />

Revealed, SG24-6480.<br />

2.8.2 DFSMShsm Fast Replication<br />

The DFSMShsm Fast Replication in z/<strong>OS</strong> 1.5 also provides a fast, easy to use backup and<br />

recovery solution specifically designed <strong>for</strong> <strong>DB2</strong> V8. It is designed to allow fast, non-disruptive<br />

backups to be taken at appropriate events when there is minimum activity at the application<br />

level or when a fast point-in-time backup is desired. See 5.1, “System level point-in-time<br />

recovery” on page 218, and the book Disaster Recovery with <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-6370.<br />

Chapter 2. Per<strong>for</strong>mance overview 27


28 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 3. SQL per<strong>for</strong>mance<br />

3<br />

In this chapter we discuss the major per<strong>for</strong>mance enhancements that affect SQL. The chapter<br />

contains the following sections:<br />

► Multi-row FETCH, INSERT, cursor UPDATE and DELETE<br />

Multi-row operations can be executed in a single SQL statement explicitly to process a<br />

rowset. It is used implicitly by default in the distributed environment as described in<br />

Chapter 7, “Networking and e-business” on page 281. The DSNTEP4 sample is similar to<br />

DSNTEP2 and exploits multi-row fetch as described in Chapter 9, “Installation and<br />

migration” on page 341.<br />

► Materialized query table<br />

Materialized query tables (MQT) can be created in NFM as a pre-computed join, sort or<br />

aggregation and re-used by <strong>DB2</strong> query rewrite in dynamic SQL to improve the execution<br />

of long running queries in the Data Warehouse type environment.<br />

► Star join processing enhancements<br />

The execution of star join is improved by: Access path enhancements, better estimates of<br />

the filtering effect of dimensions, the use of sparse index in cache, and the use of<br />

in-memory work file.<br />

► Stage 1 and indexable predicates<br />

The predicates comparing mismatched string data types or comparing mismatched<br />

numeric data types that are Stage 2 in <strong>DB2</strong> V7 can become Stage 1 and indexable in <strong>DB2</strong><br />

<strong>Version</strong> 8. This benefit can be obtained by rebinding the plan or package.<br />

► Multi-predicate access path enhancement<br />

Queries which contain two or more predicates referencing a table may get a better access<br />

path with statistics <strong>for</strong> a group of columns (non-indexed) collected by RUNSTATS.<br />

► Multi-column sort merge join<br />

Access path selection allows multi-column predicates <strong>for</strong> sort merge join (SMJ) with<br />

mismatched string data types; decides to sort new table based on cost and enables query<br />

parallelism <strong>for</strong> multi-column sort merge join (MCSMJ).<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 29


► Parallel sort enhancement<br />

Parallel sort is enabled <strong>for</strong> multiple-table sort (not restricted <strong>for</strong> single-table sort) <strong>for</strong> long<br />

running queries resulting in reduction of elapsed time. Parallel sort may need bigger work<br />

file buffer pool size, more work file or use Parallel Access Volume.<br />

► Table UDF improvement<br />

<strong>DB2</strong> allows you to specify the cardinality option when you reference a user-defined table<br />

function in an SQL statement. With this option, users have the capability to better tune the<br />

per<strong>for</strong>mance of queries that contain user-defined table functions.<br />

► ORDER BY in SELECT INTO with FETCH FIRST N ROWS<br />

It enables SELECT INTO to get the top rows based on a user-specified ordering, thereby<br />

reducing the need <strong>for</strong> a number of FETCHes.<br />

► Trigger enhancements<br />

This enhancement saves work file allocation if WHEN condition evaluates to false or<br />

transition file fits into working storage. This avoids work file creation at each trigger<br />

invocation.<br />

► REXX support improvements<br />

The per<strong>for</strong>mance of REXX programs accessing <strong>DB2</strong> tables is improved in <strong>DB2</strong> V8 if the<br />

program issues large numbers of SQL statements by avoiding loading DSNREXX at each<br />

REXX API invocation and optimizing REXX API initialization.<br />

► Dynamic scrollable cursors<br />

Dynamic scrollable cursor is a new option which allows the application to see the<br />

updated/inserted rows and goes against the base table. It does not create the temporary<br />

table needed <strong>for</strong> static scrollable cursors.<br />

► Backward index scan<br />

Potential per<strong>for</strong>mance enhancements through better access paths and potentially fewer<br />

required indexes.<br />

► Multiple distinct<br />

With <strong>DB2</strong> V7 only one DISTINCT keyword per SELECT/HAVING clause is allowed. If we<br />

need to aggregate (COUNT, SUM) by distinct values in more than one column, we must<br />

submit multiple queries. With <strong>DB2</strong> V8, a query with multiple DISTINCTs reduces CPU and<br />

elapsed time when compared to the time necessary in <strong>DB2</strong> V7 to execute multiple<br />

queries.<br />

► Visual Explain<br />

We provide an overview of the new Visual Explain and show examples of using the new<br />

Statistic Advisor function. Visual Explain was rewritten to provide better, faster analysis of<br />

problem queries. It provides much more detailed in<strong>for</strong>mation about the access path. It<br />

<strong>for</strong>mats the in<strong>for</strong>mation into an XML document which can be sent to the lab <strong>for</strong> analysis.<br />

The EXPLAIN tables have been enhanced <strong>for</strong> <strong>DB2</strong> V8, and a summary of these changes<br />

is provided in Appendix D, “EXPLAIN and its tables” on page 407.<br />

30 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


3.1 Multi-row FETCH, INSERT, cursor UPDATE and DELETE<br />

When using multi-row fetch operations, available in NFM, you normally fetch a set of rows, or<br />

a rowset in a single fetch operation, as shown here in the case of 10 rows:<br />

FETCH NEXT ROWSET FROM my-cursor FOR 10 ROWS INTO :hva1, :hva2, :hva3<br />

Figure 3-1 shows the advantage of dealing with rowsets.<br />

SQL<br />

Declare<br />

Cursor<br />

Open<br />

Cursor<br />

Fetches<br />

Close<br />

Cursor<br />

Commit<br />

Single-row Fetch vs. Multi-row Fetch<br />

APPL DBM1 MSTR IRLM<br />

SQL<br />

Declare<br />

Cursor<br />

Open<br />

Cursor<br />

Fetches<br />

Close<br />

Cursor<br />

Commit<br />

Figure 3-1 Multi-row fetch reduces the trips across the API<br />

APPL DBM1 MSTR IRLM<br />

Since <strong>DB2</strong> now fetches 10 rows in a single Application Program Interface (API) crossing<br />

(going from the application to <strong>DB2</strong> and back), instead of 10 API crossings, one <strong>for</strong> each row<br />

fetched without rowsets, multi-row fetch reduces the multiple trips between the application<br />

and the database engine. This reduction produces even more benefits in distributed<br />

applications, see 7.2, “Multi-row FETCH and INSERT in DRDA” on page 285.<br />

Characteristics of multi-row fetch:<br />

► Multi-row fetch eliminates multiple trips between the application and the database engine<br />

► Multi-row fetch enhances the usability and power of SQL<br />

► A single fetch statement using multi-row fetch can retrieve multiple rows of data from the<br />

result table of a query as a rowset<br />

► Rowset is the set of rows that is retrieved through a multi-row fetch<br />

Characteristics of a rowset cursor:<br />

► A rowset cursor is a cursor which returns one or more rows <strong>for</strong> a single fetch statement<br />

► Each row in a rowset can be referenced in subsequent cursor-positioned UPDATE and<br />

DELETE statements<br />

Chapter 3. SQL per<strong>for</strong>mance 31


Characteristics of the host variable array (HVA):<br />

► The HVA is an array in which each element of the array contains a value <strong>for</strong> the same<br />

column (one HVA per column)<br />

► The HVA can only be referenced in multi-row FETCH or INSERT<br />

► The HVA is used to receive multiple values <strong>for</strong> a column on FETCH, or to provide multiple<br />

values <strong>for</strong> a column on INSERT<br />

► The HVA is supported in COBOL, PL/1, C and C++<br />

3.1.1 Example of usage of multi-row fetch in PL/I<br />

Figure 3-2 shows the declaration of Host Variable Arrays, the declaration of the cursor with<br />

rowset positioning, open cursor and fetch of a rowset of 10 rows in a single SQL statement.<br />

Declare HVAs with 10 elements <strong>for</strong> each column<br />

DCL COL1(10) CHAR(8);<br />

Each element of the H<strong>OS</strong>T VARIABLE ARRAY<br />

contains a value <strong>for</strong> the same column<br />

DCL COL2(10) CHAR(8);<br />

DCL COL3(10) BIN FIXED(31);<br />

Declare a CURSOR C1 and fetch 10 rows using a Multi-row FETCH<br />

EXEC SQL<br />

DECLARE C1 CURSOR WITH ROWSET P<strong>OS</strong>ITIONING FOR<br />

SELECT * FROM TABLE1;<br />

WITH ROWSET P<strong>OS</strong>ITIONING specifies<br />

whether multiple rows of data can be accessed<br />

EXEC SQL OPEN C1;<br />

as a rowset on a single FETCH statement<br />

EXEC SQL<br />

FETCH NEXT ROWSET FROM C1 FOR 10 ROWS<br />

INTO :COL1, :COL2, :COL3; The size of the rowset is not specified on the<br />

DECLARE CURSOR statement, it is done at<br />

.....<br />

FETCH time<br />

Figure 3-2 Usage of multi-row fetch<br />

3.1.2 Example of usage of multi-row insert in PL/I<br />

Example 3-1 shows the statement to insert a rowset of 10 rows into a table with a single SQL<br />

statement.<br />

Example 3-1 Insert 10 rows using host variable arrays <strong>for</strong> column values<br />

EXEC SQL<br />

INSERT INTO TABLE2<br />

VALUES ( :COL1, :COL2, :COL3)<br />

FOR 10 ROWS ;<br />

.....<br />

When we increase the number of rows processed per multi-row fetch or insert, the size of the<br />

host variable array is increased in the application program and it is processed row by row in<br />

<strong>DB2</strong>.<br />

32 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


In an application, multi-row inserts, positioned updates, and positioned deletes have the<br />

potential of expanding the unit of work, <strong>for</strong> instance by deleting a rowset. This can affect the<br />

concurrency of other users accessing the data. Minimize contention by adjusting the size of<br />

the host variable array, committing between inserts, updates, and preventing lock escalation.<br />

GET DIAGN<strong>OS</strong>TICS can be used in conjunction with and instead of the SQLCA to interrogate<br />

the results of all SQL statements. It is especially important when dealing with non-atomic<br />

multi-row insert statements, and objects with long names, which potentially no longer fit into<br />

the SQLCA message area. See <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SQL Reference, SC18-7426-01<br />

<strong>for</strong> details.<br />

3.1.3 Multi-row fetch/update and multi-row fetch/delete in local applications<br />

When the cursor is positioned on a rowset, the rows belonging to the rowset can be updated<br />

or deleted:<br />

► Multi-row FETCH/UPDATE<br />

– Positioned UPDATE of multi-row FETCH<br />

– The rows of the current rowset are updated if the cursor is positioned on a rowset<br />

► Multi-row FETCH/DELETE<br />

– Positioned DELETE of multi-row FETCH<br />

– The rows of the current rowset are deleted if the cursor is positioned on a rowset<br />

If cursor CS1 is positioned on a rowset consisting of 10 rows of a table and we want to delete<br />

the fourth row of the rowset:<br />

EXEC SQL DELETE FROM T1 WHERE CURRENT OF CS1 FOR ROW 4 OF ROWSET;<br />

The same is applicable to UPDATE.<br />

Example of usage of multi-row fetch/update and fetch/delete in PL/I<br />

The example in Figure 3-3 shows the statements to update and delete rowsets of 10 rows<br />

from a table positioned by a rowset cursor.<br />

Chapter 3. SQL per<strong>for</strong>mance 33


3.1.4 Per<strong>for</strong>mance<br />

Update 10 rows using a positioned Multi-row FETCH/UPDATE<br />

on a rowset cursor<br />

EXEC SQL<br />

UPDATE TABLE1<br />

SET COL3=COL3+1<br />

WHERE CURRENT OF C1;<br />

Delete 10 rows using a positioned Multi-row FETCH/DELETE<br />

EXEC SQL<br />

DELETE FROM TABLE1<br />

WHERE CURRENT OF C1;<br />

Figure 3-3 Example of multi-row cursor update and delete<br />

To update in SQL, if only the nth row in the rowset instead of the whole rowset needs to be<br />

updated, which might be more common, you specify ‘FOR ROW n OF ROWSET’, as shown<br />

here:<br />

EXEC SQL<br />

UPDATE TABLE1<br />

SET COL3=COL3+1<br />

WHERE CURRENT OF C1 FOR ROW n OF ROWSET;<br />

All constraint checks are effectively made at the end of the statement. In the case of a<br />

multi-row update, this validation occurs after all the rows are updated. The only place it can be<br />

different is in AFTER UPDATE FOR EACH ROW triggers that have an external action. In all<br />

other cases, the whole UPDATE is an atomic operation. Either all changes are made or no<br />

changes are made.<br />

In this section we discuss the environment and measurements related to multi-row operations<br />

when executed locally.<br />

Per<strong>for</strong>mance measurement scenario<br />

► Configuration<br />

– <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 and V7<br />

– z/<strong>OS</strong> Release 1.4.0<br />

– 2-way processors 2084 z990<br />

– ESS 800 DASD with FICON® channels<br />

– Non-data sharing<br />

► Non-partitioned table space, 100,000 rows table, 26 columns, 1 index<br />

34 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► Static SQL with table space scan<br />

► Fetch, insert, fetch/update and fetch/delete, each <strong>for</strong> a total of 100k rows<br />

– V7 and V8 single row<br />

– V8 multi-row (explicit)<br />

Multi-row fetch per<strong>for</strong>mance<br />

Figure 3-4 shows the CPU time (class 1) measurement <strong>for</strong> single-row fetch and multi-row<br />

fetch <strong>for</strong> all 100,000 rows from a non-partitioned table space. For the multi-row fetch cases we<br />

fetch the 100k rows varying the rowset from 2, 10, 100, 1k, and 10k rows.<br />

Class 1 CPU Time (Sec) 2-way 2084<br />

1.5<br />

1<br />

0.5<br />

0<br />

1.09<br />

Multi-row Fetch Per<strong>for</strong>mance<br />

(100,000 rows Fetched / test)<br />

Single-row V8 multi-row<br />

1.15<br />

Figure 3-4 CPU time (class 1) <strong>for</strong> single-row and multi-row fetch<br />

1.02<br />

V7 V8 50kx2 10kx10 1kx100 100x1k 10x10k<br />

V8 with explicit multi-row Fetch<br />

These measurements show:<br />

► For single-row fetch there is a 5% increase in CPU time when we compare the<br />

measurements in V7 to V8. This increase is primarily due to the overhead when operating<br />

in 64-bit addressing as compared to 31-bit addressing and normal release to release<br />

overhead.<br />

► 40% CPU time improvement with MR=10 rows<br />

► 50% CPU time improvement with MR=100+ rows<br />

The per<strong>for</strong>mance improvement using multi-row fetch in general depends on:<br />

► Number of rows fetched in one fetch<br />

► Number of columns fetched (more improvement with fewer columns), data type and size of<br />

the columns<br />

0.64<br />

50kx2 - 50,000 fetch loops, 2 rows per multi-row fetch<br />

10kx10 - 10,000 fetch loops, 10 rows per multi-row fetch<br />

1kx100 - 1,000 fetch loops, 100 rows per multi-row fetch<br />

100x1k - 100 fetch loops, 1,000 rows per multi-row fetch<br />

10x10k - 10 fetch loops, 10,000 rows per multi-row fetch<br />

0.55<br />

0.54<br />

0.54<br />

Chapter 3. SQL per<strong>for</strong>mance 35


► Complexity of the fetch. The fixed overhead saved <strong>for</strong> not having to go between the<br />

database engine and the application program has a lower percentage impact <strong>for</strong> complex<br />

SQL that has longer path lengths.<br />

If the multi-row fetch reads more rows per statement, it results in CPU time improvement, but<br />

after 10 to 100 rows per multi-row fetch, the benefit is decreased. The benefit decreases<br />

because, if the cost of one API overhead per row is 100% in a single row statement, it gets<br />

divided by the number of rows processed in one SQL statement. So it becomes 10% with 10<br />

rows, 1% with 100 rows, 0.1% <strong>for</strong> 1000 rows, and then the benefit becomes negligible.<br />

It turns out that the percentage improvement is larger when class 2 accounting is turned on,<br />

because the cost of class 2 accounting which was encountered <strong>for</strong> each row fetched now is<br />

encountered only <strong>for</strong> each multi-row fetch SQL statement. So the cost of class 2 accounting<br />

would be dramatically reduced, <strong>for</strong> example, 100 times if fetching 100 rows in one multi-row<br />

fetch SQL statement.<br />

Multi-row insert per<strong>for</strong>mance<br />

Figure 3-5 shows the CPU time (class 1) measurements <strong>for</strong> single-row insert and multi-row<br />

insert of 100,000 rows into a non-partitioned table space.<br />

Class 1 CPU Time (Sec)<br />

4<br />

3<br />

2<br />

1<br />

0<br />

Figure 3-5 CPU time (class 1) <strong>for</strong> single-row and multi-row insert<br />

The measurements, compared to V7, show:<br />

► For single-row fetch there is a reduction in CPU time when we compare the<br />

measurements in V7 and V8 and insert requests.<br />

► 35% CPU time improvement with MR=10 rows<br />

► 40% CPU time improvement with MR=100+ rows<br />

36 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

2.92<br />

Multi-row Insert Per<strong>for</strong>mance<br />

(100,000 rows Inserted / test)<br />

Single-row V8 multi-row<br />

2.73<br />

2.51<br />

V7 V8 50kx2 10kx10 1kx100 100x1k 10x10k<br />

1.94<br />

1.8<br />

1.79<br />

V8 with explicit multi-row Insert<br />

50kx2 - 50,000 insert loops, 2 rows per multi-row insert<br />

10kx10 - 10,000 insert loops, 10 rows per multi-row insert<br />

1kx100 - 1,000 insert loops, 100 rows per multi-row insert<br />

100x1k - 100 insert loops, 1,000 rows per multi-row insert<br />

10x10k - 10 insert loops, 10,000 rows per multi-row insert<br />

1.79


3.1.5 Conclusion<br />

The per<strong>for</strong>mance improvement with multi-row insert is not as high as with multi-row fetch<br />

since a row insert is more complex and costly than a row fetch.<br />

The per<strong>for</strong>mance improvement using multi-row insert depends on:<br />

► Number of rows inserted in one insert SQL statement<br />

► Number of columns inserted (more improvement with fewer columns), data type and size<br />

of columns.<br />

► Number of indexes on the table<br />

► For single-row insert, the measured CPU cost in V8 is the same as V7.<br />

Multi-row fetch/update per<strong>for</strong>mance<br />

Multi-row fetch/update measurements, where the whole rowset was updated, show a<br />

behavior similar to multi-row fetch. The measurement values are in Table 3-1.<br />

► Measurements, compared to V7, show<br />

– 25% CPU time improvement with MR=10 rows<br />

– 40% CPU time improvement with MR=100+ rows<br />

The per<strong>for</strong>mance improvement is not as high as MR fetch since a row cursor update is more<br />

complex and costly than a row fetch.<br />

► Per<strong>for</strong>mance improvement depends on<br />

– Number of rows fetched/updated in one SQL statement<br />

– Number of columns fetched/updated<br />

– Complexity of the fetch/update SQL statement<br />

– Number of indexes updated<br />

Multi-row fetch/delete per<strong>for</strong>mance<br />

Multi-row fetch/delete measurements show a behavior similar to multi-row fetch. The<br />

measurement values are in Table 3-1.<br />

Measurements, compared to V7, show<br />

► 25% CPU time improvement with MR=10 rows<br />

► 35% CPU time improvement with MR=100+ rows<br />

Per<strong>for</strong>mance improvement is not as high as MR fetch since a row cursor delete is more<br />

complex and costly than a row fetch.<br />

The per<strong>for</strong>mance improvement depends on:<br />

► Number of rows fetched/deleted in one SQL statement<br />

► Number of columns fetched<br />

► Complexity of the fetch/delete SQL statement<br />

► Number of indexes on the table<br />

Multi-row operations allow <strong>DB2</strong> V8 to reduce the traffic between the application program and<br />

<strong>DB2</strong> when compared to single-row operations. The measurements show better per<strong>for</strong>mance<br />

improvement in the case of statements with:<br />

► Less complex SQL and data types<br />

► Fewer columns processed<br />

Chapter 3. SQL per<strong>for</strong>mance 37


► More rows per one SQL statement (10 rows per multi-row statement results in significant<br />

improvement)<br />

► Fewer indexes processed in table<br />

Table 3-1 provides a summary of the measurements discussed <strong>for</strong> multi-row operations<br />

processing 100,000 rows in a non-partitioned table space with a 100,000 row table, 26<br />

columns, and 1 index.<br />

Table 3-1 Class 1 CPU time (sec.) to process 100,000 rows<br />

Type of MR operation<br />

loopsxrows per SQL<br />

In general, <strong>for</strong> single-row processing <strong>DB2</strong> V8 uses more CPU time, with the exception of the<br />

insert operation.<br />

3.1.6 Recommendation<br />

Explicit multi-row FETCH, INSERT, cursor UPDATE, and cursor DELETE in local<br />

environments can improve per<strong>for</strong>mance with a reduction of CPU time (between 25% and 40%<br />

in the measurements processing 10 rows per SQL statement) if a program processes a<br />

considerable number of rows. Depending on each particular case, a number between 10 rows<br />

and 100 rows per SQL can be a good starting point <strong>for</strong> multi-row operations.<br />

This option requires definition of host variable array declaration of the cursor with rowset<br />

positioning and the text of the SQL to specify the rowset size.<br />

You also have to change your coding on how to do cursor processing. You have to look at how<br />

many rows are returned on a FETCH via SQERRD3 flag in the SQLCA (or the equivalent<br />

ROW_COUNT when using GET DIAGN<strong>OS</strong>TICS).<br />

For existing programs it is worth evaluating the benefits provided vs. the cost of recoding the<br />

programs. The extra storage needed <strong>for</strong> multi-row operations is allocated in the allied address<br />

space, or stored procedure, or DDF.<br />

A variable array has to be explicitly declared. Example 3-2, extracted from the <strong>DB2</strong><br />

Application Programming and SQL Guide, SC18-7415, shows declarations of a fixed-length<br />

character array and a varying-length character array in COBOL.<br />

Example 3-2 COBOL array declaration<br />

01 OUTPUT-VARS.<br />

05 NAME OCCURS 10 TIMES.<br />

49 NAME-LEN PIC S9(4) COMP-4 SYNC.<br />

49 NAME-DATA PIC X(40).<br />

38 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

FETCH INSERT FETCH/UPDATE FETCH/DELETE<br />

V7 single-row 1.09 2.92 2.5 3.68<br />

V8 single-row 1.15 2.73 2.79 3.81<br />

50kx2 1.02 2.51 2.8 3.71<br />

10kx10 0.64 1.94 1.88 2.76<br />

1kx100 0.55 1.8 1.57 2.42<br />

100x1k 0.54 1.79 1.51 2.37<br />

10x10k 0.54 1.79 1.51 2.35


05 SERIAL-NUMBER PIC S9(9) COMP-4 OCCURS 10 TIMES.<br />

Tip: Verify that the PTFs <strong>for</strong> APARs PQ91898, PQ93620, PQ89181, and PQ87969 are<br />

applied:<br />

► PTF UQ92546 <strong>for</strong> per<strong>for</strong>mance APAR PQ91898 reduces excessive lock and getpage<br />

requests in multi-row insert.<br />

► PTF UQ96567 <strong>for</strong> per<strong>for</strong>mance APAR PQ93620 reduces CPU overhead during<br />

multi-row cursor delete.<br />

► PTFs UQ90464 and UQ92692, respectively <strong>for</strong> APAR PQ89181 and PQ87969, reduce<br />

CPU usage by providing improved lock management.<br />

PTF UK06848 <strong>for</strong> APAR PQ99482 provides QMF <strong>for</strong> TSO/CICS 8.1 with the optional<br />

support of multi-row fetch and insert.<br />

3.2 Materialized query table<br />

For many years, the optimization <strong>for</strong> decision-support queries has been a difficult task,<br />

because such queries typically operate over huge amounts of data (1 to 10 terabytes),<br />

per<strong>for</strong>ming multiple joins and complex aggregation.<br />

When working with the per<strong>for</strong>mance of a long running query executed via dynamic SQL,<br />

especially in Data Warehousing, involving joins of many tables, DBAs often created summary<br />

tables manually in order to:<br />

► Improve the response time<br />

► Avoid the redundant work of scanning (sometimes in the <strong>DB2</strong> work file), aggregation and<br />

joins of the detailed base tables (history)<br />

► Simplify SQL to be coded<br />

However, you need to be aware of the existence of the DBA’s summary tables and make a<br />

decision whether to use them or the base tables depending on the query. Another issue is<br />

setting up the synchronization of these summary tables with base tables.<br />

A materialized query table (MQT) is a table containing materialized data derived from one or<br />

more source tables specified by a fullselect to satisfy long running queries requiring good<br />

response time (minutes or even seconds).<br />

The characteristics of MQTs are:<br />

► Source tables <strong>for</strong> MQTs can be base tables, views, table expressions or user-defined table<br />

expressions.<br />

► MQTs can be chosen by the optimizer to satisfy dynamic query (through automatic query<br />

rewrite) when a base table or view is referenced. No query rewrite is done <strong>for</strong> static SQL,<br />

you need to address the MQT directly.<br />

► MQTs are used to precompute once expensive joins, sorts or aggregations. They can be<br />

reused many times to improve query per<strong>for</strong>mance.<br />

► MQTs can be accessed directly by static and dynamic SQL.<br />

Materialized query tables are also known as automatic summary tables in other plat<strong>for</strong>ms.<br />

Chapter 3. SQL per<strong>for</strong>mance 39


3.2.1 Creating MQTs<br />

MQTs compared to views<br />

► MQTs occupy storage space<br />

► MQTs are not usually referenced in a user query, but typically referenced via query rewrite<br />

by <strong>DB2</strong>.<br />

MQTs compared to indexes<br />

► MQTs can be associated with multiple tables. An index can be created <strong>for</strong> one table only.<br />

► Exploitation of MQTs and indexes is transparent to the applications.<br />

We use the extended CREATE TABLE SQL statement to define an MQT and we:<br />

► Specify a fullselect associated with a table<br />

► Specify the mechanisms that are used to refresh the MQT<br />

► Enable/disable an MQT <strong>for</strong> automatic query rewrite<br />

The privilege set needed to define the MQT must include at least one of the following:<br />

► The CREATETAB privilege <strong>for</strong> the database, implicitly or explicitly specified by the IN<br />

clause<br />

► DBADM, DBCTRL, or DBMAINT authority <strong>for</strong> the database in which the table is being<br />

created<br />

► SYSADM or SYSCTRL authority<br />

See Example 3-3 <strong>for</strong> the DDL of a materialized query table.<br />

Example 3-3 Define a table as MQT<br />

CREATE TABLE TRANSCNT (ACCTID, LOCID, YEAR, CNT) AS (<br />

SELECT ACCTID, LOCID, YEAR, COUNT(*)<br />

FROM TRANS<br />

GROUP BY ACCTID, LOCID, YEAR )<br />

DATA INITIALLY DEFERRED<br />

REFRESH DEFERRED<br />

MAINTAINED BY SYSTEM<br />

ENABLE QUERY OPTIMIZATION;<br />

Options creating MQTs<br />

The options are:<br />

► DATA INITIALLY DEFERRED<br />

– The MQTs are not populated at creation<br />

– Use REFRESH TABLE to populate a system-maintained MQT<br />

– Use the INSERT statement to insert data into a user-maintained MQT or use LOAD<br />

► REFRESH DEFERRED<br />

– Data in the MQT is not refreshed when its base tables are updated<br />

– Can be refreshed any time using the REFRESH TABLE statement<br />

► MAINTAINED BY SYSTEM/USER<br />

► ENABLE /DISABLE QUERY OPTIMIZATION<br />

Referential constraints between base tables are also an important factor in determining<br />

whether a materialized query table can be used <strong>for</strong> a query.<br />

40 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


For instance, in a data warehouse environment, data is usually extracted from other sources,<br />

trans<strong>for</strong>med, and loaded into data warehouse tables. In this case the referential integrity<br />

constraints can be maintained and en<strong>for</strong>ced by means other than the database manager to<br />

avoid the serialization and overhead of en<strong>for</strong>cing them by <strong>DB2</strong>.<br />

ALTER a base table to MQT<br />

We use the extended ALTER TABLE SQL statement to change an existing base table into an<br />

MQT. With this statement we:<br />

► Specify a fullselect associated with a table<br />

► Specify one of the mechanisms to refresh the table<br />

► Enable/disable an MQT <strong>for</strong> automatic query rewrite<br />

► Switch between system-maintained and user-maintained types<br />

See Example 3-4.<br />

Example 3-4 Alter a table to MQT<br />

ALTER TABLE TRANSCNT ADD MATERIALIZED QUERY AS (<br />

SELECT ACCTID, LOCID, YEAR, COUNT(*) AS CNT<br />

FROM TRANS<br />

GROUP BY ACCTID, LOCID, YEAR )<br />

DATA INITIALLY DEFERRED<br />

REFRESH DEFERRED<br />

MAINTAINED BY USER;<br />

3.2.2 Populating MQTs<br />

We have mentioned that an MQT can be maintained by system or user.<br />

► System-maintained MQTs (default) are populated with the new REFRESH TABLE option.<br />

This option:<br />

– Deletes all the rows in the MQT<br />

– Executes the fullselect associated with the MQT to recalculate the data<br />

– Inserts the calculated result into the MQT<br />

– Updates the catalog <strong>for</strong> the refresh timestamp and cardinality of the MQT<br />

– Cannot be updated by load, insert, update and delete<br />

You need to refresh materialized query tables periodically to maintain data currency with<br />

base tables. However, realize that refreshing materialized query tables can be an<br />

expensive process.<br />

► User-maintained MQTs can be populated by:<br />

– The REFRESH TABLE option<br />

– Load, insert, update and delete<br />

3.2.3 Controlling query rewrite<br />

Query rewrite is the process that can use an MQT if the query being optimized by <strong>DB2</strong> has<br />

common source tables and all the predicates of the fullselect that make up the MQT.<br />

<strong>DB2</strong> uses two special registers <strong>for</strong> dynamic SQL to control query rewrite:<br />

► CURRENT REFRESH AGE<br />

► CURRENT MAINTAINED TABLE TYPES<br />

Chapter 3. SQL per<strong>for</strong>mance 41


Special register CURRENT REFRESH AGE<br />

The value in this special register represents a refresh age. The refresh age of an MQT is the<br />

timestamp duration between the current timestamp and the timestamp of the last REFRESH<br />

TABLE statement <strong>for</strong> the MQT.<br />

This special register controls whether an MQT can be considered in query rewrite as follows:<br />

► Value “0” means no MQTs are considered in query rewrite<br />

► Value “ANY” means all MQTs are considered in rewrite<br />

The default value of this special register can be specified in the CURRENT REFRESH AGE<br />

field on panel DSNTIP4 at installation time.<br />

The data type <strong>for</strong> CURRENT REFRESH AGE is DEC(20,6).<br />

Note: The default value disables query rewrite. Add SET CURRENT REFRESH AGE ANY<br />

to make sure of the use of MQT. You can verify this with Explain.<br />

Setting the CURRENT REFRESH AGE special register to a value other than zero should be<br />

done with caution. Allowing a materialized query table that may not represent the values of<br />

the underlying base table to be used to optimize the processing of a query may produce<br />

results that do not accurately represent the data in the underlying table.<br />

Note: You need to add the new DSNZPARM with REFSHAGE=ANY to enable query<br />

rewrite as a default.<br />

Special register CURRENT MAINTAINED TABLE TYPES<br />

This special register specifies a VARCHAR(255) value. The name of the dynamic ZPARM is<br />

MAINTYPE. The value identifies the types of MQT that can be considered in query rewrite:<br />

► Value 'SYSTEM' means all system-maintained, query optimization enabled MQTs<br />

► Value 'USER' means all user-maintained, query optimization enabled MQTs<br />

► Value 'ALL' means all query optimization enabled MQTs<br />

The initial value of this special register is determined by the value of field CURRENT MAINT<br />

TYPES on installation panel DSNTIP6. The default of this field is SYSTEM.<br />

Figure 3-6 shows the relationship between the two special registers <strong>for</strong> MQTs.<br />

CURRENT<br />

REFRESH<br />

AGE<br />

ANY<br />

Figure 3-6 Relationship between two special registers <strong>for</strong> MQTs<br />

42 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

0<br />

default<br />

CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION<br />

SYSTEM USER ALL NONE<br />

All system-<br />

maintained<br />

query<br />

optim ization<br />

enabled<br />

MQTs<br />

All user-<br />

maintained<br />

query<br />

optimization<br />

enabled<br />

MQTs<br />

All<br />

query<br />

optimization<br />

enabled<br />

MQTs<br />

None<br />

None None None None


Rules <strong>for</strong> query rewrite<br />

If the query references tables that are also referenced in MQTs, the optimizer can decide to<br />

select the qualified MQT that gives the best per<strong>for</strong>mance <strong>for</strong> the query.<br />

Figure 3-7 summarizes the checking that is per<strong>for</strong>med <strong>for</strong> a query, if automatic query rewrite<br />

is generally enabled in your <strong>DB2</strong> subsystem at installation time.<br />

The automatic query rewrite is supported <strong>for</strong> dynamically prepared queries that are read-only<br />

and have some other restrictions.<br />

The automatic query rewrite is a general process that can use a materialized query table M if<br />

the fullselect F that makes up the MQT has common source tables as the submitted query Q<br />

that is being optimized by <strong>DB2</strong>.<br />

Other conditions are checked during table mapping to verify if the result of the submitted<br />

query can be derived from or can directly use the result of one or more materialized query<br />

tables.<br />

During a predicate matching process, the predicates in the materialized query table fullselect<br />

are compared, one by one, to the predicates in the query Q.<br />

Diagrammatic Overview of Automatic Query Rewrite<br />

Table mapping<br />

Common table: table in both Q and F<br />

Residual table: table in Q only<br />

Extra table: table in F only<br />

Rejoin table: common table joins with<br />

M to derive non-key columns<br />

Predicate matching<br />

Join predicates: exact match in both Q and M<br />

Local predicates: P in Q subsumes P in M<br />

C > 5 subsumes C > 0;<br />

C in ('A', 'B') subsumes C in ('A', 'B', 'C')<br />

In other words, M contains data that Q needs.<br />

Figure 3-7 Rules <strong>for</strong> query rewrite<br />

Table<br />

mapping<br />

Restrictions on Query<br />

Subselect that can be rewritten:<br />

Read-only query<br />

Contains base tables & table<br />

functions, not outer joins only<br />

No ROWID, LOB types<br />

Heuristics of Selections<br />

Match with no regrouping, no residual<br />

joins, and no rejoins.<br />

Match with no regrouping and no<br />

residual joins<br />

Match with the largest reduction ratio:<br />

|T1|*...*|Tn|/|M|, where T1, ..., Tn are<br />

base tables in F<br />

Predicate<br />

matching<br />

Grouping<br />

matching<br />

Expression<br />

derivation<br />

Restrictions on Fullselect<br />

Base tables & table functions<br />

Single SELECT after view and table<br />

expression merge<br />

No ROWID, LOB types<br />

No outer joins<br />

.<br />

Grouping matching<br />

Functional dependency: column K determines C<br />

Matching requirement: Grouping column in F<br />

determines grouping column in Q<br />

No regrouping requirement: Grouping column in<br />

Q determines grouping column in F<br />

Expression derivation<br />

Column equivalence: T1.C1=T2.C1, T2.C1 can be used<br />

<strong>for</strong> T2.C1<br />

Arithmetic expressions: C*(A+B) can be derived from<br />

B+A and C<br />

Scalar functions: substr(C, 5,10) can be derived from C<br />

Set functions:<br />

AVG(C) = SUM(C)/COUNT(*) if C NOT NULL<br />

VAR(C) = ...<br />

Rejoin table columns: From key column T.K derive<br />

non-key column T.C<br />

If there are any predicates that are in the materialized query table subselect, but are not in the<br />

query, then it can be assumed that these predicates may have resulted in discarded rows as<br />

the materialized query table was refreshed, and that any rewritten query that makes use of<br />

the materialized query table does not give the correct results.<br />

The GROUP BY clauses, if any, are compared during grouping matching, to determine if a<br />

query GROUP BY clause results in a subset (not necessarily proper) of the rows that are in<br />

Chapter 3. SQL per<strong>for</strong>mance 43


the materialized query table. If it is, then the materialized query table remains a candidate <strong>for</strong><br />

query rewrite.<br />

If the query Q contains predicates that are not identical to predicates in the materialized query<br />

table subselect, they are examined to determine if column references to base table columns<br />

can derive values from materialized query table columns instead. This takes place during the<br />

expression derivation step.<br />

If the contents of a materialized query table overlap with the contents of a query, the query<br />

and the materialized query table are said to match.<br />

If there are multiple materialized query tables that match the query but cannot be used<br />

simultaneously, heuristic rules are used to select one of them. If the query rewrite process is<br />

successful, <strong>DB2</strong> determines the cost and access path of the new query. Only if the cost of the<br />

new query is less than the cost of the original query is the new query substituted.<br />

Query rewrite example<br />

A simple example of query rewrite is depicted in Figure 3-8. If MQT1 is selected by automatic<br />

query rewrite <strong>for</strong> query RefQ, this means that:<br />

► MQT1 is enabled <strong>for</strong> query optimization by CURRENT REFRESH AGE and CURRENT<br />

MAINTAINED TABLE TYPES<br />

► MQT1 is populated as discussed be<strong>for</strong>e<br />

► Query optimization is enabled<br />

► Tables referenced in the query RefQ match (same tables) the source tables in MQT1<br />

► The predicates in MQT1 match (same predicates) with predicates in the query RefQ<br />

► The GROUP BY clause in the query RefQ is a subset (same GROUP BY) of the rows that<br />

are in MQT.<br />

Fact<br />

Store<br />

RefQ<br />

Figure 3-8 Query rewrite example<br />

44 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Query rewrite example<br />

prod_id time_id store_id ... ... sale_amt<br />

( reference query)<br />

select S.city_id,<br />

sum(F.sale_amt)<br />

from Fact F, Store S<br />

where F.store_id = S.store_id<br />

group by S.city_id<br />

QRW<br />

(query rewrite)<br />

store_id .... city_id city_name<br />

MQT1<br />

select A.cityid,<br />

A.sm_sale<br />

from MQT1 A<br />

select S.city_id,<br />

sum(F.sale_amt) as sm_sale<br />

from Fact F, Store S<br />

where F.store_id = S.store_id<br />

group by S.city_id


3.2.4 Per<strong>for</strong>mance<br />

The SQL statement used by query rewrite is simpler and has a lower cost than running on the<br />

source tables because all calculations have been done when MQT was populated.<br />

If the final query plan comes from a rewritten query:<br />

► PLAN_TABLE shows the MQT used and its access path<br />

► TABLE_TYPE column shows the value 'M' <strong>for</strong> an MQT<br />

In<strong>for</strong>mational referential constraints are introduced to allow users to declare a referential<br />

constraint, avoiding the overhead of en<strong>for</strong>cing the referential constraints by <strong>DB2</strong>. This allows<br />

<strong>DB2</strong> to take advantage of the in<strong>for</strong>mation provided by the referential constraints (data<br />

associations) in query rewrite and some utilities.<br />

We now show some per<strong>for</strong>mance measurements using the functions supported in query<br />

rewrite using MQTs.<br />

Per<strong>for</strong>mance evaluation of MQTs<br />

The evaluation of per<strong>for</strong>mance of MQTs shows:<br />

► MQTs are not used <strong>for</strong> short running queries.<br />

► Query rewrite time grows reasonably when the number of eligible MQTs increases.<br />

► Basic query rewrite works. Results can be obtained directly from MQTs or derived from<br />

MQTs.<br />

► Query rewrite can select the best MQT from a set of qualified MQTs.<br />

The environment <strong>for</strong> MQT measurements<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V7 and V8 NFM<br />

► z/<strong>OS</strong> Release 1.4.0<br />

► z900 Turbo with 3 CPs<br />

► ESS 800 DASD<br />

► Three workloads with different profiles<br />

MQTs and short running queries<br />

Figure 3-9 shows the CPU time <strong>for</strong> a short running query.<br />

Chapter 3. SQL per<strong>for</strong>mance 45


Figure 3-9 MQTs and short running queries<br />

Observations on MQTs and short running queries:<br />

► Create several MQTs which scan various numbers of 4 KB pages to count the number of<br />

rows in the table<br />

► Enable/disable MQTs <strong>for</strong> query rewrite <strong>for</strong> queries in MQT fullselect<br />

► Compare query CPU time with and without MQT<br />

► MQTs are not used <strong>for</strong> short running query scanning 815 page table (0.019 sec. CPU<br />

time)<br />

► MQTs are used <strong>for</strong> query scanning 1032 page table (0.015 sec. CPU using MQT, 0.037<br />

sec. without MQT)<br />

If the estimated cost <strong>for</strong> a given query is below the <strong>DB2</strong> threshold, the automatic query rewrite<br />

is not attempted. The value is similar to the threshold to prevent parallelism <strong>for</strong> short running<br />

queries.<br />

Increase of bind cost<br />

Figure 3-10 shows the overhead introduced by the number of MQTs qualified in BIND cost.<br />

46 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

MQTs and short running queries<br />

CPU time <strong>for</strong> SELECT<br />

COUNT(*) from tables with<br />

various numbers of 4K<br />

pages<br />

MQTs are not used <strong>for</strong> short<br />

running query scanning 815<br />

page table (0.019s CPU<br />

time)<br />

MQTs are used <strong>for</strong> query<br />

scanning 1032 page table<br />

(0.015s cpu, 0.037s w/o<br />

MQT)<br />

CPU Time (sec)<br />

CPU Time <strong>for</strong> SELECT COUNT(*)<br />

0.08<br />

0.07<br />

0.06<br />

0.05<br />

0.04<br />

0.03<br />

0.02<br />

0.01<br />

0<br />

815 1148<br />

1032 1449<br />

Number of Pages<br />

NO MQT<br />

MQT


Increase of BIND cost<br />

BIND cost <strong>for</strong> query<br />

(select count(*)...)<br />

without MQT is 0.01 s<br />

BIND cost <strong>for</strong> query<br />

using one MQT is<br />

0.015 s<br />

Roughly 0.4 ms to<br />

examine each<br />

qualified MQT<br />

Figure 3-10 Increase of BIND cost<br />

We have run Explain <strong>for</strong> a simple query with varying number of MQTs (0, 1, 5, 10, 20, 30, and<br />

40) eligible <strong>for</strong> query rewrite. All MQTs are created the same except <strong>for</strong> the literal value in<br />

predicates. All MQTs are evaluated as possible candidates <strong>for</strong> query rewrite.<br />

We see that bind cost in CPU increases almost linearly as more and more MQTs are eligible<br />

<strong>for</strong> query rewrite.<br />

Query rewrite <strong>for</strong> a simple query<br />

Figure 3-11 reports the per<strong>for</strong>mance of a query rewrite <strong>for</strong> a simple query.<br />

This query selects the count of the number of rows grouped by column BRN <strong>for</strong> those values<br />

of BRNs that have more than 50 rows. In V7, <strong>DB2</strong> has to scan all rows from the source table<br />

(one million rows). The plan table indicates a table space scan <strong>for</strong> table EVE. <strong>DB2</strong> V7 could<br />

decrease the elapsed type if parallelism is enabled. With parallelism the elapsed time is<br />

smaller but there is a small increase in CPU time due to the parallelism overhead.<br />

When executing the same query in V8, the automatic query rewrite is done by the optimizer<br />

selecting the MQT named MQT091. This fact is reflected in the plan table showing a table<br />

scan in a smaller table space.<br />

The summary of measurements of query rewrite <strong>for</strong> a simple query:<br />

► V7 DEGREE(1)<br />

24.77 sec. elapsed time and 4.06 sec. CPU time<br />

► V7 DEGREE(ANY)<br />

6.11 sec. elapsed time and 4.19 sec. CPU time<br />

► V8 using MQT<br />

1.1 sec. elapsed time and 0.06 sec. CPU time<br />

The measurements show that:<br />

CPU Time (sec)<br />

0.035<br />

0.03<br />

0.025<br />

0.02<br />

0.015<br />

0.01<br />

0.005<br />

BIND time<br />

0 1 5 10 20 30 40<br />

Number of MQT<br />

Chapter 3. SQL per<strong>for</strong>mance 47


► The elapsed time is 22 times smaller (about 95%) and CPU time 68 times smaller (about<br />

98%) when we compare V7 DEGREE(1) with V8 using the MQT.<br />

Figure 3-11 Query rewrite <strong>for</strong> simple query<br />

Query rewrite <strong>for</strong> join<br />

Figure 3-12 reports the per<strong>for</strong>mance of a query rewrite <strong>for</strong> a join.<br />

The query rewrite <strong>for</strong> join is similar to the simple query. The plan table <strong>for</strong> V7 shows the join of<br />

the three tables (633k, 1.5 M and 1.3 M rows) using nested loop join. The execution in <strong>DB2</strong><br />

V8 uses the MQT201 that reads 171 rows with a large reduction in the elapsed and CPU<br />

time. Summary of the measurements of query rewrite <strong>for</strong> join:<br />

► V7 DEGREE(1)<br />

28.02 sec. elapsed, 16.52 sec. CPU<br />

► V7 DEGREE(ANY)<br />

14.25 sec. elapsed, 17.9 sec. CPU<br />

► V8 using MQT<br />

0.9 sec. elapsed, 0.07 sec. CPU<br />

In this example, there is a reduction of 31 times (about 96%) in elapsed time and 236 times<br />

(about 99%) in CPU time when we compare V7 DEGREE(1) with V8 using the MQT.<br />

48 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Query rewrite <strong>for</strong> a simple query<br />

V7 PLAN_TABLE<br />

TNAME TABLE_TYPE ACCESSTYPE<br />

EVE T R<br />

V8 PLAN_TABLE<br />

TNAME TABLE_TYPE ACCESSTYPE<br />

MQT091 M R<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

V7 DEGREE(1)<br />

V7 DEGREE(ANY)<br />

V8 using MQT<br />

22X<br />

70X<br />

Elapsed sec CPU sec


Figure 3-12 Query rewrite <strong>for</strong> join<br />

Query rewrite <strong>for</strong> join<br />

CREATE TABLE MQT201 (CRE,INT,COUNT) AS(<br />

SELECT CRE,INT,COUNT(*)<br />

FROM CLA,COI,CIA<br />

WHERE COI.POL=CIA.POL AND<br />

COI.CVI=CIA.CVI AND<br />

COI.CLI=CIA.CLI AND<br />

CIA.CLI=CLA.CLI AND<br />

CIA.CAI=CLA.CAI<br />

GROUP BY CRE,INT)<br />

DATA INITIALLY DEFERRED<br />

REFRESH DEFERRED<br />

MAINTAINED BY USER<br />

ENABLE QUERY OPTIMIZATION;<br />

V7 PLAN_TABLE<br />

TABLE<br />

SIZE<br />

TNAME TABLE_TYPE METHOD<br />

633 K<br />

1.5 M<br />

1.3 M<br />

COI<br />

CIA<br />

CLA<br />

V8 PLAN_TABLE<br />

T<br />

T<br />

T<br />

0<br />

1<br />

1<br />

TNAME TABLE_TYPE METHOD<br />

MQT201 M 0<br />

171 rows in MQT<br />

Elapsed sec CPU sec<br />

GROUP BY and predicate matching<br />

The MQT remains a candidate <strong>for</strong> query rewrite if the query GROUP BY clause results in a<br />

subset of the rows that are in the MQT<br />

The predicate in the query subsumes the predicate in the MQT. Example: C1>8 subsumes<br />

C1>0.<br />

The predicates in the query should be coded as those in the MQT subselect. Otherwise,<br />

matching may fail on some complex predicates.<br />

Figure 3-13 shows the impact of regrouping the MQT data when <strong>DB2</strong> obtains the final answer<br />

set in the query.<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

V7 DEGREE(1)<br />

V7 DEGREE(ANY)<br />

V8 using MQT<br />

31X<br />

236<br />

X<br />

Chapter 3. SQL per<strong>for</strong>mance 49


Figure 3-13 Regrouping on MQT result<br />

In this example the populated MQT661 has 1808 rows as the result of joining two tables and<br />

grouping by BRN,PST. Explain was executed <strong>for</strong> query number 662 as shown in Example 3-5.<br />

Example 3-5 Explain <strong>for</strong> Q662<br />

** EXPLAIN ALL SET QUERYNO=662 FOR<br />

SELECT BRN, SUM(OFC),COUNT(DISTINCT PLC.POL),<br />

COUNT(COV.OFC)<br />

FROM COV,PLC<br />

WHERE<br />

COV.POL = PLC.POL AND COV.CVT='B'<br />

GROUP BY BRN<br />

ORDER BY BRN;<br />

The PLAN_TABLE <strong>for</strong> V8 in Figure 3-13 shows that the <strong>DB2</strong> Optimizer has selected the MQT.<br />

The result is a reduction in elapsed time from 45.1 sec. to 0.92 sec. We see a significant<br />

reduction even if we compare it with V7 with parallelism.<br />

The new access path using MQT regroups 1808 rows avoiding the nested loop join of one<br />

table having 1.7 million rows with a table with 624 thousand rows.<br />

Summary of measurements of a query rewrite <strong>for</strong> simple query:<br />

► V7 DEGREE(1)<br />

45.1 sec. elapsed time and 12.92 sec. CPU time<br />

► V7 DEGREE(ANY)<br />

9.04 sec. elapsed time and 13.87 sec. CPU time<br />

50 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Re-grouping on MQT results<br />

CREATE TABLE MQT661 (BRN,PST,COUNT,SUM) AS (<br />

SELECT BRN.PST,COUNT(DISTINCT PLC.POL),<br />

SUM(COV.OFC)<br />

FROM COV, PLC<br />

WHERE COV.POL=PLC.POL<br />

AND COV.CVT= 'B'<br />

GROUP BY BRN,PST)<br />

DATA INITIALLY DEFERRED<br />

REFRESH DEFERRED<br />

MAINTAINED BY USER<br />

ENABLE QUERY OPTIMIZATION;<br />

V7 PLAN_TABLE<br />

TABLE<br />

SIZE<br />

TNAME TABLE_TYPE METHOD<br />

1.7 M<br />

624 K<br />

COV<br />

PLC<br />

T<br />

T<br />

0<br />

1<br />

V8 PLAN_TABLE<br />

TNAME TABLE_TYPE METHOD<br />

MQT661 M 0<br />

1808 rows in MQT<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

V7 degree=1<br />

V7 degree=any<br />

V8 using MQT<br />

47X<br />

Elapsed sec CPU sec<br />

117<br />

X


► V8 using MQT<br />

0.92 sec. elapsed time and 0.11 sec. CPU time<br />

The measurements show that the elapsed time was 49 times smaller (about 97%) and CPU<br />

time 117 times smaller (about 99%) when we compare V7 DEGREE(1) with V8 using an<br />

MQT.<br />

Expression derivation<br />

► Arithmetic expressions: (A+B)*C can be derived from B+A and C<br />

► Column equivalence: If TI.C1=T2.C1, T2.C1 can be used <strong>for</strong> T1.C1<br />

► Scalar functions: SUBSTR(A,3,5) can be derived from A<br />

► Set functions: AVG(C) can be derived from SUM(C) and COUNT(*) if C NOT NULL<br />

Figure 3-14 shows one example of expression derivation using an MQT.<br />

Expression derivation<br />

Query<br />

Figure 3-14 Expression® derivation example<br />

In the example the populated MQT673 is the result of joining three tables and two<br />

aggregations:<br />

SUM(COV.MCP),SUM(PLC.CAS)<br />

The measured query selects<br />

SUM(COV.MCP) + SUM(PLC.CAS)<br />

This can be derived from the two aggregated columns from MQT.<br />

The predicates<br />

SELECT<br />

CREATE TABLE MQT673 ( COUNT,SUM1,SUM2,CVT) AS(<br />

SELECT<br />

COUNT(DISTINCT PLC.POL),<br />

SUM(COV.MCP),SUM(PLC.CAS),<br />

COV.CVT<br />

FROM<br />

PLC,COV,EVE<br />

WHERE<br />

PLC.POL = EVE.POL AND<br />

PLC.POL = COV.POL AND<br />

EVE.EXT = 'ADD BILL' AND<br />

EVE.TXC = 'IBIA0102'<br />

GROUP BY COV.CVT)<br />

DATA INITIALLY DEFERRED..........<br />

COUNT(DISTINCT PLC.POL), MQT673 disabled <strong>for</strong> QR<br />

SUM(COV.MCP) + SUM(PLC.CAS) Query ran <strong>for</strong> 10.5 seconds<br />

FROM<br />

PLC,COV,EVE MQT673 enabled <strong>for</strong> QR<br />

WHERE Query ran <strong>for</strong> 0.91 second<br />

using<br />

PLC.POL = EVE.POL AND<br />

PLC.POL = COV.POL AND<br />

EVE.EXT = 'ADD BILL' AND EVE.TXC = 'IBIA0102' AND COV.CVT = 'P' ;<br />

Chapter 3. SQL per<strong>for</strong>mance 51


EVE.EXT = 'ADD BILL' AND EVE.TXC = 'IBIA0102'<br />

In the query match with the predicates<br />

EVE.EXT = 'ADD BILL' AND EVE.TXC = 'IBIA0102'<br />

In the MQT due to join predicates.<br />

The predicate<br />

COV.CVT = 'P'<br />

3.2.5 Conclusions<br />

filters to one aggregation in the MQT because of GROUP BY COV.CVT.<br />

The measurements show a per<strong>for</strong>mance improvement in elapsed time from 10.5 sec. to 0.91<br />

sec. (about 91%) when using the MQT.<br />

Note that an expression like (A+B)*C cannot be derived from A*C+B*C.<br />

MQT considerations<br />

► All MQTs and their indexes are dropped if their associated base tables are dropped.<br />

► No primary keys, unique indexes or triggers are allowed on MQTs.<br />

► Design issues between a few generic MQTs and many more specialized MQTs:<br />

– Trade off between query per<strong>for</strong>mance and MQT maintenance.<br />

– Identify a set of queries which consume a lot of resource. Design MQTs <strong>for</strong> the set of<br />

queries as a starting point. Example: Top queries that consume a large amount of<br />

resources.<br />

► Automatic query rewrite is done at query block level by the <strong>DB2</strong> optimizer.<br />

► MQTs are not used <strong>for</strong> short running queries.<br />

► Query rewrite works <strong>for</strong> both star join and non-star join queries.<br />

► Code the predicates in the query in exactly the same way as they are in the MQT<br />

fullselect.<br />

Exception: The order of the items in the IN list predicate does not need to be in exactly the<br />

same order.<br />

MQTs can be created as a precomputed join, sort or aggregation, and reused by <strong>DB2</strong> query<br />

rewrite in dynamic SQL to improve the execution of long running queries in the Data<br />

Warehouse environment, providing largely reduced elapsed time and CPU time.<br />

► Query rewrite time seems reasonable <strong>for</strong> simple queries.<br />

► Query rewrite time grows reasonably when the number of eligible MQTs increases.<br />

► Query rewrite works. The query result can be obtained directly from the MQT or derived<br />

from the MQT.<br />

► Query rewrite can select the best MQT from a set of qualified MQTs.<br />

► Up to 100 times query per<strong>for</strong>mance improvement is observed; simple examples with<br />

tables that are not so large, show improvement of 22x, 31x, and 47x in elapsed time and<br />

70x, 236x and 117x in CPU time.<br />

52 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The most important factor in the return on investment on MQTs remains the frequency of<br />

utilization, and, there<strong>for</strong>e, a balance of how specialized the MQT is and how well it per<strong>for</strong>ms<br />

versus the range of applicability.<br />

3.2.6 Recommendations<br />

MQTs allow more flexibility <strong>for</strong> the physical data base design of tables at the detailed level<br />

(sometimes known as atomic level) in a corporate data warehouse. The base tables can be<br />

more normalized, closer to the conceptual model, and the per<strong>for</strong>mance issues of long running<br />

queries involving joins, summarizations, and subqueries can be resolved when materialized<br />

as MQTs.<br />

Plan MQTs <strong>for</strong> the top consuming queries, not <strong>for</strong> all queries. Use MQTs to aggregate results<br />

based on the most used predicates joining large tables and allow the <strong>DB2</strong> optimizer to use<br />

regrouping, predicate matching and expression derivation.<br />

Multi-dimensional applications can gain benefits by using MQTs, when queries have<br />

opportunities <strong>for</strong> regrouping.<br />

If you can identify these cases, the same MQT can be reused in many different queries. A<br />

good case is when a new table in the <strong>DB2</strong> work file as a result of join is scanned a large<br />

number of times in a nested loop join: MQTs can be indexed.<br />

The use of MQTs can potentially provide huge savings in a data warehouse environment. It is<br />

good <strong>for</strong> queries, but not <strong>for</strong> OLTP due to the extra cost <strong>for</strong> BIND.<br />

For large MQTs, remember to:<br />

► Use segmented table spaces because of the almost instantaneous mass delete in<br />

REFRESH TABLE.<br />

► Execute RUNSTATS after REFRESH <strong>for</strong> good access path selection; otherwise, <strong>DB2</strong> uses<br />

default or out-of-date statistics.<br />

Keep the number of MQTs <strong>for</strong> a base table down to an acceptable number to avoid the extra<br />

cost of BIND time due to the large number of MQTs eligible <strong>for</strong> query rewrite, as well as the<br />

processing necessary <strong>for</strong> the maintenance of MQTs. For a simple query the measured<br />

overhead is about 0.4 ms to examine each qualified MQT.<br />

When creating a user-maintained materialized query table, initially disable query optimization.<br />

Otherwise, <strong>DB2</strong> might automatically rewrite queries to use the empty materialized query<br />

table.<br />

3.3 Star join processing enhancements<br />

3.3.1 Star schema<br />

In this section we describe how, in <strong>DB2</strong> V8, the execution of star join is improved by:<br />

► Access path enhancements<br />

► Better estimates of the filtering effect of dimensions<br />

► Use of sparse indexes in cache <strong>for</strong> materialized snowflakes<br />

► Use of in-memory work files<br />

The star schema data model is often used in data warehouses, data marts and OLAP. The<br />

representation of a star schema is shown in Figure 3-15.<br />

Chapter 3. SQL per<strong>for</strong>mance 53


Star<br />

Schema<br />

Figure 3-15 Star schema<br />

The attributes of a star schema database are:<br />

► Large fact table: Like sales tables containing transactions that can be in the order of<br />

hundreds of millions, or billions of data rows.<br />

► Highly normalized design with dimensions (or snowflakes), tables to avoid maintaining<br />

redundant descriptive data in the central fact table.<br />

► Relatively small dimensions: Dimensions can be denormalized to one table (without the<br />

tables identified as “S” in Figure 3-15) or normalized in related tables in the <strong>for</strong>m of a<br />

snowflake.<br />

► Sparse “Hyper Cube”: Caused by high correlation among dimensions, leading to a sparse<br />

nature of data in the fact table; <strong>for</strong> example, product sales are dependent on the climate,<br />

there<strong>for</strong>e, the sale of shorts is more likely in a state where the people enjoy hot weather.<br />

► Fact table is dependent on the dimension tables.<br />

Star schema query<br />

Star schema query is normally a star join with the following characteristics:<br />

► Equi-join predicates between the fact and dimension tables<br />

► Local predicates on the dimension tables<br />

► Large number of tables in the query<br />

For a star join query, <strong>DB2</strong> uses a special join type called a star join if the following conditions<br />

are true:<br />

► The tables meet the conditions that are specified in the section “Star join<br />

(JOIN_TYPE=’S’)” of the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Administration Guide, SC18-7413.<br />

Unlike the steps in the other join methods (nested loop join, merge scan join, and hybrid<br />

join) in which only two tables are joined in each step, a step in the star join method can<br />

involve three or more tables. Dimension tables are joined to the fact table via a<br />

multi-column index that is defined on the fact table. There<strong>for</strong>e, having a well-defined,<br />

multi-column index on the fact table is critical <strong>for</strong> efficient star join processing.<br />

► The STARJOIN system parameter is set to ENABLE, and the number of tables in the<br />

query block is greater than or equal to the minimum number that is specified in the<br />

SJTABLES system parameter.<br />

Note: The default <strong>for</strong> star join processing is DISABLE.<br />

► Another system parameter is the maximum pool size (MB) <strong>for</strong> star join SJMXPOOL.<br />

54 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

S<br />

D<br />

Fact<br />

table<br />

D<br />

F<br />

D<br />

D<br />

S<br />

S<br />

snowflake<br />

Dimension<br />

table<br />

S<br />

S


Star join technical issues<br />

The technical issues surrounding the optimization of decision support and data warehousing<br />

queries against a star schema model can be broken down into bind-time and run-time issues.<br />

The first consideration generally is the sheer size of the fact table, and also the large number<br />

of tables that can be represented in the star schema.<br />

► Bind-time issues<br />

For non-star join queries, the optimizer uses the pair-wise join method to determine the<br />

join permutation order. However, the number of join permutations grows exponentially with<br />

the number of tables being joined. This results in an increase in bind time, because of the<br />

time required to evaluate the possible join permutations. Star join does not do pair-wise<br />

join. It joins several unrelated tables via a (simulated) cartesian join to the fact table.<br />

► Run-time issues<br />

Star join queries are also challenging at run-time. <strong>DB2</strong> uses either cartesian joins of<br />

dimension tables (not based on join predicates, the result is all possible combinations of<br />

values in both tables) or pair-wise joins (based on join predicates).<br />

The result is all possible combinations of values in both tables. The pair-wise joins have<br />

worked quite effectively in the OLTP world. However, in the case of star join, since the only<br />

table directly related to other tables is the fact table, the fact table is most likely chosen in<br />

the pair-wise join, with subsequent dimension tables joined based on cost.<br />

Even though the intersection of all dimensions with the fact table can produce a small<br />

result, the predicates supplied to a single dimension table are typically insufficient to<br />

reduce the enormous number of fact table rows. For example, a single dimension join to<br />

the fact table may find:<br />

– 100+ million sales transactions in the month of December<br />

– 10+ million sales in San Jose stores<br />

– 10+ million sales of Jeans, but<br />

– Only thousands of rows that match all three criteria<br />

Hence there is no one single dimension table which could be paired with the fact table as<br />

the first join pair to produce a manageable result set.<br />

With these difficulties in mind, the criteria <strong>for</strong> star join can be outlined as follows:<br />

► “Selectively” join from the outside-in:<br />

Purely doing a cartesian join of all dimension tables be<strong>for</strong>e accessing the fact table may<br />

not be efficient if the dimension tables do not have filtering predicates applied, or there is<br />

no available index on the fact table to support all dimensions. The optimizer should be able<br />

to determine which dimension tables should be accessed be<strong>for</strong>e the fact table to provide<br />

the greatest level of filtering of fact table rows.<br />

For this reason, outside-in processing is also called the filtering phase. <strong>DB2</strong> V8 enhances<br />

the algorithms to do a better job at selecting which tables to join during outside-in<br />

processing.<br />

► Efficient “Cartesian join” from the outside-in:<br />

A physical cartesian join generates a large number of resultant rows based on the cross<br />

product of the unrelated dimensions. A more efficient cartesian type process is required<br />

as the number and size of the dimension tables increase, to avoid an exponential growth in<br />

storage requirements. A key feedback technique is useful <strong>for</strong> making cartesian joins<br />

efficient.<br />

► Efficient “join back”, inside-out:<br />

The join back to dimension tables that are accessed after the fact table must also be<br />

efficient. Non-indexed or materialized dimensions present a challenge <strong>for</strong> excessive sort<br />

Chapter 3. SQL per<strong>for</strong>mance 55


merge joins and work file usage. <strong>DB2</strong> V8 enhancements introduce support <strong>for</strong> in-memory<br />

work files and sparse indexes <strong>for</strong> work files to meet this challenge.<br />

► Efficient access of the fact table:<br />

Due to the generation of arbitrary (or unrelated) key ranges from the cartesian process,<br />

the fact table must minimize unnecessary probes and provide the greatest level of<br />

matching index columns based on the pre-joined dimensions.<br />

Of course, the very first step is determine if the query qualifies <strong>for</strong> a star join. You can refer to<br />

the white paper The Evolution of Star Join Optimization available from the Web site:<br />

http://www.ibm.com/software/data/db2/os390/techdocs/starjoin.pdf<br />

Star join per<strong>for</strong>mance characteristics<br />

Star join characteristics are:<br />

► Snowflakes are common <strong>for</strong> star join queries.<br />

► Snowflakes are generally materialized.<br />

► Snowflake work files could not have indexes defined on them be<strong>for</strong>e the implementation of<br />

sparse index in V7.<br />

► Sort merge join is usually chosen to join the snowflake to the fact table composite; this can<br />

be relatively inefficient.<br />

► Sorting a large intermediate result (composite table) including a join to the fact table (no<br />

index) is expensive.<br />

The result of outside-in processing (the star join itself) is a composite table (the composite<br />

result of previous operations. It needs to be sorted in join column sequence if sort merge<br />

join is used (very likely) during inside out processing.<br />

► Sorting the large intermediate result <strong>for</strong>ces the parallel group to merge (less parallelism).<br />

3.3.2 In memory work file<br />

<strong>DB2</strong> V8 supports in memory work files (IMWF) <strong>for</strong> star join queries. This means the normal<br />

work file database is not used. The complete work file is stored in memory instead.<br />

Figure 3-16 shows the utilization of IMWF to improve the per<strong>for</strong>mance of star join.<br />

56 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


ISCAN<br />

(Mat)<br />

3.3.3 Sparse index<br />

In memory work file (IMWF)<br />

S<br />

Outside-in<br />

SCAN<br />

IMWF<br />

In-memory<br />

workfiles<br />

Figure 3-16 In memory work file - Description<br />

NLJ NLJ<br />

NLJ<br />

SCAN ISCAN SCAN<br />

S S<br />

IMWF<br />

Dimension D (Time)<br />

D (Store)<br />

SALES<br />

(300M)<br />

Inside-out<br />

NLJ +<br />

IMWF<br />

The in memory work file is used <strong>for</strong> caching the data and index keys in a dedicated virtual<br />

memory pool. If IMWF fails (<strong>for</strong> whatever reason), sparse index on the work file is used.<br />

IMWF characteristics:<br />

► IMWF reduces contention on the work file buffer pool<br />

► IMWF reduces CPU and work file I/O<br />

► The memory pool is created only when star join is enabled<br />

► Can specify the maximum pool size via DSNZPARM SJMXPOOL<br />

► SJMXPOOL is changeable from 0 to 1024 MB.<br />

– 20 MB is the default<br />

– Memory pool is allocated at execution time above the bar<br />

► Exact amount of required space is allocated<br />

► The pool contains only the join column and the columns selected<br />

► Binary search via in memory index keys<br />

► If the dedicated pool cannot be allocated or the space in it becomes insufficient to store<br />

the data, the traditional sparse index is used; that is, a work file is created.<br />

In this section we describe the implementation of a sparse index on the work file during star<br />

join execution. The difference between a normal and a sparse index is in the regular index<br />

there is one entry <strong>for</strong> each row in the table and in the sparse index there is one entry <strong>for</strong><br />

several rows that have the same key. Sparse index was first introduced in <strong>DB2</strong> V4 <strong>for</strong><br />

uncorrelated IN subqueries.<br />

► In <strong>DB2</strong> V7 sparse index can only be used during INSIDE-OUT processing<br />

► In <strong>DB2</strong> V8 in both inside-out and outside-in, but only if IMWF cannot be used<br />

IMWF<br />

NLJ<br />

SCAN<br />

IMWF<br />

Dim Dim Dim Dim Dim<br />

NLJ<br />

ISCAN<br />

Dimension<br />

Chapter 3. SQL per<strong>for</strong>mance 57


Star join access path without a sparse index<br />

Figure 3-17 shows the access path to execute a star join (be<strong>for</strong>e PQ61458, which introduced<br />

the sparse index function also in V7).<br />

100<br />

Time NLJ NLJ Store Fact<br />

Figure 3-17 Star join access path (be<strong>for</strong>e PQ61458)<br />

Characteristics of the star join access path:<br />

► Use of a multi-column fact table index during outside-in phase. Nested-loop join (NLJ) is<br />

used.<br />

► No index on the snowflake work file during the inside-out phase. Sort-merge join (SMJ) is<br />

used.<br />

This process can be efficient if the number of rows in the fact table composite involves a low<br />

number of rows, but can be very expensive <strong>for</strong> a large fact table composite.<br />

Sparse indexes on work files<br />

Figure 3-18 shows the structure of a sparse index on the work file.<br />

The development of sparse indexes on work files in <strong>DB2</strong> V8 improves the per<strong>for</strong>mance of the<br />

star join execution.<br />

58 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

500 15,000,000 600 30,000<br />

SMJ<br />

Prod<br />

SMJ<br />

Custmr ...<br />

Outside-in<br />

phase<br />

Fact table index<br />

(Time,Store,...)<br />

Expensive to sort large<br />

Fact table composite<br />

Inside-out phase<br />

Sort merge join is<br />

used to join<br />

snowflake to Fact<br />

table composites


Sparse Index<br />

T1<br />

Binary Search<br />

Figure 3-18 Sparse index on work file<br />

NLJ<br />

t1.c = t2.c<br />

Key RID<br />

With a sparse index there is a binary search to find the entry <strong>for</strong> the key searched in memory<br />

and scans a few rows in the work file.<br />

Sparse index on work file:<br />

► Made available in <strong>DB2</strong> V7 via APAR PQ61458<br />

► Enhanced in <strong>DB2</strong> V8, sort key and a 5 byte RID<br />

► Sparse indexes are built in cache when they are sorted in join column order<br />

► Cache up to 240 KB in memory in thread local storage pool<br />

► Probed through an equal-join predicate<br />

► New ACCESSTYPE='T' in PLAN_TABLE <strong>for</strong> sparse index access as well as <strong>for</strong> IMWF<br />

► Nested-loop join can be used <strong>for</strong> inside-out phase of star join<br />

Sparse index <strong>for</strong> star join<br />

Figure 3-19 shows the use of a sparse index in the inside-out phase in a star join.<br />

With the sparse index the access path can be changed to avoid sort-merge-join in the<br />

inside-out phase:<br />

► Use of a multi-column fact table index during outside-in phase<br />

► Use of a sparse index during inside-out phase<br />

RID<br />

... ...<br />

T2 (WF)<br />

T2<br />

(WF)<br />

Sorted in t2.c order<br />

As a result there is no longer the need to sort a large composite file (no sort work file space<br />

requirement) and reduction of the overhead (merge and repartition) caused by sort.<br />

Chapter 3. SQL per<strong>for</strong>mance 59


3.3.4 Per<strong>for</strong>mance<br />

Sparse index <strong>for</strong> star join<br />

100 500 15,000,000 600 30,000<br />

Time<br />

NLJ<br />

Store<br />

NLJ<br />

Fact<br />

NLJ<br />

Prod<br />

NLJ<br />

Custmr ...<br />

Fact table index<br />

(Time,Store,...)<br />

Outside-in phase<br />

Figure 3-19 Sparse index <strong>for</strong> star join<br />

The best per<strong>for</strong>mance can be obtained if the buffer pool <strong>for</strong> the work files has enough space<br />

to hold the snowflake work files on which the 'T' access in PLAN_TABLE is used.<br />

Per<strong>for</strong>mance measurements show benefits in queries from different workloads as result of the<br />

usage of the features described be<strong>for</strong>e.<br />

Sparse index per<strong>for</strong>mance<br />

Figure 3-20 summarizes the <strong>DB2</strong> V7 measurements with (APAR PQ61458) and without<br />

sparse indexes (SI) in different queries from two workloads.<br />

60 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Inside-out phase<br />

Access through sparse index<br />

Fast scan of workfile<br />

to avoid sort of the<br />

composites


Sparse index (SI) per<strong>for</strong>mance<br />

Large elapsed time reduction<br />

Elapsed Time (s)<br />

Thousands<br />

Figure 3-20 Sparse index per<strong>for</strong>mance<br />

4<br />

3<br />

2<br />

1<br />

0<br />

I10<br />

I14<br />

I22<br />

S22A S22C VP12<br />

I26 S22B VP11 VP13<br />

QUERY NO<br />

The per<strong>for</strong>mance measurements considering the use of sparse indexes in star join show:<br />

► 77 queries on two workloads are measured.<br />

► Among the 41 queries that exploit sparse index (SI), most of queries show 50% - 80%<br />

elapsed time reduction. Top queries:<br />

– Query VP13 elapsed without SI = 3634 sec. and with SI = 561.9 sec. (84% reduction)<br />

– Query I10 elapsed time without SI = 3399 sec. and with SI = 1838 sec. (45% reduction)<br />

– Query VP12 elapsed without SI = 3143 sec. and with SI = 498.7 sec. (84% reduction)<br />

– Query I22 elapsed time without SI = 3142 sec. and with SI = 1625 sec. (48% reduction)<br />

► With parallelism, they show an additional 30% - 60% elapsed time reduction.<br />

► Per<strong>for</strong>mance improves more when more sorts are involved.<br />

Star join access path<br />

Figure 3-21 shows a comparison on CPU times between <strong>DB2</strong> V7 and <strong>DB2</strong> V8.<br />

without SI<br />

with SI<br />

These measurement results were based on all the <strong>DB2</strong> V8 supported features, including the<br />

in memory work file.<br />

Chapter 3. SQL per<strong>for</strong>mance 61


V8 Star Join Access Path<br />

Figure 3-21 Star join access path<br />

Star join access path in <strong>DB2</strong> V8 had reduction in CPU time due to:<br />

► Improved star join cost estimation that better estimates the filtering effect of dimensions<br />

► Snowflake materialization occurs only if it is cost-effective<br />

► Updated star join detection logic, optimization and run-time processes<br />

► Use of in memory work files both in outside-in and inside-out join phases<br />

The measured CPU time <strong>for</strong> the top queries:<br />

► Query 3001: CPU time in V7 = 119 sec. and in V8 = 2.3 (reduction of 98%)<br />

► Query 3008: CPU time in V7 = 118 sec. and in V8 = 1 (reduction of 99%)<br />

► Query 3004: CPU time in V7 = 118 sec. and in V8 = 11 (reduction of 90%)<br />

► Query 3006: CPU time in V7 = 102 sec. and in V8 = 10 (reduction of 90%)<br />

In Memory Work File (IMWF) per<strong>for</strong>mance<br />

Measurements of the query workload submitted in single thread using various sizes of IMWF<br />

show:<br />

► 20 MB vs. no IMWF - Many queries have per<strong>for</strong>mance gain<br />

► 32 MB vs. 20 MB - Three more queries show improvement<br />

► 64 MB vs. 32 MB - One more query shows improvement<br />

► 128 MB vs. 64 MB - No per<strong>for</strong>mance gain<br />

Figure 3-22 shows the CPU time reduction with 64 MB IMWF when compared to no IMWF.<br />

The result indicates the effect of IMWF (comparison when IMWF is disabled and enabled) on<br />

all the other <strong>DB2</strong> V8 supported features. When IMWF is disabled, the traditional sparse<br />

indexes are used, with the same access path.<br />

62 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CPU Time (s)<br />

140<br />

120<br />

100<br />

80<br />

60<br />

40<br />

20<br />

0<br />

2001 3001 3006 3008 2015<br />

2005 2010 2018 2014 3004<br />

QUERY NO<br />

V7<br />

V8


CPU reduction using in memory work file<br />

CPU Time (s)<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

4232 4509 4416 4135 4457<br />

4580 3016 4417 4485 4901<br />

QUERY NO<br />

Figure 3-22 In memory work file - CPU reduction<br />

V8 NO IMWF<br />

V8 64 MB<br />

Per<strong>for</strong>mance improvements observed on queries from a workload with 64 MB of IMWF<br />

compared with no IMWF:<br />

► Up to 40% elapsed time reduction<br />

► Up to 31% CPU time reduction. Top queries from the workload:<br />

– Query 4580: CPU time NO IMWF = 560 sec. and with IMWF = 446 (reduction of 21%)<br />

– Query 4485: CPU time NO IMWF = 559 sec. and with IMWF = 386 (reduction of 31%)<br />

– Query 4901: CPU time NO IMWF = 553 sec. and with IMWF = 411 (reduction of 25%)<br />

In practical environments 128 MB to 256 MB can be a good starting point, depending on the<br />

workload using the snowflake data model.<br />

Bigger improvements are anticipated in environments where work file data sets are shared<br />

concurrently with other threads, such as <strong>for</strong> sorting.<br />

Per<strong>for</strong>mance study on warehouse workload<br />

Total elapsed time and total CPU time were measured <strong>for</strong> 79 star join queries in a highly<br />

normalized data warehouse workload in V7 and V8.<br />

Figure 3-23 shows the improvement in per<strong>for</strong>mance with sparse indexes, access path<br />

changes and the use of in memory work file.<br />

Chapter 3. SQL per<strong>for</strong>mance 63


3.3.5 Conclusion<br />

Star join workload<br />

Total elapsed time and total cpu time <strong>for</strong> 79 queries on highly<br />

normalized warehouse workload<br />

Elapsed Time or CPU Time (thousand seconds)<br />

Figure 3-23 Star join workload<br />

Observations on star join workload <strong>for</strong> 79 queries:<br />

► V7 old cost model is the default. Sparse index enhancements apply.<br />

► V7 new cost model - Set SPRMSJNC DSNZPARM to ON (by APAR PQ61458)<br />

– V7 new cost model provides access path/per<strong>for</strong>mance improvement on long running<br />

queries<br />

– Recommend SAP/BW customer use new cost model<br />

► 33.5% reduction on total elapsed time vs. old cost model<br />

► V8 without IMWF enhancement<br />

– Have access path improvements <strong>for</strong> medium and short running queries<br />

– 36.4% reduction on total CPU time vs. V7 new cost model<br />

► V8 IMWF enhancement<br />

► Reduce the elapsed time of the workload by about 35%<br />

Total elapsed time and total CPU time <strong>for</strong> 79 queries:<br />

► V7 old model: 39968 sec. elapsed time and 15219 sec. CPU time<br />

► V7 new model: 26581 sec. elapsed time and 13462 sec. CPU time<br />

► V8 w/o IMWF: 26512 sec. elapsed time and 8563 sec. CPU time<br />

► V8 with IMWF: 17200 sec. elapsed time and 5847 sec. CPU time<br />

The comparison between the V7 old model and V8 with IMWF resulted in a total of a 56%<br />

reduction in elapsed time and a 61% reduction in CPU time.<br />

V8 star join queries per<strong>for</strong>m much better than V7 due to:<br />

► Star join access path enhancements<br />

64 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

V7 Old Model<br />

V8 w/o IMWF<br />

V7 New Model<br />

V8 with IMWF<br />

E.T.<br />

CPU


► In memory work file which caches the data and index keys in a dedicated virtual memory<br />

pool<br />

Star join per<strong>for</strong>mance is dependent on the circumstances. Your mileage may vary.<br />

3.3.6 Recommendations<br />

The size of the in memory work file can be set on the installation panel DSNTIP8, parameter<br />

STAR JOIN MAX POOL.<br />

The in memory data caching <strong>for</strong> star join is most effective when the schema contains<br />

snowflakes. There<strong>for</strong>e, <strong>for</strong> the users whose star schema is highly normalized and has many<br />

snowflakes, a larger pool size would be recommended (<strong>for</strong> example, 256 MB), particularly<br />

when the <strong>DB2</strong> subsystem is dedicated to star schema workloads. This virtual storage is<br />

above the 2 GB bar and the real storage use is limited to only the pages touched, so there<br />

should be no significant penalty <strong>for</strong> those not using star joins and potentially much greater<br />

benefit <strong>for</strong> those using star joins.<br />

Note: An unfiltered snowflake may not be materialized in V8 in contrast to V7 where all<br />

snowflakes were materialized into work files.<br />

The sparse index support in inside-out phase and part of the new star join access path<br />

selection logic are included in APAR PQ61458 applicable to V7.<br />

After migrating to <strong>DB2</strong> V8, specify adequate amounts of memory <strong>for</strong> maximum pool size in<br />

DSNZPARM SJMXPOOL to gain the benefit of in memory work files in a dedicated virtual<br />

memory pool <strong>for</strong> star join.<br />

3.4 Stage 1 and indexable predicates<br />

Figure 3-24 shows one example of the execution of one SQL using index and shows the<br />

difference between Stage 1 and Stage 2 predicates, where Stage 1 predicates can be<br />

resolved sooner, without involving complex analysis.<br />

The SELECT statement reads all orders from the table TORDER that has order number<br />

between 15000 and 17000. <strong>DB2</strong> specifies the use of the index on column ORDERNO starting<br />

at key value 15000. <strong>DB2</strong> uses the index tree to find the leaf page containing the value 15000<br />

and scans <strong>for</strong>ward until it accesses the leaf page containing the value 17000. Then it stops<br />

the scan. GETPAGEs are issued <strong>for</strong> each index page referenced.<br />

In complex SQL statements with multiple predicates, they are applied in the sequence:<br />

1. Matching index predicate<br />

2. Other index key predicates applied<br />

3. All other stage 1 predicates<br />

4. All stage 2 predicates<br />

If the predicate is applied in the earlier stage, the per<strong>for</strong>mance is improved. If the predicate is<br />

used as an argument <strong>for</strong> a matching index, <strong>DB2</strong> does not need to read data pages not<br />

satisfying the predicate. On the other hand, if the predicate is stage 2, <strong>DB2</strong> has to read rows<br />

that do not satisfy the predicate and send them to further analysis.<br />

Chapter 3. SQL per<strong>for</strong>mance 65


.<br />

SELECT * FROM PAOLO.TORDER<br />

WHERE ORDERNO BETWEEN 15000 AND 17000<br />

STAGE 2<br />

PREDICATES<br />

1<br />

INDEXED<br />

predicate<br />

root<br />

page<br />

DBAS<br />

Buffer<br />

Figure 3-24 Analysis of Stage 1 and Stage 2 predicates<br />

Stage 1 predicates are simple predicates evaluated by <strong>DB2</strong>. They are evaluated first to<br />

reduce processing cost and eliminate the number of rows to be evaluated by the complex<br />

predicates. Stage 2 predicates are complex predicates evaluated by <strong>DB2</strong>’s more complex<br />

analysis. They are also known as residual predicates.<br />

An indexable predicate is a predicate that can use a (matching) index access as an access<br />

path. Indexable predicates are always stage 1, but not all stage 1 predicates are indexable.<br />

Stage 1 predicates are better than stage 2 predicates.<br />

However, if your application has been coded in C on a work station, that language does not<br />

have a DECIMAL data type, although some of the existing tables might have columns defined<br />

as DECIMAL(p,s).<br />

Java does not have a fixed length character string data type; every string is variable length.<br />

66 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

STAGE 1<br />

PREDICATES<br />

2<br />

OTHER index key<br />

predicates applied<br />

some<br />

leaf<br />

pages<br />

TORDER<br />

.<br />

Applies ALL<br />

Stage 2<br />

Predicates<br />

4<br />

3<br />

Applies ALL<br />

other Stage 1<br />

predicates<br />

some<br />

data<br />

pages<br />

I/O<br />

ROWS<br />

PAGES<br />

GETPAGE results in<br />

I/O operation<br />

if the page is not in<br />

the BUFFERPOOL.<br />

GETPAGES<br />

Scans DATA<br />

PAGES from<br />

TORDER doing<br />

matching index<br />

scan from<br />

15000 to 17000


3.4.1 New indexable predicates in V7<br />

PTF UQ61237 <strong>for</strong> APAR PQ54042 resolves a case of incorrect output resulting from SQL<br />

statements that contain a BETWEEN predicate. The type of BETWEEN predicate that may<br />

have this problem is:<br />

col BETWEEN col-expression AND col-expression<br />

Where “col” is a simple column and “col-expression” is any expression involving a column.<br />

In addition, BETWEEN predicates of the <strong>for</strong>m:<br />

T1.COL BETWEEN T2.COL1 AND T2.COL2<br />

can now be indexable when accessing the table on the left hand side of the BETWEEN<br />

keyword if the tables on the right hand side of the BETWEEN keyword have already been<br />

accessed.<br />

3.4.2 More stage 1 and indexable predicates in V8<br />

In V8, more predicates with mismatched data types and mismatched lengths can be applied<br />

by <strong>DB2</strong>. This allows some stage 2 predicates to become stage 1 predicates, and stage 1<br />

predicates allow more index usage, and it applies to both join and local predicates.<br />

The potential <strong>for</strong> per<strong>for</strong>mance improvement with no application change is very significant.<br />

Note that mismatched string data types in join became stage 1 in V6.<br />

Mismatched numeric types<br />

Figure 3-25 shows an example of a predicate using mismatched numeric types that is stage 2<br />

in V7 and becomes stage 1 and indexable in V8 NFM.<br />

In the example, the selection of rows from employee table has to scan the table space in V7<br />

because the predicate indicates salary defined as decimal (12,2) is compared to a host<br />

variable defined as floating point that is stage 2.<br />

The same predicate is stage 1 in V8 and it allows matching index scan to find the rows <strong>for</strong> the<br />

execution of the SQL.<br />

Example of mismatched numeric type<br />

employee ( name character (20),<br />

salary decimal (12,2),<br />

deptid character (3) );<br />

SELECT * FROM employee<br />

WHERE salary > :hv_float ;<br />

in V7<br />

Stage-2 predicate<br />

Table space scan<br />

Figure 3-25 Example of mismatched numeric types<br />

V8<br />

Stage-1 predicate<br />

salary indexable<br />

Chapter 3. SQL per<strong>for</strong>mance 67<br />

.


But not all mismatched numeric types become stage 1. The exceptions that are still stage 2<br />

predicates are:<br />

► REAL -> DEC(p,s) where p >15<br />

where REAL is the right hand side predicate -> DEC(p,s) is the left hand side predicate<br />

► FLOAT -> DEC(p,s) where p >15<br />

– REAL or FLOAT column in the outer table of a join<br />

– REAL or FLOAT literal or host variable<br />

DEC_column > REAL_hostvar<br />

REAL and FLOAT values cannot be converted to decimal (the index column) with precision ><br />

15 without possibly changing the collating sequence.<br />

Mismatched string types<br />

Figure 3-26 shows examples of mismatched string types that were stage 2 in V7 and are<br />

stage 1 and indexable in V8 CM.<br />

Example of mismatched string types<br />

SELECT * FROM employee<br />

WHERE deptid = :HV ;<br />

Figure 3-26 Example of mismatched string types<br />

In the example, the selection of rows from the employee table has to scan the table space in<br />

V7 because the column DEPTID is defined as CHAR(3) and is compared to a string of four<br />

characters. This is a stage 2 predicate in <strong>DB2</strong> V7.<br />

The same predicate is stage 1 in V8 and it allows a matching index scan.<br />

Not all mismatched string types become stage 1. The exceptions that are still stage 2<br />

predicates are:<br />

► graphic/vargraphic -> char/varchar<br />

where, <strong>for</strong> example, graphic is the right hand side predicate -> char is the left hand side<br />

predicate<br />

68 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

SELECT * FROM employee<br />

WHERE deptid = 'M60A' ;<br />

in V7<br />

or<br />

Stage-2 predicate<br />

Tablespace scan<br />

CHAR(3)<br />

V8<br />

:HV > 3 bytes<br />

Stage-1 predicate<br />

Could use index on<br />

deptid column


3.4.3 Per<strong>for</strong>mance<br />

► char/varchar(n1)-> char/varchar(n2)<br />

– where n1>n2 and not equal predicate<br />

► graphic/vargraphic(n1) -> graphic/vargraphic(n2)<br />

– where n1>n2 and not equal predicate<br />

► char/varchar(n1) -> graphic/vargraphic(n2)<br />

– where n1>n2 and not equal predicate<br />

Per<strong>for</strong>mance measurements were made to show the type of benefits that can be achieved<br />

using mismatched numeric data types and mismatched string types in predicates that were<br />

stage 2 in V7 and are stage 1 in V8.<br />

Mismatched numeric data types<br />

The measured query is a count of the rows of a result set of a SELECT joining two tables<br />

where the columns in the join predicate are INTEGER and DEC(8).<br />

Figure 3-27 shows the SQL text executed in V7 (with DEGREE(1) and DEGREE(ANY)) and<br />

V8, the PLAN_TABLE indicating the usage of an index to execute the join, and the measured<br />

elapsed and CPU times. The tables used here are the same as in Figure 3-13 on page 50.<br />

Mismatched numeric data types<br />

SELECT COUNT(*) FROM CV, PL<br />

WHERE PL.LP = 19861025<br />

AND CV.CS = PL. LP;<br />

Data type of LP is DEC(8)<br />

Index PLIX on LP column<br />

Data type of CS is INT<br />

Index CVIX on CS column<br />

V7 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

CVIX<br />

PLIX<br />

Figure 3-27 Mismatched numeric data types<br />

0<br />

1<br />

V8 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

PLIX<br />

CVIX<br />

0<br />

1<br />

0<br />

1<br />

1<br />

1<br />

Elapsed sec CPU sec<br />

The columns involved in this equi-join have different numeric data types: Column LP is<br />

DEC(8) and column CS is INT.<br />

V7 shows that table CV is joined with table PL using the nested loop join method. PL is<br />

accessed via a one column matching index only access. CV is accessed via a non-matching<br />

index only access that results in reading all leaf pages in the index.<br />

9<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

V7 DEGREE(1)<br />

V7 DEGREE(ANY)<br />

V8 DEGREE(1)<br />

6X<br />

16<br />

X<br />

Chapter 3. SQL per<strong>for</strong>mance 69


V8 shows that PL is joined with CV also using nested loop join method. But the sequence is<br />

different. Both tables are accessed via a one-column matching index only scan, but the<br />

access path in V8 is more efficient.<br />

Other measurement indicators are listed in Table 3-2.<br />

Table 3-2 Measurements <strong>for</strong> mismatched numeric data types<br />

Measurement V7 V8 Delta<br />

Elapsed time in sec. 7.9 1.4 -82%<br />

CPU time in sec. 5.8 0.3 -95%<br />

Work file getpages 0 0 0<br />

Data getpages 77 43 -44%<br />

Index getpages 2558 8 -99.7%<br />

Matching index 1 2 100%<br />

Mismatched string data types<br />

This measured query is a join of two tables where the local predicates have different lengths<br />

as shown in Figure 3-28.<br />

Figure 3-28 Different lengths <strong>for</strong> string data type<br />

The predicate comparing strings of different length becomes stage 1, and then the <strong>DB2</strong><br />

Optimizer changes the sequence of tables in the join to do an earlier filtering, resulting in<br />

better per<strong>for</strong>mance.<br />

70 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Different length <strong>for</strong> string data type<br />

SELECT BRN.REG,PLC.POL,LEN,PLC.BRA,<br />

CMA.SUR,TRC,CST,COV.CVI,LPC,CSC,CVT<br />

FROM BRN,PLC,COV,CIA,CMA,CLB,CCT,CAG<br />

WHERE PLC.BRN = BRN.BRN<br />

AND PLC.POL = COV.POL<br />

AND PLC.POL = CIA.POL<br />

AND PLC.POL = CAG.POL<br />

AND COV.POL = CIA.POL<br />

AND COV.POL = CAG.POL<br />

AND COV.CVI = CIA.CVI<br />

AND CIA.CLI = CLB.CLI<br />

AND CAG.CMA = CMA.CMA<br />

AND COV.CVC = CCT.CVC<br />

AND CST = 'MAILD ' /* CHAR(5) CHAR(6) */<br />

AND COV.CVT IN ('A ','B ','G ','P ')<br />

ORDER BY REG,PLC.POL,PLC.BRN,SUR;<br />

V7 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

COVIX<br />

PLCIX<br />

0<br />

1<br />

V8 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

CCTT<br />

COVIM<br />

0<br />

1<br />

0<br />

1<br />

0<br />

1<br />

12<br />

10<br />

8<br />

6<br />

4<br />

2<br />

0<br />

9.6X<br />

V7 DEGREE(1)<br />

V8 DEGREE(1)<br />

40 X<br />

Elapsed sec CPU sec


3.4.4 Conclusions<br />

Summary of measurements with a predicate comparing a string data type with different<br />

lengths:<br />

► Elapsed time in V7 = 10.65 sec. and in V8 = 1.11 sec. (reduction of 89%)<br />

► CPU time in V7 = 3.24 sec. and in V8 = 0.08 sec. (reduction of 97%)<br />

► Predicates comparing mismatched string data types are stage 1 and indexable with minor<br />

exceptions.<br />

► Predicates comparing mismatched numeric data types are stage 1 and indexable with<br />

minor exceptions.<br />

3.4.5 Recommendations<br />

► Consider rebinding plans or packages to get better access paths.<br />

► Consider creating an index <strong>for</strong> the mismatched columns to enable index access.<br />

3.4.6 Considerations on CASTing<br />

In <strong>DB2</strong> V7, we recommend you use the CAST function to make both data types the same.<br />

However, if you do this, first you add some overhead, and then you generally dictate the join<br />

sequence because <strong>DB2</strong> favors the index and picks the simple column side as inner table. Let<br />

us look at the following SELECT:<br />

SELECT *<br />

FROM CUST AS C, ORD_DEC AS O<br />

WHERE C.CUST_NO = O.CUST_NO;<br />

If you rewrite the predicate as ‘.CUST_NO = CAST(O.CUST_NO AS INTEGER)’, <strong>DB2</strong> very<br />

likely picks the CUST table as inner table. Furthermore, since ORD_DEC.CUST_NO is<br />

DEC(15,0), this has a bigger range than the INTEGER type. Unless you are very sure that all<br />

the values in the ORD_DEC.CUST_NO are within the range of INTEGER, the CAST may fail<br />

and <strong>DB2</strong> may return an error. In <strong>DB2</strong> V8, unless you really want to dictate the join sequence,<br />

it is better not to add any CAST and let <strong>DB2</strong> choose the join sequence based on costing.<br />

Generally this provides better per<strong>for</strong>mance.<br />

3.5 Multi-predicate access path enhancement<br />

Queries which contain two or more predicates referencing a table can get a better access<br />

path with statistics <strong>for</strong> a group of columns (non-indexed or non-leading index columns)<br />

collected by RUNSTATS in V8.<br />

Long running queries with skewed data distribution or column correlation type environment<br />

involving joins with multiple predicates on columns that are not the leading columns of an<br />

index or columns that do not participate in indexes are good candidates to benefit from<br />

improved access paths.<br />

The new access path in V8 can change the sequence of tables participating in joins involving<br />

multiple tables to take advantage of early filtering, and as a result, accessing fewer pages to<br />

execute the SQL statement.<br />

Chapter 3. SQL per<strong>for</strong>mance 71


Query per<strong>for</strong>mance problem<br />

Lack of multi-column statistics can cause a bad access path and poor query per<strong>for</strong>mance<br />

when a table is referenced by two or more equal, range or BETWEEN predicates.<br />

The possibility of hitting this problem increases when:<br />

► The number of predicates referencing one table increases<br />

► The number of joined tables in a query increases<br />

Two, often complementary, <strong>DB2</strong> V8 functions help with this issue:<br />

► Collecting additional statistics<br />

► Relying on <strong>DB2</strong> V8 better filter factor estimation<br />

Additional statistics<br />

Collecting cardinality and multi-column distribution statistics and rebinding is the first step to<br />

solve the problem. The Statistics Advisor, of Visual Explain V8, can generate automatically<br />

the RUNSTATS statement <strong>for</strong> the query, after using the Analyze function <strong>for</strong> a multi-predicate<br />

SQL text. See 6.4, “RUNSTATS enhancements” on page 272. Visual Explain is discussed in<br />

3.15, “Visual Explain” on page 110 and 3.15.3, “Statistics Advisor” on page 116.<br />

Example 3-6 shows one SQL statement text used as input to Visual Explain. This is the old<br />

query 5 used to verify the <strong>DB2</strong> Catalog consistency, discussed in Chapter 9, “Installation and<br />

migration” on page 341.<br />

Example 3-6 SQL text <strong>for</strong> Visual Explain<br />

SELECT DBNAME, NAME FROM SYS<strong>IBM</strong>.SYSTABLESPACE TS<br />

WHERE NTABLES <br />

(SELECT COUNT(*) FROM SYS<strong>IBM</strong>.SYSTABLES TB<br />

WHERE TYPE IN ('T', 'X','M')<br />

AND TB.DBNAME = TS.DBNAME<br />

AND TB.TSNAME = TS.NAME<br />

AND TS.NAME 'SYSDEFLT');<br />

The query has one correlated subquery.<br />

The outer query scans the SYS<strong>IBM</strong>.SYSTABLESPACE table which has the indicated number<br />

of tables NTABLES different from the counts of tables in the inner query based on table<br />

SYS<strong>IBM</strong>.SYSTABLES. For each qualified row in the outer table, the inner query is<br />

re-executed. Table type = “X” specifies auxiliary table at the current server <strong>for</strong> storing LOB<br />

data.<br />

The Explain function in Visual Explain <strong>for</strong> the SQL text results in the graphic <strong>for</strong> the access<br />

path selected by <strong>DB2</strong> V8 in Figure 3-29.<br />

72 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 3-29 Access path graph in Visual Explain<br />

If we click the rectangle indicating (4)SYSTABLESPACE in the graph, it shows that<br />

SYSTABLESPACE has 828 rows and it is estimated that approximately 794 rows of the table<br />

qualify in the table space scan.<br />

On the left side of the graph there is one tree structure that shows in<strong>for</strong>mation about the<br />

columns, indexes and table space related to the selected table SYSTABLESPACE. If there is<br />

a frequency distribution on one column of the table, under the respective column there is a<br />

Coldist folder. If you select i, you can see the values of the column and the filtering factor <strong>for</strong><br />

the value.<br />

For each qualified row in the outer table, the subquery is executed using a matching index<br />

scan using predicate TB.DBNAME=TS.DBNAME with filtering factor of 0.0098 returning 18<br />

RIDs.<br />

The report function generates in<strong>for</strong>mation about the cardinalities used. If there are no<br />

statistics available, default cardinality is used by the optimizer.<br />

Example 3-7 shows the RUNSTATS statement given by the Statistics Advisor of Visual<br />

Explain <strong>for</strong> the query in Example 3-6 after the execution of the analyze function. Visual<br />

Explain enhancements are reported in 3.15, “Visual Explain” on page 110.<br />

Example 3-7 RUNSTATS statement provided by the Statistics Advisor<br />

RUNSTATS TABLESPACE DSNDB06.SYSDBASE<br />

TABLE(SYS<strong>IBM</strong>.SYSTABLESPACE)<br />

COLUMN(NAME)<br />

TABLE(SYS<strong>IBM</strong>.SYSTABLES)<br />

COLUMN(TYPE,TSNAME)<br />

COLGROUP(TYPE) FREQVAL COUNT 10<br />

Chapter 3. SQL per<strong>for</strong>mance 73


3.5.1 Per<strong>for</strong>mance<br />

SORTDEVT SYSDA<br />

INDEX(SYS<strong>IBM</strong>.DSNDSX01,<br />

SYS<strong>IBM</strong>.SQLDTX01,<br />

SYS<strong>IBM</strong>.DSNDTX01,<br />

SYS<strong>IBM</strong>.DSNDTX03,<br />

SYS<strong>IBM</strong>.DSNDTX02 KEYCARD,<br />

HAA.TABLEIX)<br />

SHRLEVEL CHANGE REPORT YES<br />

Note that the RUNSTATS suggested by the Statistics Advisor specifies the new COLGROUP<br />

option introduced in V8 to collect frequency in a column group. For the table<br />

SYS<strong>IBM</strong>.SYSTABLESPACE the statistic is <strong>for</strong> the column NAME used as a predicate in the<br />

correlated subquery to have a better filter factor estimate. The statistic <strong>for</strong> indexes specifies<br />

one index <strong>for</strong> SYSTABLESPACE and five indexes <strong>for</strong> SYSTABLES.<br />

You may consider executing RUNSTATS to collect these statistics.<br />

In <strong>DB2</strong> V8, RUNSTATS can collect the most and least frequently occurring frequencies on<br />

almost any column or column group. RUNSTATS can also collect multi-column cardinality on<br />

almost any column group. See also 6.4, “RUNSTATS enhancements” on page 272.<br />

In many queries there are predicates on some matching and some screening columns. You<br />

can collect statistics to better reflect the total index filtering. When you have correlations and<br />

skews on some indexed and some non-indexed columns, you can collect statistics so the<br />

optimizer can more accurately estimate the number of rows which qualify from the table.<br />

The statistics that can be collected are:<br />

► Frequency distributions <strong>for</strong> (non-indexed) columns or groups of columns<br />

► Cardinality values <strong>for</strong> groups of non-indexed or non-leading index columns<br />

► LEAST frequently occurring values, along with M<strong>OS</strong>T <strong>for</strong> both indexed and non-indexed<br />

column distributions<br />

The new keywords: COLGROUP, M<strong>OS</strong>T, LEAST, BOTH, SORTNUM, and SORTDEVT<br />

Better filter factor estimation in V8<br />

<strong>DB2</strong> V8 can estimate a better filter factor by using statistics inference derivation. This can<br />

result in with or without the additional statistics mentioned earlier:<br />

► Improved query selectivity estimation using statistical inference on available statistics,<br />

when applicable<br />

► Queries which contain two or more predicates referencing a table may get better access<br />

paths<br />

► Significant per<strong>for</strong>mance improvement <strong>for</strong> some complex queries<br />

► Consider rebinding this type of query<br />

The per<strong>for</strong>mance measurements show the benefits with statistics on multiple columns.<br />

Better filter factor estimation<br />

Statistics on predicate columns allow the <strong>DB2</strong> optimizer to select a better access path as<br />

reported in the example in Figure 3-30.<br />

74 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Better filter factor estimation<br />

V7 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

TSS on PLO<br />

CLAIX<br />

CLBIX<br />

BLAIX<br />

0<br />

1<br />

4<br />

4<br />

Figure 3-30 Better filter factor estimation<br />

0<br />

2<br />

1<br />

1<br />

V8 PLAN_TABLE<br />

IXNAME METHOD MATCHCOL<br />

TSS on PLO<br />

BLAIX<br />

CLBIX<br />

CLAIX<br />

0<br />

1<br />

1<br />

1<br />

0<br />

1<br />

This figure shows a join of four tables and two join predicates between tables PLO and CLA.<br />

The plan table <strong>for</strong> V7 shows a join of table PLO and CLA using NLJ that is followed by a join<br />

to table CLB and BLA using hybrid join.<br />

In <strong>DB2</strong> V8, the same queries allow the <strong>DB2</strong> optimizer to find a better access path applying<br />

earlier a better filtering factor. The sequence of join of four tables changes: table BLA, that<br />

was processed last, becomes the second table scanned using NLJ, as the tables that follow.<br />

In <strong>DB2</strong> V8, the hybrid join method is not used.<br />

The measurements of this example show:<br />

► Elapsed time = 56.4 seconds in V7 to 19.1 seconds in V8 (66% reduction, a factor of 3)<br />

► CPU time = 39.1 seconds in V7 to 12.4 seconds in V8 (68% reduction, a factor of 3.2)<br />

The improvement ratio can be even more significant in complex queries involving more tables<br />

and more predicates.<br />

Access path improvements - multi-column statistics<br />

Measurements on other queries from the sample workload show improvements in CPU time<br />

resulting from a better access path as shown in Figure 3-31.<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

V7 DEGREE(1)<br />

V8 DEGREE(1)<br />

3X<br />

1<br />

0<br />

2 Elapsed sec CPU sec<br />

3.2X<br />

Chapter 3. SQL per<strong>for</strong>mance 75


3.5.2 Conclusions<br />

Figure 3-31 Access path improvements - Multi-column statistics<br />

Measurements of CPU time <strong>for</strong> top consuming queries:<br />

► Query Q7011<br />

CPU time = 132 sec. in V7 to 27 sec. in V8 (68% reduction, factor of 3.2)<br />

► Query Q2042<br />

CPU time = 76 sec. in V7 to 27 sec. in V8 (64% reduction, factor of 2.8)<br />

► Query Q800<br />

CPU time = 68 sec. in V7 to 66 sec. in V8 (2% reduction)<br />

The improvement ratio varies and tends to be more significant in complex queries involving<br />

more tables and more predicates.<br />

Multi-column statistics provided by the RUNSTATS utility in V8 allow <strong>DB2</strong> to better estimate<br />

the filtering factor <strong>for</strong> a query.<br />

This benefits queries with multiple predicates in one table and joins of multiple tables. As the<br />

number of predicates increases and the number of tables joined increases, there is more<br />

opportunity <strong>for</strong> improvements.<br />

3.5.3 Recommendations<br />

Access path improvements - multi-column statistics<br />

CPU Time (sec)<br />

150<br />

100<br />

Q2042<br />

Q200<br />

In case you are not satisfied with query per<strong>for</strong>mance, we recommend collecting the<br />

distribution statistics on the non-leading indexed columns and/or non-indexed columns, which<br />

are used as predicates in the query (<strong>for</strong> which there are no statistics in the catalog).<br />

Collecting these statistics can ensure <strong>DB2</strong> can use them <strong>for</strong> better access path selection.<br />

76 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

50<br />

0<br />

Q800 Q10002 Q1005<br />

Q7011 Q16203<br />

Query Number<br />

Q19<br />

V7<br />

V8


Consider this option if the long running queries involve multiple predicates in one table and<br />

joins of multiple tables. The Statistics Advisor function of Visual Explain helps significantly by<br />

suggesting statistics to be collected, and how to collect them, <strong>for</strong> the query. This is a better<br />

way to resolve bad access path problems than using OPTIMIZATION HINTS.<br />

Rebinding programs that contain an SQL statement with predicates on multiple, not indexed<br />

columns and joins, should also be considered.<br />

3.6 Multi-column sort merge join<br />

3.6.1 Per<strong>for</strong>mance<br />

In V7, when there is more than one predicate <strong>for</strong> the sort merge join, access path selection<br />

makes decisions based only on the first SMJ predicate. If there is a second predicate on SMJ,<br />

it is applied at a later stage. The new table in MCSMJ is always sorted, and query parallelism<br />

is disabled.<br />

In V8, access path selection supports multi-column predicates in SMJ. The new table is<br />

sorted or not, based on cost, and query parallelism is enabled <strong>for</strong> multi-column sort merge<br />

join (MCSMJ). This applies also in case of mismatched string data types. Mismatched<br />

numeric types, and DATETIME types are not supported yet. To summarize:<br />

► For char data types only, mismatched predicates on two and more col are allowed<br />

► Sort is now cost-based<br />

► Parallelism is allowed <strong>for</strong> MCMSJ<br />

Two examples are presented showing improved per<strong>for</strong>mance <strong>for</strong> multi-column sort merge<br />

join.<br />

The first example compares a two table join with mismatched data types executed in V7 and<br />

V8 without parallelism. The second example shows the same query without parallelism and<br />

with parallelism.<br />

Mismatched data types<br />

Figure 3-32 shows an example of MCSMJ.<br />

The join of two tables P and PX has two mismatched data type predicates, the first comparing<br />

CHAR(20) and VARCHAR(20), and the second comparing CHAR(10) and VARCHAR(10).<br />

The difference is in V7 the access path uses only one predicate, and in V8 it applies both<br />

predicates to process sort merge join. The elapsed time is reduced from 184 seconds in V7 to<br />

71.2 seconds in V8, without using parallelism in this case.<br />

The sort merge join processing multi-column in V8 reduces the amount of pages used by sort<br />

in the work file as a result of better filtering when compared to single column: 1648262<br />

getpages in V7 and 318540 getpages in V8 (reduction of 81%).<br />

Chapter 3. SQL per<strong>for</strong>mance 77


Mismatched data types<br />

SELECT COUNT(*) FROM P, PX<br />

WHERE P.KEY


3.6.2 Conclusion<br />

Figure 3-33 Query parallelism in V8<br />

Queries involving joins using MCSMJ (the method is likely to be used when the result set<br />

tends to be large) can have benefits because of access path enhancements due to better<br />

filtering when multiple columns are used as predicates.<br />

Enabling query parallelism in long running queries can give extra improvement in elapsed<br />

time, but generally an increase in CPU time.<br />

3.6.3 Recommendations<br />

Query parallelism in V8<br />

SELECT COUNT(*) FROM P,PX<br />

WHERE P.KEY < 1000<br />

AND P.BD_C20=PX.BD_VC20<br />

AND P.CT_C10 = PX.CT_VC10;<br />

Data type of P.BD is CHAR(20)<br />

Data type of P.CT is CHAR(10)<br />

V8 PLAN_TABLE<br />

DEGREE(ANY)<br />

TBNAME METHOD MATCHCOL<br />

Evaluate the usage of sort merge join in long running queries. V8 allows improvement if there<br />

are multi-column predicates in sort merge join. If the elapsed time is a concern, the query can<br />

be executed in shorter elapsed time if executed with query parallelism.<br />

3.7 Parallel sort enhancement<br />

PX<br />

P<br />

V8 PLAN_TABLE<br />

(continue)<br />

ACCESSTYE<br />

R<br />

I<br />

0<br />

2<br />

ACCESS<br />

DEGREE<br />

30<br />

?<br />

In V7, parallel sort has the following characteristics:<br />

► Parallel sort enabled <strong>for</strong> single-table sort composite only<br />

► Not cost-based decision<br />

► No threshold to disable parallel sort <strong>for</strong> short running queries<br />

0<br />

1<br />

JOIN<br />

DEGREE<br />

?<br />

3<br />

Elapsed sec CPU sec<br />

Sort composite tables from more than one table can have longer elapsed time because sort is<br />

not executed in parallel. If the composite table is from a single table, then parallel sort is<br />

invoked in V7.<br />

80<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

V8 DEGREE(1)<br />

V8 DEGREE(ANY)<br />

Chapter 3. SQL per<strong>for</strong>mance 79


3.7.1 Per<strong>for</strong>mance<br />

In V8 the parallel sort has been changed:<br />

► Parallel sort is enabled <strong>for</strong> single and multiple-table sort composite<br />

► Cost-based decision<br />

► Thresholds to disable parallel sort <strong>for</strong> short running queries<br />

– Total sort data size (


► Reduced improvement when merge pass is still required<br />

► Reduced improvement when query has two or more parallel sort composites to be merged<br />

Multiple table GROUP BY sort<br />

Let us look at the query in Example 3-8 where <strong>DB2</strong> executes a parallel sort when grouping 4<br />

million rows in 600,000 groups in a join of two tables.<br />

Example 3-8 Multiple table GROUP BY sort query<br />

SELECT C_CUSTKEY, C_NAME,<br />

SUM(O_ORDERKEY * 0.0001) AS REVENUE,<br />

C_ACCTBAL, C_NAME, C_ADDRESS, C_PHONE, C_COMMENT<br />

FROM CUSTOMER, ORDER<br />

WHERE C_MKTSEGMENT = 'BUILDING'<br />

AND C_CUSTKEY = O_CUSTKEY<br />

AND O_ORDERDATE < DATE('1994-12-05')<br />

GROUP BY C_CUSTKEY, C_NAME,<br />

C_ACCTBAL, C_NAME, C_ADDRESS, C_PHONE, C_COMMENT<br />

Figure 3-35 shows the per<strong>for</strong>mance improvement.<br />

Multiple table GROUP BY sort<br />

Group By sort of 4M rows to 0.6M groups<br />

nested loop join of 2 tables, 1 parallel group, DEGREE(30)<br />

merge pass used <strong>for</strong> both V7 and V8<br />

up to 46% reduction in elapsed time<br />

no reduction in workfile activities<br />

Fetch first 10<br />

rows<br />

Figure 3-35 Multiple table group by sort<br />

Elapsed<br />

secs<br />

CPU<br />

secs<br />

Workfile<br />

getpages<br />

Fetch all rows Elapsed<br />

secs<br />

CPU<br />

secs<br />

Workfile<br />

getpages<br />

V7<br />

Seq Sort<br />

V8<br />

Parallel<br />

Sort<br />

We observe, in the example of GROUP BY, the best situation is when we fetch the first 10<br />

rows (reduction of 46% in elapsed time) when V8 is compared to V7.<br />

Multiple table ORDER BY sort<br />

Let us look at the query in Example 3-9 where the ORDER BY is requested.<br />

Delta<br />

54 29 -46%<br />

73 72.6 -0.5%<br />

195400 193610 -1%<br />

102 85 -17%<br />

120 124 +4%<br />

255108 253304 -0.7%<br />

Chapter 3. SQL per<strong>for</strong>mance 81


3.7.2 Conclusions<br />

Example 3-9 Multiple table ORDER BY sort query<br />

SELECT C_CUSTKEY, C_NAME,<br />

O_ORDERKEY AS REVENUE,<br />

C_ACCTBAL, C_NAME, C_ADDRESS, C_PHONE, C_COMMENT<br />

FROM CUSTOMER, ORDER<br />

WHERE C_MKTSEGMENT = 'BUILDING'<br />

AND C_CUSTKEY = O_CUSTKEY<br />

AND O_ORDERDATE < DATE('1994-12-05')<br />

ORDER BY C_CUSTKEY, C_NAME,<br />

REVENUE,<br />

C_ACCTBAL, C_NAME, C_ADDRESS, C_PHONE, C_COMMENT<br />

Figure 3-36 shows the per<strong>for</strong>mance improvements <strong>for</strong> ORDER BY due to parallel sort.<br />

Multiple table ORDER BY sort<br />

Figure 3-36 Multiple table order by sort<br />

We observe in the example of ORDER BY the best situation is when we fetch the first 10 rows<br />

(reduction of 81% in elapsed time) when V8 is compared to V7. In this case there is also a<br />

significant reduction in the number of getpages <strong>for</strong> work files. No merge is needed because<br />

the rows are already in the right sequence.<br />

Parallel sort can improve the elapsed time of long running queries when parallelism is used<br />

as summarized in the following list:<br />

► Up to 6x elapsed time improvement observed with no merge pass<br />

► Typical queries have less improvement due to merge pass<br />

► May need bigger work file buffer pool size<br />

► May need to allocate more work files or use parallel access volume (PAV)<br />

► Work file getpage may increase when query has two or more parallel sort composites<br />

82 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

ORDER BY sort of 4M rows<br />

nested loop join of 2 tables, 1 parallel group, DEGREE(30)<br />

merge pass not needed <strong>for</strong> V8, rows already in order by sequence<br />

up to 4.7X reduction in elapsed time<br />

up to 3X reduction in workfile activities<br />

Fetch first 10<br />

Elapsed<br />

rows<br />

secs<br />

CPU<br />

secs<br />

Workfile<br />

getpages<br />

Fetch all rows Elapsed<br />

secs<br />

CPU<br />

secs<br />

Workfile<br />

getpages<br />

V7<br />

Seq Sort<br />

V8<br />

Parallel<br />

Sort<br />

Delta<br />

216 42 -81%<br />

88 74 -16%<br />

1221204 406994 -67%<br />

682 535 -22%<br />

550 557 +1%<br />

1627864 813712 -50%


3.7.3 Recommendations<br />

Parallel sort in V8 enables parallelism <strong>for</strong> multiple-table composite, is cost-based and is<br />

disabled <strong>for</strong> short running queries. When used, it affects the use of work files.<br />

► Parallel sort uses more work files concurrently<br />

► May need bigger work file buffer pool size<br />

► Monitor critical buffer pool shortage and adjust buffer pool size<br />

► Have sufficient number of work files to reduce contention<br />

► Use ESS DASD to benefit from PAV<br />

3.8 Table UDF improvement<br />

3.8.1 Description<br />

<strong>DB2</strong> allows you to specify the cardinality option passing the expected value when you<br />

reference a user-defined table function in an SQL statement. With this option, users give <strong>DB2</strong><br />

the in<strong>for</strong>mation needed <strong>for</strong> better tuning the per<strong>for</strong>mance of queries that contain user-defined<br />

table functions.<br />

The cardinality option <strong>for</strong> user-defined table functions is primarily intended <strong>for</strong> the integration<br />

of <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> with Content Manager to allow improved per<strong>for</strong>mance through better<br />

optimization.<br />

The table UDF improvement can be achieved by the conjunction of:<br />

► The cardinality option <strong>for</strong> a user-defined table function allows users to tune the<br />

per<strong>for</strong>mance of queries that contains user-defined table functions.<br />

► A join predicate between a user-defined function and a base table is stage 1, and possibly<br />

indexable, if the base table is the inner table of the join and the other stage 1 conditions<br />

are met.<br />

► Rows returned from a user-defined function are prefetched into a work file in its first<br />

invocation. This feature is enabled by <strong>DB2</strong> based on the access cost estimation.<br />

Queries involving user-defined table functions, in general, could benefit from this feature,<br />

when users can estimate the number of rows returned by the function be<strong>for</strong>e the queries are<br />

run. You should note that this option is a nonstandard SQL extension and specific to <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> implementation.<br />

User-defined table function<br />

The user-defined table function cardinality option indicates the total number of rows returned<br />

by a user-defined table function reference. The option is used by <strong>DB2</strong> at bind time to evaluate<br />

the table function access cost.<br />

A user-defined table function cardinality option can be specified <strong>for</strong> each table function<br />

reference in the following <strong>for</strong>ms:<br />

► A keyword CARDINALITY followed by an integer that represents the expected number of<br />

rows returned by the table function.<br />

► A keyword CARDINALITY MULTIPLIER followed by a numeric constant. The expected<br />

number of rows returned by the table function is computed by multiplying the given<br />

number of the reference cardinality value that is retrieved from the CARDINALITY field of<br />

SYS<strong>IBM</strong>.SYSROUTINES by the corresponding table function name that was specified<br />

when the corresponding table function was defined.<br />

Chapter 3. SQL per<strong>for</strong>mance 83


3.8.2 Per<strong>for</strong>mance<br />

We show three examples.<br />

Example 3-10 shows passing a multiplier value.<br />

Example 3-10 User-defined table function (1/3)<br />

SELECT *<br />

FROM TABLE(TUDF(1) CARDINALITY MULTIPLIER 30) AS X;<br />

If the cardinality was specified to be 1 when TUDF was defined, <strong>DB2</strong> assumes that the<br />

expected number of rows to be returned is 30 (30 x 1) <strong>for</strong> this invocation of user-defined table<br />

function TUDF.<br />

Example 3-11 shows a different multiplier.<br />

Example 3-11 User-defined table function (2/3)<br />

SELECT R<br />

FROM TABLE(TUDF(2) CARDINALITY MULTIPLIER 0.3) AS X;<br />

If the cardinality was specified to be 100 when TUDF was defined, <strong>DB2</strong> assumes that the<br />

expected number of rows to be returned by TUDF is 30 (0.3 x 100).<br />

Example 3-12 shows passing an absolute value.<br />

Example 3-12 User-defined table function (3/3)<br />

SELECT R<br />

FROM TABLE(TUDF(3) CARDINALITY 30) AS X;<br />

<strong>DB2</strong> assumes that the expected number of rows to be returned by TUDF is 30, regardless of<br />

the value in the table function.<br />

For more details on the specification of CARDINALITY and CARDINALITY MULTIPLIER, see<br />

the table-UDF-cardinality-clause section in <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SQL Reference,<br />

SC18-7426.<br />

Table UDFs are driven by Content Manager in all members of the <strong>DB2</strong> family:<br />

► Content Manager uses Text In<strong>for</strong>mation Extender/Text Extender to per<strong>for</strong>m text search<br />

► Results from the table UDF are joined with base or other tables<br />

Measurements show the per<strong>for</strong>mance improvements <strong>for</strong> the table UDF as a result of:<br />

► Cardinality option:<br />

– User/Extender can specify the cardinality of the table UDF in SQL levels<br />

– Better access path selection<br />

► Table UDF block fetch support<br />

– Materialize the rows from a table UDF into a work file at UDF open statement<br />

► Table UDF join predicates become sortable<br />

– Retrofitted into V7 as PQ54042<br />

Figure 3-37 shows that specifying the cardinality option in SQL reduced both the elapsed and<br />

CPU time.<br />

84 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Table UDF – Cardinality Option<br />

SELECT .....<br />

FROM ORDER A , TABLE(TUDF(100000 )<br />

CARDINALITY 100000) AS B<br />

WHERE A.cust_key = B.int_key<br />

AND A.order_key BETWEEN 1 AND 1500000 ;<br />

Access path is<br />

changed from<br />

NLJ to HBJ<br />

with correct<br />

cardinality<br />

value 100000<br />

Figure 3-37 Table UDF - Cardinality option<br />

Figure 3-38 shows the measurements with no block fetch and with block fetch.<br />

Table UDF – Block Fetch Support<br />

seconds<br />

seconds<br />

Figure 3-38 Table UDF - Block fetch support<br />

300<br />

250<br />

200<br />

150<br />

100<br />

150<br />

100<br />

50<br />

0<br />

50<br />

0<br />

10 100000<br />

cardinality<br />

Non block fetch Block fetch<br />

Elapsed<br />

CPU<br />

Elapsed<br />

CPU<br />

Block Fetch support<br />

Materialize the rows from a table UDF into a workfile at UDF open call<br />

CPU improvement by avoiding task switches.<br />

Native Measurement using a simple Table UDF<br />

Measured in 10 to 1M rows<br />

About 40% CPU time was saved using Block Fetch support or a simple Table UDF<br />

on Freeway Turbo<br />

Chapter 3. SQL per<strong>for</strong>mance 85


3.8.3 Conclusion<br />

The measurements show that SQL statements using user-defined table functions can have<br />

per<strong>for</strong>mance improvement if using the cardinality option. Improvements apply to applications<br />

related to Content Management.<br />

3.8.4 Recommendations<br />

Specify cardinality to help the optimizer<br />

Make sure you have sufficient work file buffers and data sets across I/O devices, preferably<br />

with the Parallel Access Volume feature:<br />

► To avoid work file I/O contention, especially with other concurrently running jobs<br />

► For high table UDF cardinality<br />

3.9 ORDER BY in SELECT INTO with FETCH FIRST N ROWS<br />

This function allows you to specify ORDER BY in the SELECT INTO statement. It enables<br />

SELECT INTO to get the top rows based on a user-specified ordering. This means you can<br />

now issue a single SQL statement where in the past you had to issue a number of SQL<br />

statements or even write a program.<br />

An example would be:<br />

SELECT INTO.... ORDER BY ANNUAL_INCOME FETCH FIRST 1 ROW ONLY<br />

In this case up to 30% CPU time reduction can occur when compared to the<br />

Open/Fetch/Close sequence which was required in V7 when there were multiple rows to be<br />

selected, no sort was required. Generally, the entire result set is retrieved and sorted be<strong>for</strong>e<br />

the first row is returned.<br />

3.10 Trigger enhancements<br />

Prior to <strong>DB2</strong> V8:<br />

► The AFTER trigger causes the creation of a work file <strong>for</strong> old and new transition variables at<br />

each trigger invocation<br />

► Work files are always created, even when the WHEN condition evaluates to false<br />

With V8:<br />

► Avoid work file allocation if the WHEN condition evaluates to false<br />

► Avoid work file allocation if the transition table fits into 4 KB of working storage.<br />

Use of memory rather than of work files <strong>for</strong> small transition tables or variable<br />

► Work files are allocated if the transition table exceeds the working storage<br />

Example 3-13 shows the creation of the row trigger used in the measurements.<br />

Example 3-13 Sample row trigger creation<br />

CREATE TRIGGER ADD_AFT<br />

AFTER INSERT ON USRT001.EMPLOYEE<br />

REFERENCING NEW AS NROW<br />

FOR EACH ROW MODE <strong>DB2</strong>SQL<br />

86 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


3.10.1 Per<strong>for</strong>mance<br />

WHEN (NROW.EMPDPTID='010')<br />

BEGIN ATOMIC<br />

UPDATE USRT001.DEPTMENT<br />

SET DPTDPTSZ = DPTDPTSZ + 1<br />

WHERE DPTDPTID = NROW.EMPDPTID;<br />

END;<br />

The sample trigger used in the per<strong>for</strong>mance measurement has:<br />

► Name: ADD_AFT<br />

► Trigger activated: AFTER the operation<br />

► Operation starting the trigger: INSERT<br />

► Subject table name: USRT001.EMPLOYEE<br />

► New transition variable correlation name: NROW<br />

► Granularity: FOR EACH ROW<br />

► Trigger condition: WHEN (NROW.EMPDPTID='010')<br />

► Trigger body:<br />

BEGIN ATOMIC<br />

UPDATE USRT001.DEPTMENT<br />

SET DPTDPTSZ = DPTDPTSZ + 1<br />

WHERE DPTDPTID = NROW.EMPDPTID;<br />

END;<br />

For more details on triggers, see Chapter 12. Using triggers <strong>for</strong> active data in the manual <strong>DB2</strong><br />

<strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Application Programming and SQL Guide, SC18-7415.<br />

Per<strong>for</strong>mance measurements were made in two cases:<br />

► 100 inserts activated trigger 100 times<br />

► 100 inserts activated trigger 100 times but WHEN condition evaluated to true only once<br />

The invocation of the triggers is via dynamic SQL. The triggers are static SQL.<br />

100 inserts activated trigger 100 times<br />

Figure 3-39 shows SQL and work file activity in V7 and V8 <strong>for</strong> the same SQL execution.<br />

Chapter 3. SQL per<strong>for</strong>mance 87


100 Inserts activated trigger 100 times<br />

SQL DML TOTAL<br />

-------- --------<br />

SELECT 0<br />

INSERT 100<br />

UPDATE 100<br />

DELETE 0<br />

DESCRIBE 100<br />

DESC.TBL 0<br />

PREPARE 100<br />

OPEN 0<br />

FETCH 0<br />

CL<strong>OS</strong>E 0<br />

DML-ALL 401<br />

Figure 3-39 SQL and BPOOL activity - Trigger 100 times<br />

The execution of 100 inserts activates the trigger 100 times executing update. With <strong>DB2</strong> V7,<br />

the buffer pool BP1 used by the work files indicates 600 getpages and 400 buffer updates. In<br />

<strong>DB2</strong> V8 there was no activity related to work files.<br />

Figure 3-40 compares the CPU times when executing triggers in V7 and V8.<br />

CPU time - lower is better<br />

Figure 3-40 CPU time when invoking the trigger 100 times<br />

The figure shows that the CPU used <strong>for</strong> non-nested (everything that is not in the trigger) was<br />

reduced by 8.0% and the CPU to execute the trigger was reduced by 5.5%.<br />

Generally a larger improvement can be anticipated by avoiding work files. In this case, such<br />

improvement is partially offset by the increase in CPU usage by going to V8.<br />

88 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 - workfile activity<br />

BP1 BPOOL ACTIVITY TOTAL<br />

--------------------- --------<br />

BPOOL HIT RATIO (%) 100<br />

GETPAGES 600<br />

GETPAGES-FAILED 0<br />

BUFFER UPDATES 400<br />

SYNCHRONOUS WRITE 0<br />

SYNCHRONOUS READ 0<br />

SEQ. PREFETCH REQS 100<br />

LIST PREFETCH REQS 0<br />

DYN. PREFETCH REQS 0<br />

PAGES READ ASYNCHR. 0<br />

100 Inserts activated Trigger 100 times<br />

0.02<br />

0.015<br />

0.01<br />

0.005<br />

0<br />

-8.0%<br />

-5.5%<br />

CPU non-nested CPU trigger<br />

<strong>DB2</strong> V8 - workfile activity<br />

BP1 no use reported<br />

<strong>DB2</strong> V7<br />

<strong>DB2</strong> V8


The accounting class 1 and class 2 CPU and elapsed times <strong>for</strong> triggers, stored procedures,<br />

and user-defined functions are accumulated in separate fields and exclude the time<br />

accumulated in other nested activity.<br />

For more details, see Chapter 24. Analyzing per<strong>for</strong>mance data in the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong><br />

<strong>Version</strong> 8 Administration Guide, SC18-7413.<br />

Inserts activated the trigger 100 times but WHEN condition true once<br />

Figure 3-41 shows the measurement when 100 inserts activated the trigger 100 times but 99<br />

times the WHEN condition evaluated false.<br />

100 Inserts activated Trigger 100 times<br />

but WHEN condition evaluated to true only once<br />

SQL DML TOTAL<br />

-------- --------<br />

SELECT 100<br />

INSERT 100<br />

UPDATE 1<br />

DELETE 0<br />

DESCRIBE 100<br />

DESC.TBL 0<br />

PREPARE 100<br />

OPEN 0<br />

FETCH 0<br />

CL<strong>OS</strong>E 0<br />

DML-ALL 401<br />

<strong>DB2</strong> V7 - workfile activity<br />

BP1 BPOOL ACTIVITY TOTAL<br />

--------------------- --------<br />

BPOOL HIT RATIO (%) 100<br />

GETPAGES 600<br />

GETPAGES-FAILED 0<br />

BUFFER UPDATES 400<br />

SYNCHRONOUS WRITE 0<br />

SYNCHRONOUS READ 0<br />

SEQ. PREFETCH REQS 100<br />

LIST PREFETCH REQS 0<br />

DYN. PREFETCH REQS 0<br />

PAGES READ ASYNCHR. 0<br />

Figure 3-41 SQL and BPOOL activity - Trigger with WHEN true only once<br />

<strong>DB2</strong> V8 - workfile activity<br />

BP1 no use reported<br />

The execution of 100 inserts caused the shown amount of work files activity, to actually<br />

execute the update in just one case. The 100 SELECTs shown in the accounting are due to<br />

the WHEN condition which causes 100 SELECTs to a DUMMY TABLE.<br />

In V7 the buffer pool BP1 used by the work files indicates 600 getpages and 400 buffer<br />

updates. In this case there was no activity related to the work files in V8.<br />

Figure 3-42 compares the CPU times when executing triggers in V7 and V8 and the WHEN<br />

condition is evaluated to true only once.<br />

The figure shows that the CPU used <strong>for</strong> non-nested was reduced 8.3% and the CPU to<br />

execute the trigger is reduced by a more visible 24%.<br />

Chapter 3. SQL per<strong>for</strong>mance 89


3.10.2 Conclusion<br />

100 Inserts activated trigger 100 times<br />

but WHEN condition evaluated to true only once<br />

0<br />

CPU non-nested CPU trigger<br />

.<br />

Figure 3-42 CPU time to invoke trigger but WHEN condition true once<br />

The measurements of execution of triggers show:<br />

► Saved work file usage<br />

► CPU saving <strong>for</strong> avoided work file allocation if the rows fit into the work space<br />

► Per<strong>for</strong>mance improvement depends on:<br />

– Complexity of triggering SQL<br />

– Complexity of SQL executed in the trigger<br />

– Number of times the triggers are invoked<br />

3.10.3 Recommendation<br />

You don’t need to do anything, not even REBIND, to have the per<strong>for</strong>mance benefit if you are<br />

using triggers that allocate work files.<br />

3.11 REXX support improvements<br />

CPU time - lower is better<br />

0.02<br />

0.015<br />

0.01<br />

0.005<br />

The per<strong>for</strong>mance of REXX programs accessing <strong>DB2</strong> tables is improved in V8 in the case of<br />

programs issuing large numbers of SQL statements.<br />

The improvement is due to two changes:<br />

► <strong>DB2</strong> V8 avoids loading and chaining control blocks <strong>for</strong> each REXX API invocation; they are<br />

now built only at initialization time and then pointed to <strong>for</strong> the successive API calls. This<br />

has reduced the CPU time.<br />

► The REXX exec points to the DSNREXX code. The change now loads the modules and<br />

keeps them in local application address space <strong>for</strong> the duration of the job whenever they<br />

have not been preloaded in LPA. This avoids accessing the modules again from disk. This<br />

90 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

-8.3%<br />

-24%<br />

<strong>DB2</strong> V7<br />

<strong>DB2</strong> V8


3.11.1 Per<strong>for</strong>mance<br />

3.11.2 Conclusion<br />

can provide a large elapsed time improvement in all cases where the DSNREXX module<br />

is not already loaded in LLA/VLF to reduce the module fetch time.<br />

Figure 3-43 shows the measurements of a REXX application fetching 100k rows from a table<br />

in V7 and V8. There are very significant reductions in elapsed time and some reduction in<br />

CPU time.<br />

Figure 3-43 REXX support improvement<br />

The measurements show that the elapsed time of programs in REXX language can be<br />

significantly reduced (if the DSNREXX module was not already preloaded by other means.)<br />

The improvement is larger with larger number of SQL statements.<br />

CPU time is also reduced.<br />

3.11.3 Recommendations<br />

REXX support improvement<br />

REXX application which issues 100k<br />

fetches against a TPCD table.<br />

Class 1 elapsed time 29X better than V7<br />

Class 1 CPU time 30% better<br />

You do not need to do anything to have the per<strong>for</strong>mance benefits if you are using REXX<br />

programs that issue a large number of calls.<br />

3.12 Dynamic scrollable cursors<br />

V7CL1 V8 CL1<br />

Be<strong>for</strong>e <strong>DB2</strong> V7, you could only scroll cursors in a <strong>for</strong>ward position. So when a cursor was<br />

opened, the cursor would be positioned be<strong>for</strong>e the first row of the result set. When a fetch was<br />

executed, the cursor would move <strong>for</strong>ward one row.<br />

<strong>DB2</strong> V7 introduced static scrollable cursors as cursors which can be scrolled backwards or<br />

<strong>for</strong>wards, and to an absolute position or to a relative position. They use a DECLARED<br />

TEMPORARY TABLE (DTT) introduced first in <strong>DB2</strong> V6. When the cursor is opened, <strong>DB2</strong><br />

3500<br />

3000<br />

2500<br />

2000<br />

1500<br />

1000<br />

500<br />

0<br />

Elapsed sec<br />

CPU sec<br />

Chapter 3. SQL per<strong>for</strong>mance 91


stores the selected columns from each qualifying base row in the result DTT and scrolling is<br />

per<strong>for</strong>med on this temporary table. <strong>DB2</strong> deletes the result table when the cursor is closed.<br />

Dynamic scrollable cursors are new with <strong>DB2</strong> V8. Dynamic scrollable cursors do not<br />

materialize the result table. Instead, they scroll directly on the base table and are there<strong>for</strong>e<br />

sensitive to all committed inserts, updates, and deletes. Dynamic scrollable cursors are<br />

supported <strong>for</strong> the index scan and table space scan access paths. DPSIs can also support<br />

dynamic scrollable cursors. Dynamic scrollable cursors can also be used with row-level<br />

operations or rowset-level operations.<br />

3.12.1 Static scrollable cursor description<br />

Static scrollable cursors introduced in V7 allow scrolling backwards as well as <strong>for</strong>wards. They<br />

also provide the capability to place the cursor to an absolute position or a position relative to<br />

the current cursor. In terms of per<strong>for</strong>mance, when a static scrollable cursor is opened, the<br />

qualifying rows are copied to a <strong>DB2</strong>-declared temporary table, also commonly known as the<br />

result table. This result table has a fixed (static) number of qualifying rows. Per<strong>for</strong>mance<br />

impact is based upon the number of qualifying rows that must be copied from the base table<br />

to the temporary table. Once the qualifying rows are copied to the temporary table, scrolling is<br />

then per<strong>for</strong>med on this table in either the <strong>for</strong>ward or backward direction, sequentially or to a<br />

specific row. When the cursor is closed, <strong>DB2</strong> deletes the result table.<br />

Dynamic scrollable cursors generally do not employ the usage of a temporary table.<br />

There<strong>for</strong>e, the single most important per<strong>for</strong>mance difference between static scrollable cursors<br />

and dynamic scrollable cursors is the overhead in building the result table, maintaining a<br />

consistent relationship between the base and result tables with an updatable cursor, and<br />

deleting the result table at close cursor <strong>for</strong> static scrollable cursors.<br />

Sensitivity options <strong>for</strong> static scrollable cursors<br />

A static scrollable cursor can be sensitive or insensitive to update, and can be sensitive or<br />

insensitive to changes made by other applications or outside of the cursor. These can be<br />

specified in the DECLARE CURSOR statement and FETCH statement. Table 3-3 outlines the<br />

available combinations, whether the cursor is read only or updatable, and whether the cursor<br />

is sensitive to changes to the base table.<br />

Table 3-3 Static cursor declare and fetch specifications<br />

Specification<br />

on DECLARE<br />

Specification<br />

on FETCH<br />

92 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Type of<br />

Cursor<br />

Comments<br />

Insensitive Insensitive Read-only Not aware of updates, deletes and inserts to<br />

base table<br />

<strong>DB2</strong> uses the predefined TEMP database and<br />

segmented table space to create your DTT and<br />

move in the results at execution time.<br />

Sensitive Insensitive Updatable Aware of own updates and deletes within the<br />

cursor.<br />

Changes by another agent are not visible to the<br />

cursor.<br />

Any inserts are not recognized.<br />

<strong>DB2</strong> uses the predefined TEMP database and<br />

segmented table space to create your DTT and<br />

move in the results at execution time.


Specification<br />

on DECLARE<br />

Specification<br />

on FETCH<br />

Type of<br />

Cursor<br />

Comments<br />

Sensitive Sensitive Updatable Aware of own updates and deletes within the<br />

cursor.<br />

Changes by another agent are visible to the<br />

cursor after commit.<br />

Any inserts are not recognized.<br />

<strong>DB2</strong> uses the predefined TEMP database and<br />

segmented table space to create your DTT and<br />

move in the results at execution time.<br />

The following is the description of the DECLARE CURSOR and FETCH options which were<br />

introduced in V7. The DECLARE CURSOR statement specifies that the cursor is scrollable by<br />

the SCROLL keyword. If SCROLL is specified, then you need to specify either INSENSITIVE<br />

or SENSITIVE STATIC. Any inserts are not visible in static scrollable cursors in every option,<br />

because <strong>for</strong> static scrollable cursors, inserts are not considered cursor operations and the<br />

result table is considered fixed after open cursor.<br />

► If you specify INSENSITIVE in DECLARE CURSOR, the scrollable cursor is strictly<br />

read-only. In a FETCH statement you can only specify INSENSITIVE. FETCH<br />

INSENSITIVE retrieves the row from the result table. The cursor is not sensitive to<br />

updates, inserts, and deletes made to the base table. So the application cannot see the<br />

changes made through the cursor, using positioned update and delete, nor the changes<br />

made outside the cursor.<br />

► If you specify SENSITIVE in DECLARE CURSOR, the scrollable cursor is updatable. In a<br />

FETCH statement you can specify INSENSITIVE or SENSITIVE to determine whether or<br />

not changes to the rows outside the cursor can be seen by the FETCH.<br />

– INSENSITIVE in a FETCH statement<br />

Applications can see the changes they have made themselves, using positioned<br />

updates or deletes through the cursor. In this case <strong>DB2</strong> updates both the base table<br />

and result table. However, updates and deletes to the base table made outside of the<br />

cursor are not visible to the application. The reason is that a FETCH INSENSITIVE<br />

cursor only accesses the result table, so the changes to the base table made outside<br />

the cursor are not visible.<br />

– SENSITIVE in a FETCH statement<br />

Applications can see the committed updates and deletes made by other applications<br />

outside the cursor, as well as changes they have made themselves using positioned<br />

and searched updates and delete through the cursor. A FETCH SENSITIVE first<br />

refreshes the rows in the DTT to pick up any committed updates and deletes from the<br />

base table, while a FETCH INSENSITIVE just returns the appropriate row from the<br />

DTT.<br />

Optimistic locking<br />

The static cursor model introduces the concept of optimistic locking. A specification of<br />

Isolation Level Cursor Stability (CS) can be used with Lock Size Row such that locks are held<br />

<strong>for</strong> the minimum duration because locking is optimistic in that no positioned update or delete<br />

occurs (lock/unlock the row), and even if it does, a new lock is acquired to compare the values<br />

between the base table and temporary table. In short, optimistic locking holds locks <strong>for</strong> the<br />

minimum duration, thereby increasing concurrency <strong>for</strong> that table. In addition, <strong>for</strong> applications<br />

that compare by value, it frees these applications from coding the comparison by moving this<br />

logic to the DBMS <strong>for</strong> better per<strong>for</strong>mance and less application code.<br />

Chapter 3. SQL per<strong>for</strong>mance 93


While there is no optimistic locking with the dynamic scrollable cursor model, it is also<br />

recommended that CS be used to achieve maximum concurrency. Since dynamic scrollable<br />

cursors are most useful <strong>for</strong> applications that want to see updated rows as well as newly<br />

inserted rows, specifying an isolation level of RS or RR restricts updates to the table by other<br />

users.<br />

3.12.2 Dynamic scrollable cursor description<br />

Dynamic scrollable cursors allow visibility of inserts as well as updates done by you or other<br />

users, while static scrollable cursors do not have a visibility to inserts. The differences of<br />

dynamic scrollable cursor compared to static scrollable cursor are:<br />

► Accesses the base tables directly<br />

► Inserts done into the base tables are visible<br />

► New options of DECLARE CURSOR statement:<br />

– DECLARE CURSOR ASENSITIVE<br />

– DECLARE CURSOR SENSITIVE DYNAMIC<br />

Dynamic scrollable cursors can be used with row-level or rowset-level operations, so DDF<br />

applications should use multi-row FETCH and positioned UPDATE/DELETE <strong>for</strong> multi-row<br />

FETCH.<br />

Sensitivity options <strong>for</strong> dynamic scrollable cursor<br />

In this section we show the syntax of the DECLARE CURSOR and FETCH statements<br />

associated with the dynamic scrollable cursors.<br />

DECLARE CURSOR statement<br />

There are some new options in V8 in the DECLARE CURSOR statement to support dynamic<br />

scrollable cursors. Figure 3-44 shows the syntax of the DECLARE CURSOR.<br />

DECLARE cursor-nam e<br />

Figure 3-44 DECLARE CURSOR syntax<br />

NO SCROLL is the default and indicates that the cursors are not scrollable. If you specify<br />

SCROLL, the cursors become scrollable. ASENSITIVE and SENSITIVE DYNAMIC are new<br />

options of scrollable cursors introduced in V8. INSENSITIVE and SENSITIVE STATIC are<br />

equivalent to static scrollable cursors in V7.<br />

The new two attributes of dynamic scrollable cursors determine the sensitivity of the cursors.<br />

► SENSITIVE DYNAMIC SCROLLABLE<br />

94 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

DECLARE CURSOR<br />

NO SCROLL<br />

ASENSITIVE<br />

IN S E N S ITIV E<br />

SENSITIVE<br />

STATIC<br />

DYNAMIC<br />

SCROLL<br />

CURSOR FOR select-statement<br />

WITH HOLD<br />

WITH RETURN<br />

statement-name


If you specify this option, the result table of the cursor is dynamic. It means that the size of<br />

the result table is not fixed and it may change depending on the changes made against<br />

rows in the underlying table after the cursor is opened. All inserts, updates, and deletes by<br />

the same application processes through the cursor are immediately visible. Also all<br />

positioned updates and deletes are immediately visible even be<strong>for</strong>e commit. And inserts<br />

and updates and deletes by other applications are visible once committed. No temporary<br />

result table is created <strong>for</strong> SENSITIVE DYNAMIC, since the FETCH statements are<br />

executed against the base table.<br />

► ASENSITIVE SCROLLABLE<br />

You can use this option, when you let <strong>DB2</strong> determine the sensitivity of the cursor. <strong>DB2</strong><br />

determines whether the cursor behaves as SENSITIVE DYNAMIC SCROLLABLE or<br />

INSENSITIVE (STATIC) SCROLLABLE depending on the update ability of the associated<br />

SELECT statement. ASENSITIVE CURSORS may then require TEMP database since<br />

they can resolve to INSENSITIVE cursors, depending on the SELECT statement.<br />

– The cursor behaves as an INSENSITIVE SCROLLABLE cursor, when the SELECT<br />

statement is read-only and does not allow the cursor to be sensitive. In these cases,<br />

access to the declared temporary table may be necessary.<br />

– The cursor provides maximum sensitivity, which is SENSITIVE DYNAMIC<br />

SCROLLABLE, when the cursor is not read-only.<br />

It is suitable <strong>for</strong> client applications that do not care about whether or not the server<br />

supports sensitivity.<br />

Note: There is no DYNAMIC option <strong>for</strong> INSENSITIVE. The syntax is SENSITIVE<br />

DYNAMIC SCROLLABLE cursor (the query cannot be read-only) or INSENSITIVE<br />

SCROLLABLE cursor (the query can be anything, but a temp table may be required <strong>for</strong><br />

materialization).<br />

The current conditions <strong>for</strong> read-only cursors are listed under Declare Cursor in Chapter 5<br />

of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SQL Reference, SC18-7426-01. The READ ONLY and<br />

FETCH ONLY clauses by themselves do not require a temporary data base.<br />

FETCH statement<br />

There is no new option in V8 to use dynamic scrollable cursors. All the positioning keywords<br />

<strong>for</strong> fetch (NEXT, PRIOR, FIRST, LAST, CURRENT, BEFORE, AFTER, ABSOLUTE, and<br />

RELATIVE) that were introduced in <strong>DB2</strong> V7 to support static scrollable cursors are equally<br />

relevant <strong>for</strong> dynamic scrollable cursors. However, there are some restrictions and<br />

considerations about the FETCH statement. Figure 3-45 shows the FETCH syntax.<br />

Chapter 3. SQL per<strong>for</strong>mance 95


FETCH<br />

FROM<br />

Figure 3-45 FETCH syntax<br />

INSENSITIVE<br />

SENSITIVE<br />

single-fetch-clause: ,<br />

These are implications on the FETCH statement using dynamic scrollable cursors:<br />

► The keyword INSENSITIVE is not allowed (SQLCODE -244) in the FETCH statement:<br />

– If the associated DECLARE CURSOR statement is specified as SENSITIVE DYNAMIC<br />

SCROLL, or<br />

– If the associated DECLARE CURSOR statement is specified as ASENSITIVE<br />

SCROLL, and <strong>DB2</strong> selects SENSITIVE DYNAMIC SCROLL <strong>for</strong> the associated<br />

SELECT statement.<br />

► SQLCODE +231 is returned in special cases<br />

– If FETCH CURRENT or FETCH RELATIVE +0 are requested, but the row on which the<br />

cursor is positioned has been deleted or updated so that it no longer meets the criteria.<br />

It happens only when using ISOLATION(CS) and CURRENT DATA(NO), which allows<br />

the row retrieved without taking locks.<br />

Data concurrency in dynamic scrollable cursors<br />

The characteristic of using dynamic scrollable cursors is that you can see immediately the<br />

newly updated or inserted or deleted data of your application. To get maximum data<br />

concurrency and get a high per<strong>for</strong>mance, you should use CURRENTDATA(NO) as a bind<br />

option and ISOLATION(CS) as an ISOLATION level.<br />

CURRENTDATA is a bind option which helps to determine the currency of data returned by<br />

an application cursor. In a local environment, CURRENTDATA can only have an impact <strong>for</strong> an<br />

application bound with ISOLATION(CS) and executing read-only queries which do not utilize<br />

a work file. The primary benefit in using CURRENTDATA(NO) is per<strong>for</strong>mance. This is<br />

especially true in a data sharing environment; using CURRENTDATA(NO) should reduce lock<br />

contention and CPU utilization.<br />

96 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

FETCH syntax<br />

cursor-name<br />

INTO host-variable<br />

INTO DESCRIPTOR<br />

NEXT<br />

PRIOR<br />

FIRST<br />

LAST<br />

CURRENT<br />

BEFORE<br />

AFTER<br />

ABSOLUTE host-variable<br />

integer-constant<br />

RELATIVE host-variable<br />

integer-constant<br />

descriptor-name<br />

single-fetch-clause<br />

No new syntax.<br />

Cannot specify<br />

INSENSITIVE -<br />

SQLCODE -244


3.12.3 Per<strong>for</strong>mance<br />

To describe the difference between CURRENTDATA(NO) and CURRENTDATA(YES), let us<br />

give you an example:<br />

1. Program A, bound with ISOLATION(CS) CURRENTDATA(YES), fetches a row from a<br />

cursor. The row was read from the base table and not from a work file.<br />

2. Program B tries to update the row just read by Program A. The access is not allowed<br />

because the CURRENTDATA(YES) option <strong>for</strong> Program A caused a lock to be acquired on<br />

the page or the row.<br />

3. Program A issues a searched UPDATE of the row just fetched from step 1.<br />

In this example you see that CURRENTDATA protects the integrity of the data read by<br />

Program A between the fetch and the searched UPDATE.<br />

If Program A were to be bound with CURRENTDATA(NO) then Program B would be able to<br />

access the row just fetched by Program A (assuming correct timing and that lock avoidance<br />

worked). When Program A issues its searched UPDATE, it can wipe out the changes just<br />

made by Program B. So with the CURRENTDATA(NO) option, you must ensure the program<br />

has read intent only, otherwise <strong>DB2</strong> advantages of avoiding taking a lock to increase data<br />

concurrency can be offset by data integrity issues.<br />

Binding a plan or package with ISOLATION(CS) indicates that the data fetched by a cursor to<br />

be committed, but if the application process returns to the same page, another application<br />

might have since updated, deleted, or inserted qualifying rows. If the cursor is defined as<br />

FOR UPDATE OF, the data returned by the cursor is stable and it may not be updated by<br />

another transaction while the updateable cursor is positioned on it. If the cursor is defined as<br />

read-only (or is ambiguous), then isolation level CS ensures that the data returned is<br />

committed and the stability of the cursor is determined by the CURRENTDATA option.<br />

If the application is bound with ISOLATION(RR) or ISOLATION(RS), the updates of the table<br />

by other users are strictly restricted, you cannot acquire the advantage of using dynamic<br />

scrollable cursors, since a row or page lock is held <strong>for</strong> all accessed rows at least until the next<br />

commit point.<br />

Several measurements, using different types of programs, have been implemented. There are<br />

four scenarios. The first two cases deal with single-row processing. They compare static<br />

scrollable cursors and dynamic scrollable cursors <strong>for</strong> FETCH and UPDATE programs. The<br />

other two cases deal with multi-row processing. They compare single-row and multi-row<br />

processing when using static or dynamic scrollable cursors <strong>for</strong> FETCH and UPDATE<br />

programs.<br />

Hardware and software environment<br />

All the test cases use the following environment:<br />

► Hardware: <strong>IBM</strong> z900 Series 2064-216 (z900 turbo)<br />

– One LPAR with 2 dedicated processors<br />

– 7 GB real storage<br />

– Dedicated ESS model 800 (ESS)<br />

– 4 dedicated FICON channels<br />

► Software<br />

– z/<strong>OS</strong> V1.4<br />

– <strong>DB2</strong> V8<br />

– Non-data sharing<br />

Chapter 3. SQL per<strong>for</strong>mance 97


► Measurement data collected with <strong>DB2</strong> Per<strong>for</strong>mance Expert V2<br />

– Accounting trace class 1,2,3<br />

– Statistics trace class 1,3,4,5,6,8<br />

Measurement methodology<br />

► One table defined in one segmented table space is used <strong>for</strong> all measurements.<br />

► All the measurements involved only table space scans (1 index is defined).<br />

► First time effect<br />

Bring up the <strong>DB2</strong> subsystem be<strong>for</strong>e each measurement to clear the data in the buffer pool,<br />

eliminating the inconsistency of different buffer hit ratios from run to run.<br />

► No concurrency issues<br />

There is no other program accessing the table space during the measurements.<br />

► Read programs are bound with ISOLATION(CS) and CURRENT DATA(NO)<br />

► Update programs are bound with ISOLATION(RS)<br />

► Each program issues one commit after closing the cursor<br />

Measurement cases<br />

► Read cursor (single row fetch) - Static vs. dynamic<br />

► Update cursor (single row fetch and update) - Static vs. dynamic<br />

► Multi-row FETCH using static or dynamic cursors - Single row vs. multi-row<br />

► Multi-row FETCH and UPDATE or DELETE using static or dynamic cursors - Single row<br />

vs. multi-row<br />

3.12.4 Test description and study<br />

The following is the description of our four test cases and study from our measurement data.<br />

The programs are all written in PL/I.<br />

Test scenario 1: Read cursor - Static vs. dynamic<br />

This test uses two types of FETCH programs. The intent is to compare insensitive with<br />

asensitive cursors <strong>for</strong> static and dynamic.<br />

The first program, shown in Example 3-14, declares an insensitive scrollable cursor to retrieve<br />

data from the table. It means this program is strictly read-only (does not allow positioned<br />

update and delete).<br />

Example 3-14 Read program of static cursor<br />

DECLARE C1 INSENSITIVE SCROLL CURSOR WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6, COL7, COL8, COL9, COL10<br />

FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’;<br />

DO I = 1 TO 50000;<br />

FETCH INSENSITIVE NEXT C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

END;<br />

98 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The second program, shown in Example 3-15, declares an ASENSITIVE SCROLLABLE<br />

cursor, which is the default in DECLARE CURSOR of V8. ASENSITIVE scrollable cursors<br />

allow <strong>DB2</strong> to choose the maximum sensitivity of a cursor as possible, and in this case the<br />

following SELECT statement does not indicate read-only cursor (that is, a UNION or UNION<br />

ALL, ORDER BY, FOR READ ONLY, FOR FETCH ONLY) so <strong>DB2</strong> determines dynamic as the<br />

maximum sensitivity.<br />

Example 3-15 Read program of dynamic cursor<br />

DECLARE C1 ASENSITIVE SCROLL CURSOR WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6, COL7, COL8, COL9, COL10<br />

FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’;<br />

DO I = 1 TO 50000;<br />

FETCH NEXT C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

END;<br />

The measurements have been done varying the number of FETCHes and the number of<br />

qualified rows opened as a cursor. This is done to show how the per<strong>for</strong>mance is affected by<br />

different result set sizes (the size of the temporary table in the case of the static cursor<br />

examples). The summary of our test cases is:<br />

► Use ISO(CS) and CD(NO) as a bind parameter<br />

For the read program these options provide maximum per<strong>for</strong>mance and concurrency.<br />

► 50k or 10 FETCHes<br />

► FETCH of 10 columns <strong>for</strong> a total of 50 bytes<br />

► Qualified 1 million or 100k rows opened as a cursor<br />

In the program shown in Example 3-17, we specified 1,000,000 or 100,000 in<br />

‘ROWnnnnnnnnn’ row-id.<br />

Table 3-4 shows the test results <strong>for</strong> static and dynamic cursors from the output of the <strong>DB2</strong> PE<br />

trace record.<br />

Table 3-4 Read cursor - Static vs. dynamic<br />

Trace data Static Dynamic<br />

Class 1<br />

ET/CPU<br />

Class 2<br />

ET/CPU<br />

Class 3<br />

suspend<br />

Fetch 50k<br />

Open 1M<br />

Fetch 10<br />

Open 1M<br />

Fetch 50k<br />

Open 100k<br />

Fetch 50k<br />

Open 1M<br />

Fetch 10<br />

Open 1M<br />

Fetch 50k<br />

Open 100k<br />

17.33/12.57 16.76/11.91 5.73 / 2.57 0.973/0.879 0.072/0.011 0.971/0.885<br />

17.21/12.44 16.75/11.90 5.61/ 2.43 0.849/0.743 0.069/0.009 0.849/0.748<br />

4.29 4.4 3.02 0.058 0.054 0.059<br />

Since the primary interest in this per<strong>for</strong>mance study is the <strong>DB2</strong> Class 2 CPU time and<br />

elapsed time, the PL/I programs were designed with minimum Class 1 (application) CPU and<br />

elapsed time in mind. There<strong>for</strong>e, the Class 1 CPU and elapsed times in all measurements is<br />

composed mainly of the <strong>DB2</strong> Class 2 CPU and elapsed times. The typical business<br />

Chapter 3. SQL per<strong>for</strong>mance 99


application has decidedly higher Class 1 CPU and elapsed times as reported in <strong>DB2</strong><br />

Per<strong>for</strong>mance Expert.<br />

Static read cursors<br />

By manipulating the number of fetches from 50k to 10, but keeping the result set size the<br />

same (1 million rows) you can see that the per<strong>for</strong>mance does not improve significantly (just<br />

over 4% improvement). This is because the overhead <strong>for</strong> opening and <strong>for</strong>matting the<br />

temporary table (class 3 suspend time) is essentially the same <strong>for</strong> both cases (4.29 vs. 4.40)<br />

and populating it with 1 million rows to build the result set in both cases consumes the<br />

majority of CPU cycles.<br />

However, in the third case, you can see a dramatic reduction of class 2 elapsed and CPU time<br />

when the qualified rows are changed from 1 million to 100k. In the static cursor case there are<br />

data movement I/Os from the base table to the temporary table, so in this case class 2<br />

elapsed and CPU time are dependent on the size of the temporary table to populate. Class 3<br />

time also decreases as the temporary table size decreases.<br />

As a conclusion, per<strong>for</strong>mance improvement <strong>for</strong> static scrollable cursors can be achieved, to a<br />

certain extent, by writing SQL statements that limit the result set read into the temporary table<br />

to only those rows that are essential.<br />

Dynamic read cursors<br />

See Table 3-4 again <strong>for</strong> the result trace record of the dynamic cursor case. Response times in<br />

all three cases are dramatically improved when compared against the static cursor. The<br />

elimination of <strong>for</strong>matting and building a result set into a temporary table when using the<br />

dynamic cursor model accounts <strong>for</strong> this dramatic per<strong>for</strong>mance improvement. Thus, comparing<br />

the static vs. dynamic cursor models, the <strong>DB2</strong> class 2 elapsed times are:<br />

► Fetch 50k / Result Set 1 M – 17.21 vs. 0.849 <strong>for</strong> 95% per<strong>for</strong>mance improvement<br />

► Fetch 10 / Result Set 1 M – 16.75 vs. 0.069 <strong>for</strong> 99% per<strong>for</strong>mance improvement<br />

► Fetch 50k / Result Set 100k – 5.61 vs. 0.849 <strong>for</strong> 85% per<strong>for</strong>mance improvement<br />

The important thing here is that the amount of FETCHes becomes the deciding factor <strong>for</strong> the<br />

dynamic cursor’s per<strong>for</strong>mance, whereas the number of qualifying rows was a deciding factor<br />

in the static cursor model. When the number of FETCHes is changed from 50k to 10, the CPU<br />

time is reduced from 0.849 to 0.069 <strong>for</strong> a 92% improvement. But the difference is not as large<br />

as in the case of static cursor, when the number of qualified rows is changed.<br />

Test scenario 2: Update cursor - Static vs. dynamic<br />

This case tests positioned updates and deletes. The intent is to compare sensitive cursors <strong>for</strong><br />

static and dynamic.<br />

As the sample program shows in Example 3-16, a static scrollable cursor is declared as<br />

SENSITIVE STATIC and specified as FOR UPDATE. It means that the cursor works as a<br />

cursor <strong>for</strong> a query to be used in positioned updates of the table. FETCH SENSITIVE is used<br />

in the program, so in each FETCH, <strong>DB2</strong> re-references the base table to pick up any<br />

committed updates or deletes.<br />

Example 3-16 Update program of static cursor<br />

DECLARE C1 SENSITIVE STATIC SCROLL CURSOR WITH HOLD<br />

FOR SELECT<br />

COL1, COL2, COL3, COL4,<br />

COL5,COL6 FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’<br />

FOR UPDATE OF COL6;<br />

100 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


DO I = 1 TO 1000;<br />

FETCH SENSITIVE NEXT C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6;<br />

UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;<br />

END;<br />

(Same <strong>for</strong> Deletes)<br />

Example 3-17 shows the program of a dynamic scrollable cursor. This program specifies<br />

explicitly DYNAMIC cursor in DECLARE CURSOR because the program is <strong>for</strong> update or<br />

delete.<br />

Example 3-17 Update program of dynamic cursor<br />

DECLARE C1 SENSITIVE DYNAMIC SCROLL CURSOR WITH HOLD<br />

FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6 FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’<br />

FOR UPDATE OF COL6;<br />

DO I = 1 TO 1000;<br />

FETCH SENSITIVE NEXT C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6;<br />

UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;<br />

END;<br />

(Same <strong>for</strong> Deletes)<br />

As in the previous test case, we now examine UPDATEs and DELETEs with different<br />

numbers of qualified rows. The summary description of this test case is:<br />

► Use ISO(RS) as a bind parameter<br />

This option protects data integrity (not <strong>for</strong> per<strong>for</strong>mance).<br />

► 100k or 10 FETCHes followed by 100k or 10 UPDATEs<br />

► 100k or 10 FETCHes followed by 100k or 10 DELETEs<br />

► FETCH of 6 columns <strong>for</strong> a total of 37 bytes<br />

► Qualified 1 M or 50k rows opened as a cursor<br />

The trace record results <strong>for</strong> a static and dynamic updatable cursor are listed in Table 3-5.<br />

Table 3-5 Update cursor static vs. dynamic<br />

Trace data Static Dynamic<br />

Class 1<br />

ET/CPU<br />

Class 2<br />

ET/CPU<br />

Class 3<br />

suspend<br />

UPDATE<br />

or<br />

DELETE<br />

1k<br />

Open 1M<br />

UPDATE<br />

or<br />

DELETE<br />

10<br />

Open 1M<br />

UPDATE<br />

or<br />

DELETE<br />

1k<br />

Open 50k<br />

UPDATE<br />

or<br />

DELETE<br />

1k<br />

Open 1M<br />

UPDATE<br />

or<br />

DELETE<br />

10<br />

Open 1M<br />

UPDATE<br />

or<br />

DELETE<br />

1k<br />

Open 50k<br />

16.44/11.51 15.75/11.16 4.95 / 1.33 0.601/0.148 0.218/0.016 0.508/0.144<br />

16.43/11.49 15.75/11.16 4.93 / 1.32 0.589/0.135 0.215/0.014 0.496/0.131<br />

4.5 4.31 3.56 0.454 0.195 0.364<br />

Chapter 3. SQL per<strong>for</strong>mance 101


Static updatable cursor<br />

You can see that, <strong>for</strong> the static cursor model, the per<strong>for</strong>mance characteristics are the same as<br />

<strong>for</strong> the read programs. SENSITIVE FETCHes with the static cursor refer to the base table.<br />

Buffer pool I/O to the data in the base table occurs in each FETCH. The change of the<br />

number of UPDATEs or DELETEs does not impact per<strong>for</strong>mance much when you compare the<br />

first two cases, both building a temporary table of 1 million rows. In the second case, where<br />

the SQL activity is reduced by a factor of 100, the per<strong>for</strong>mance improvement is only 2.9% <strong>for</strong><br />

class 2 CPU time, and 4% <strong>for</strong> class 2 elapsed time. Additional CPU time in accounting is<br />

consumed by extracting the qualified rows and inserting them into the temporary table.<br />

On the other hand, when the size of the temporary table is drastically reduced, but keeping<br />

the SQL activity constant, you can see a significant per<strong>for</strong>mance improvement: A <strong>DB2</strong> class 2<br />

CPU time improvement of 88.5% and a <strong>DB2</strong> class 2 elapsed time improvement of 70%.<br />

Dynamic updatable cursor<br />

The same characteristics as dynamic read cursor apply <strong>for</strong> the dynamic update cursor model.<br />

When we compare Case 2 where we are only updating 10 rows and deleting 10 other rows<br />

and compare that with Case 1 where we are updating and deleting 1,000 rows each, the class<br />

2 <strong>DB2</strong> CPU time shows a 89% improvement and the class 2 <strong>DB2</strong> elapsed time exhibits a<br />

63.7% improvement. On the other hand, when we keep the SQL activity the same (Case 1 vs.<br />

Case 3) and vary the size of the result set, the class 2 <strong>DB2</strong> CPU time only shows a 3%<br />

per<strong>for</strong>mance improvement, and the class 2 <strong>DB2</strong> elapsed time (0.589 vs. 0.496) shows a<br />

15.7% improvement. Dynamic updatable cursor per<strong>for</strong>mance is greatly dependent on the<br />

amount of SQL activity.<br />

Comparing static updatable cursors to dynamic updatable cursors using class 2 <strong>DB2</strong> elapsed<br />

times <strong>for</strong> the metric, you see:<br />

► UPDATE or DELETE 1k, result set 1 million – 16.43 vs. 0.589 <strong>for</strong> 96% per<strong>for</strong>mance<br />

improvement<br />

► UPDATE or DELETE 10, result set 1 million – 15.75 vs. 0.215 <strong>for</strong> 99% per<strong>for</strong>mance<br />

improvement<br />

► UPDATE or DELETE 1k, result set 50k – 4.93 vs. 0.496 <strong>for</strong> 90% per<strong>for</strong>mance<br />

improvement<br />

Test scenario 3: Multi-row processing with scrollable cursors<br />

<strong>DB2</strong> V8 introduces multiple-row processing <strong>for</strong> both the FETCH and INSERT statements.<br />

Fetching multiple rows of data with one SQL statement can be done with both scrollable<br />

(static and dynamic) and non-scrollable cursors. This enhancement helps to lower the SQL<br />

statement execution cost by reducing the number of trips between the application and<br />

database engine, and in a distributed environment reducing the number of send and receive<br />

network messages as well.<br />

Since the same per<strong>for</strong>mance principles apply regarding the size of the temporary table in the<br />

static cursor model and the size of the result set in the dynamic model, regardless of the<br />

single fetch or multi-fetch implementation, we only consider a temporary table size of 1 M <strong>for</strong><br />

the static cursor model and a result set size of 1 M <strong>for</strong> the dynamic cursor model in the<br />

following two test cases.<br />

We have discussed multi-row per<strong>for</strong>mance in 3.1, “Multi-row FETCH, INSERT, cursor<br />

UPDATE and DELETE” on page 31. So in this chapter we only describe the per<strong>for</strong>mance of<br />

multi-row FETCH and INSERT used in conjunction with static and dynamic scrollable cursor.<br />

102 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Single row vs. multi-row FETCH<br />

To test multi-row FETCH in static and dynamic scrollable cursors, we used two PL/I programs.<br />

BIND options and sensitivity options <strong>for</strong> the DECLARE CURSOR and FETCH statements are<br />

kept the same as the single row read cursor program. Each of the multi-row read programs<br />

fetches 100 rows (the row set size) with a single fetch and per<strong>for</strong>ms a total of 500 fetches to<br />

be compared against the original read program doing 50,000 individual fetches.<br />

Example 3-18 shows a sample of our program <strong>for</strong> multi-row FETCH using a static scrollable<br />

cursor.<br />

Example 3-18 Multi-row FETCH program of a static scrollable cursor<br />

DECLARE C1 INSENSITIVE SCROLL CURSOR WITH ROWSET P<strong>OS</strong>ITIONING WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6, COL7, COL8, COL9, COL10<br />

FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’;<br />

FETCH INSENSITIVE FIRST ROWSET FROM C1 FOR 100 ROWS INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

DO I = 1 TO 499;<br />

FETCH INSENSITIVE NEXT ROWSET<br />

C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

END;<br />

Example 3-19 shows a sample of our program <strong>for</strong> multi-row FETCH using a dynamic<br />

scrollable cursor.<br />

Example 3-19 Multi-row FETCH program of a dynamic scrollable cursor<br />

DECLARE C1 ASENSITIVE SCROLL CURSOR WITH ROWSET P<strong>OS</strong>ITIONING WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6, COL7, COL8, COL9, COL10<br />

FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’;<br />

FETCH FIRST ROWSET FROM C1 FOR<br />

100 ROWS INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

DO I = 1 TO 499;<br />

FETCH NEXT ROWSET<br />

C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,<br />

:COL6,:COL7,:COL8,:COL9,:COL10;<br />

END;<br />

In this test case we have not measured a different number of FETCHes or a different number<br />

of qualified rows, because the purpose of this case is the comparison of multi-row FETCH<br />

with single row FETCH. The summary of this test case is:<br />

► Use ISO(CS) and CD(NO) as a bind parameter<br />

These options provide maximum per<strong>for</strong>mance and concurrency <strong>for</strong> read programs.<br />

► 100 rows (rowset) of 500 FETCHes<br />

► Qualified 1 million at open cursor<br />

Chapter 3. SQL per<strong>for</strong>mance 103


Multi-row FETCH with a static cursor<br />

We apply multi-row fetching to the read programs and check how much we can improve<br />

per<strong>for</strong>mance. The 50,000 individual fetch case (listed in Case 1 in Table 3-4 on page 99) is<br />

compared with a multi-fetch program that fetches 100 rows at a time 500 times (listed in<br />

Table 3-6).<br />

Since the 1 million row temporary table is built row by row, regardless of the fetch<br />

implementation, and since we learned that this activity takes up the majority of CPU cycles in<br />

the prior static cursor measurements (whether read or updatable programs), using the<br />

multi-fetch implementation has only improved the <strong>DB2</strong> class 2 CPU time by 3% (12.44 vs.<br />

12.05) and the <strong>DB2</strong> class 2 elapsed time by 2% (17.21 vs. 16.85).<br />

Table 3-6 Multi-row FETCH static<br />

Multi-row FETCH with a dynamic cursor<br />

The results of applying the same multi-fetch implementation to the dynamic cursor model are<br />

listed in Table 3-7. If we compare them to those of the 50,000 individual fetch program in<br />

Table 3-4 on page 99, Case 1, we see a large per<strong>for</strong>mance improvement. Both the <strong>DB2</strong> class<br />

2 elapsed time and CPU time have been cut in half: 0.743 vs. 0.340 and 0.849 vs. 0.426.<br />

Reducing the number of trips between the application and database engine by a factor of 100<br />

(50,000 fetches vs. 500 multi-fetches) accounts <strong>for</strong> the per<strong>for</strong>mance gains observed.<br />

Table 3-7 Multi-row FETCH dynamic<br />

Test scenario 4: Single row vs. multi-row FETCH & UPDATE or DELETE<br />

In this case we explored multi-row FETCH followed by UPDATE or DELETE. The multi-row<br />

write programs <strong>for</strong> update and delete use a row set size of 25 rows and per<strong>for</strong>m 40 fetches<br />

each. The multi-row updates or deletes are also per<strong>for</strong>med 25 rows at a time. So it is<br />

equivalent to 1,000 rows FETCHed and UPDATEd or DELETEd. We then compare it against<br />

single row FETCH and UPDATE or DELETE of 1,000 rows which was done as part of test<br />

scenario 2. Example 3-20 shows our multi-row FETCH and UPDATE program using a static<br />

scrollable cursor. Multi-row FETCH and DELETE programs are prepared similarly.<br />

Example 3-20 Multi-row FETCH program of a static scrollable cursor<br />

DECLARE C1 SENSITIVE STATIC SCROLL CURSOR WITH ROWSET P<strong>OS</strong>ITIONING WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4,<br />

COL5,COL6 FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’<br />

104 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Static single row<br />

FETCH 50,000<br />

Open 1 million<br />

Class 1 ET / CPU 17.33 / 12.57 16.85 / 12.06<br />

Class 2 ET / CPU 17.21 / 12.44 16.84 / 12.05<br />

Class 3 suspend 4.29 4.34<br />

Static single row<br />

FETCH 50,000<br />

Open 1 million<br />

Class 1 ET / CPU 0.973 / 0.879 0.440 / 0.343<br />

Class 2 ET / CPU 0.849 / 0.743 0.426 / 0.340<br />

Class 3 suspend 0.058 0.064<br />

Static multi-row<br />

FETCH 100 rows 500 times<br />

Open 1 million<br />

Static multi-row<br />

FETCH 100 rows 500 times<br />

Open 1 million


FOR UPDATE OF COL6;<br />

FETCH SENSITIVE FIRST ROWSET FROM C1 FOR 25 ROWS INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;<br />

UPDATE TABLE SET COL6 = :COL6+10 WHERE CURRENT OF C1;<br />

DO I = 1 TO 39;<br />

FETCH SENSITIVE NEXT ROWSET FROM C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;<br />

UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;<br />

END;<br />

(Same <strong>for</strong> Deletes)<br />

Example 3-21 shows our multi-row FETCH and UPDATE program using a dynamic scrollable<br />

cursor.<br />

Example 3-21 Multi-row FETCH program of a dynamic scrollable cursor<br />

DECLARE C1 SENSITIVE DYNAMIC SCROLL CURSOR WITH ROWSET P<strong>OS</strong>ITIONING WITH HOLD FOR SELECT<br />

COL1, COL2, COL3, COL4, COL5,<br />

COL6 FROM TABLE<br />

WHERE COL2 < ‘ROWNNNNNNNNN’<br />

FOR UPDATE OF COL6;<br />

FETCH SENSITIVE FIRST ROWSET FROM C1 FOR 25 ROWS INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;<br />

UPDATE TABLE SET COL6 = :COL6+10 WHERE CURRENT OF C1;<br />

DO I = 1 TO 39;<br />

FETCH SENSITIVE NEXT ROWSET FROM C1 INTO<br />

:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;<br />

UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;<br />

END;<br />

(Same <strong>for</strong> Deletes)<br />

The summary of this test case is:<br />

► Use ISO (RS) as a bind parameter<br />

These options protect data integrity (not <strong>for</strong> per<strong>for</strong>mance).<br />

► 40 FETCHes followed by UPDATE on a rowset of 25 rows<br />

► 40 FETCHes followed by DELETE on a rowset of 25 rows<br />

► Qualified 1 million rows at open cursors<br />

Multi-row FETCH and UPDATE or DELETE with a static cursor<br />

We now move to the static updatable programs and apply multi-row update and delete<br />

function. The results are shown in Table 3-8. We can see the same per<strong>for</strong>mance apply to this<br />

type of program, the bulk of the per<strong>for</strong>mance overhead is attributable to the building of the<br />

temporary table, resulting in negligible differences in <strong>DB2</strong> class 2 elapsed and CPU times:<br />

16.43 vs. 16.39 and 11.49 vs. 11.44.<br />

Table 3-8 Multi-row FETCH and UPDATE or DELETE static<br />

Static single row<br />

UPDATE or<br />

DELETE 1k each<br />

Open 1M<br />

Class 1 ET / CPU 16.44 / 11.51 16.40 / 11.45<br />

Class 2 ET / CPU 16.43 / 11.49 16.39 / 11.44<br />

Class 3 suspend 4.50 4.51<br />

Static multi-row<br />

UPDATE or DELETE 25 rows<br />

x 40 times each<br />

Open 1M<br />

Chapter 3. SQL per<strong>for</strong>mance 105


3.12.5 Conclusion<br />

Multi-row FETCH and UPDATE or DELETE with a dynamic cursor<br />

We now apply the multi-row update and delete function to the updatable programs in the<br />

dynamic cursor model. The results are shown in Table 3-9. They show a 17.8% per<strong>for</strong>mance<br />

improvement in <strong>DB2</strong> class 2 CPU time (0.135 vs. 0.111) and a 7% per<strong>for</strong>mance improvement<br />

in <strong>DB2</strong> class 2 elapsed time (0.589 vs. 0.547).<br />

Table 3-9 Multi-row FETCH and UPDATE or DELETE dynamic<br />

Multi-row update and delete with the dynamic cursor model result in significant per<strong>for</strong>mance<br />

improvements over the static cursor model, but the multi-row fetch <strong>for</strong> update programs does<br />

not improve as dramatically as the multi-row fetch <strong>for</strong> read-only programs. Compare them to<br />

Table 3-7 on page 104. This is because with the read-only programs <strong>for</strong> multi-row fetch the<br />

bulk of the <strong>DB2</strong> CPU time is the reduction of the number of trips between the application and<br />

database engine, which has been reduced by a factor of 100 (fetching 100 rows 500 times vs.<br />

50,000 individual fetches). When we apply multi-row fetch to the update program, the <strong>DB2</strong><br />

CPU and elapsed times are not only accounting <strong>for</strong> the reduced number of trips between the<br />

application and database engine <strong>for</strong> the fetches, but also the update (1,000 rows per<strong>for</strong>med<br />

25 rows at a time) and delete (1,000 rows also per<strong>for</strong>med 25 rows at a time) activity. The<br />

update and delete activity is per<strong>for</strong>med on a rowset basis rather than individually, but it is a<br />

significant consumer of CPU cycles due to its complexity.<br />

For equivalent function, the dynamic cursor model generally outper<strong>for</strong>ms the static cursor<br />

model. The per<strong>for</strong>mance overhead to build the temporary table with static cursors is the<br />

largest contributor of CPU overhead. For the dynamic cursor model, since all accesses are<br />

per<strong>for</strong>med on the base table, the amount of SQL activity (from a <strong>DB2</strong> class 2 perspective)<br />

becomes the deciding factor.<br />

When multi-row processing is applied to static cursors (whether read or updatable), since the<br />

temporary table is built row-by-row, regardless of the fetch implementation, this new feature<br />

with <strong>DB2</strong> V8 does not contribute significantly, at least with this amount of DML activity. But <strong>for</strong><br />

dynamic read cursors, multi-row fetch shows per<strong>for</strong>mance gains of 50% <strong>for</strong> both <strong>DB2</strong> class 2<br />

CPU and elapsed times over the single fetch equivalent program. While the dynamic<br />

multi-row fetch and cursor update and delete program show significant improvement over its<br />

single fetch, update and delete equivalent program (17.8% improvement in <strong>DB2</strong> class 2 CPU<br />

time), it is not as high as just the multi-row fetch program due to the intrinsically more complex<br />

and costly functions of multi-row update and multi-row delete. In addition, the row set size <strong>for</strong><br />

the read-only multi-row fetch program was bigger (100 vs. 25) and resulted in less interaction<br />

between the application and database engine.<br />

3.12.6 Recommendations<br />

With a static cursor, class 3 time is heavily dependent on the size of the temporary table <strong>for</strong><br />

both read and updates. So it is important <strong>for</strong> the per<strong>for</strong>mance of a static scrollable cursor to<br />

106 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Dynamic single row<br />

UPDATE or<br />

DELETE 1k each<br />

Open 1M<br />

Class 1 ET / CPU 0.601 / 0.148 0.582 / 0.115<br />

Class 2 ET / CPU 0.589 / 0.135 0.547 / 0.111<br />

Class 3 suspend 0.454 0.433<br />

Dynamic multi-row<br />

UPDATE or DELETE 25 rows<br />

x 40 times each<br />

Open 1M


manage the number of qualifying rows and columns whenever possible. You should write<br />

SQL statements that limit the range of rows that are read into the temporary table.<br />

Although from a per<strong>for</strong>mance point of view dynamic scrollable cursors always outper<strong>for</strong>m the<br />

static cursor model, we do not recommend that the dynamic cursor model should always be<br />

used over the static cursor model. As mentioned previously, some customers appreciate the<br />

concept of optimistic locking (static cursor model only) since it contributes to concurrency.<br />

The static cursor model should be considered if you have a requirement <strong>for</strong> an application<br />

that must scroll back to a prior screen and retain and display the same values as be<strong>for</strong>e. Also,<br />

<strong>for</strong> gathering certain reports, such as average outstanding balance in a certain zip code,<br />

where the application programmer is not concerned about the minute-by-minute updates to<br />

the outstanding balance or the newly inserted or deleted accounts, the static cursor model<br />

with fetch insensitive can build these rows in a temporary table and permit the application to<br />

manipulate the rows as necessary, allowing concurrency to the base table.<br />

Besides per<strong>for</strong>mance, dynamic scrollable cursors are preferred when it is important <strong>for</strong> the<br />

application to see/access updated as well as newly inserted rows. Maximum concurrency can<br />

be achieved with isolation cursor stability.<br />

The summary of the recommendations <strong>for</strong> static and dynamic cursors is:<br />

► Static scrollable cursors can be the better solution if:<br />

– You need to scroll backwards to obtain initial values<br />

– You do not care about constant changes (such as business intelligence or<br />

representative samples).<br />

► Dynamic scrollable cursors can be preferable in situations where:<br />

– It is important <strong>for</strong> the application to access/see updated/inserted rows<br />

– Per<strong>for</strong>mance is important<br />

► Use multi-row operations whenever possible, particularly <strong>for</strong> the dynamic cursor model.<br />

3.13 Backward index scan<br />

With the enhancements introduced to support dynamic scrollable cursors, <strong>DB2</strong> also provides<br />

the capability <strong>for</strong> backward index scans. This allows <strong>DB2</strong> to avoid a sort and it can eliminate<br />

the need <strong>for</strong> an index. With this enhancement, available in CM, it is no longer necessary to<br />

create both an ascending and descending index on the same table columns.<br />

To be able to use the backward index scan, you must have an index on the same columns as<br />

the ORDER BY and the ordering must be exactly opposite of what is requested in the<br />

ORDER BY.<br />

For example, if you have created the index<br />

CREATE UNIQUE INDEX ON (A DESC, B ASC)<br />

then <strong>DB2</strong> V8 can do a <strong>for</strong>ward index scan <strong>for</strong> a<br />

SELECT ... FROM ... ORDER BY A DESC, B ASC<br />

and a backward index scan <strong>for</strong><br />

SELECT ... FROM ... ORDER BY A ASC, B DESC<br />

Chapter 3. SQL per<strong>for</strong>mance 107


While, <strong>for</strong><br />

or<br />

SELECT ... FROM ... ORDER BY A DESC, B DESC<br />

SELECT ... FROM ... ORDER BY A ASC, B ASC<br />

<strong>DB2</strong> still has to per<strong>for</strong>m a sort.<br />

Table 3-10 shows a set of test cases, in which we compare queries under V7 to V8. We<br />

assume that an ascending index on EMPO has been created <strong>for</strong> table EMP. Notice that the<br />

access type in the PLAN_TABLE is I in both directions.<br />

Table 3-10 Access type and sort with backward index scan<br />

Query <strong>DB2</strong> <strong>Version</strong> Access type in<br />

PLAN_TABLE<br />

SELECT EMPNO FROM EMP<br />

ORDER BY EMPNO ASC<br />

SELECT EMPNO FROM EMP<br />

ORDER BY EMPNO DESC<br />

SELECT EMPNO FROM EMP<br />

ORDER BY EMPNO ASC<br />

SELECT EMPNO FROM EMP<br />

ORDER BY EMPNO DESC<br />

3.14 Multiple distinct<br />

Prior to <strong>DB2</strong> V8, DISTINCT cannot be used more than once in a subselect, with the exception<br />

of its use with a column function whose expression is a column. That is, it is allowed to specify<br />

multiple DISTINCT keywords as an exception on the same column like:<br />

► SELECT COUNT(DISTINCT(C1)), AVG(DISTINCT(C1))<br />

However, if you use DISTINCT keywords more than once specifying different columns, you<br />

get SQLCODE -127 which means “DISTINCT IS SPECIFIED MORE THAN ONCE IN A<br />

SUBSELECT” occurs. For instance, in V7 you cannot have the following statement:<br />

► SELECT COUNT(DISTINCT(C1)), AVG(DISTINCT(C2))<br />

With <strong>DB2</strong> V8, you can use multiple DISTINCT keywords in the SELECT statement and<br />

HAVING clause. With <strong>DB2</strong> V8, the following queries are possible:<br />

► SELECT DISTINCT COUNT(DISTINCT C1), SUM(DISTINCT C2) FROM T1<br />

► SELECT DISTINCT COUNT(DISTINCT C1), COUNT(DISTINCT C2) FROM T1 GROUP<br />

BY A3<br />

► SELECT COUNT(DISTINCT C1), AVG(DISTINCT C2) FROM T1 GROUP BY C1<br />

► SELECT COUNT(DISTINCT(A1)) FROM T1 WHERE A3 > 0 GROUP BY A2 HAVING<br />

AVG(DISTINCT (A4)) > 1<br />

In these cases in V7 you have to divide the statements into multiple SELECT statements <strong>for</strong><br />

each distinct operation of columns. From the per<strong>for</strong>mance point of view, you have to execute<br />

multiple SELECT statements to retrieve the value in multiple columns.<br />

108 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Notes<br />

V7 I Base case<br />

V7 I Sort needed<br />

V8 I Same as V7<br />

V8 I Sort no longer<br />

required


3.14.1 Per<strong>for</strong>mance<br />

In V8 you can code SQL statements easily in one query when multiple distinct operations<br />

need to be done <strong>for</strong> multiple columns be<strong>for</strong>e any column functions, such as AVG, COUNT, or<br />

SUM are applied. This multiple distinct enhancement in V8 benefits usability of SQL by<br />

reducing the amount of SQL statements or simplifying some queries. And it supports <strong>DB2</strong><br />

family compatibility by making it easier to move your programs to another plat<strong>for</strong>m.<br />

Per<strong>for</strong>mance improvements are experienced when the multiple SQL statements are merged<br />

into one.<br />

The purpose of these measurements is to evaluate the improvement you can get by using a<br />

single query statement specifying multiple DISTINCT keywords <strong>for</strong> multiple columns<br />

compared to the case of using several query statements, each with one DISTINCT keyword.<br />

In these tests we SELECT columns of all DECIMAL data and GROUP BY an indexed column.<br />

First we measure the following sequence of four SELECT statements per<strong>for</strong>ming only one<br />

SELECT COUNT(DISTINCT) <strong>for</strong> each one of the four columns (no buffer pool flush in<br />

between):<br />

1. SELECT COUNT(DISTINCT C1), C5 FROM T1 GROUP BY C5;<br />

2. SELECT COUNT(DISTINCT C2), C5 FROM T1 GROUP BY C5;<br />

3. SELECT COUNT(DISTINCT C3), C5 FROM T1 GROUP BY C5;<br />

4. SELECT COUNT(DISTINCT C4), C5 FROM T1 GROUP BY C5;<br />

Then we measure the per<strong>for</strong>mance of multiple distinct statements specifying more than one<br />

DISTINCT keyword. These are the alternatives in <strong>DB2</strong> V8 to the above SELECT statements.<br />

We have three cases of using multiple COUNT(DISTINCT) on two, three, and four columns:<br />

5. SELECT COUNT(DISTINCT C1), COUNT(DISTINCT C2), C5 FROM T1 GROUP BY C5;<br />

6. SELECT COUNT(DISTINCT C1), COUNT(DISTINCT C2), COUNT(DISTINCT C3), C5<br />

FROM T1 GROUP BY C5;<br />

7. SELECT COUNT(DISTINCT C1), COUNT(DISTINCT C2), COUNT(DISTINCT C3),<br />

COUNT(DISTINCT C4), C5 FROM T1 GROUP BY C5;<br />

Figure 3-46 shows the percentage of improvement with the multiple distinct statements<br />

compared to the total time of the single distinct statements. We are comparing the total time<br />

of test cases 1 and 2 with test case 5, the sum of 1, 2, and 3, to test case 6, and the sum of 1,<br />

2, 3, and 4, to test case 7.<br />

The results show the percentage of the reduction of class 2 elapsed time and CPU time by<br />

using multiple distincts. When we merge two SELECT single distinct statements into one<br />

multiple distinct statement, there is a 40% elapsed time reduction. When we merge four<br />

SELECT single distinct statements into one multiple distinct statement, we observe more than<br />

55% elapsed time reduction.<br />

Chapter 3. SQL per<strong>for</strong>mance 109


3.14.2 Conclusion<br />

Percent reduction<br />

Figure 3-46 Multiple DISTINCT per<strong>for</strong>mance<br />

Multiple DISTINCT keywords in a single SELECT statement in V8 can largely enhance<br />

application per<strong>for</strong>mance, as well as usability of SQL. Specifying four distinct columns in one<br />

statement can make approximately 55% elapsed time improvement and 45% CPU<br />

improvement compared to the total time of the four individual statements. This improvement is<br />

due to reducing the overhead of multiple executions of queries and per<strong>for</strong>ming multiple sorts<br />

<strong>for</strong> multiple distinct columns.<br />

3.14.3 Recommendations<br />

Use multiple DISTINCT keywords in a single SELECT statement in your application as often<br />

as possible, eliminating unnecessary multiple queries. Per<strong>for</strong>mance advantages were found<br />

where there more than two DISTINCT clauses in one query.<br />

3.15 Visual Explain<br />

Visual Explain <strong>for</strong> <strong>DB2</strong> V8 provides graphical depictions of the access plans that <strong>DB2</strong><br />

chooses <strong>for</strong> your SQL queries and statements. Such graphs eliminate the need to manually<br />

interpret the PLAN_TABLE output filled by <strong>DB2</strong> EXPLAIN. See Appendix D, “EXPLAIN and its<br />

tables” on page 407 <strong>for</strong> its contents and the contents of the other EXPLAIN tables. The<br />

relationships between database objects, such as tables and indexes, and operations, such as<br />

table space scans and sorts, are clearly illustrated in the graphs. You can use this in<strong>for</strong>mation<br />

to tune your queries.<br />

Statistics Advisor is a brand new function of Visual Explain, and it is also available from the<br />

Web. Its main function is to help you identify the RUNSTATS executions that help your SQL.<br />

110 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Multiple DISTINCT per<strong>for</strong>mance<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

Time reduction when compared to invidual DISTINCTs<br />

1 2 3 4<br />

Number of DISTINCTs in one query<br />

Elapsed Time<br />

CPU Time


You can also use Visual Explain:<br />

► To generate customized reports on explicable statements<br />

► To view subsystem parameters<br />

► To view data from the plan table, statement table, and function table<br />

► To list SQL statements stored in the catalog (SYSSTMT and SYSPACKSTMT)<br />

Note: All these functions can be executed with a click in the corresponding icon in the<br />

Visual Explain icon bar.<br />

You can link to these suggestions directly from the graph. You can also link from the graph to<br />

additional statistics and descriptions <strong>for</strong> each object or operation that is used in the access<br />

plan.<br />

Each graph can display multiple query blocks, so that you can view the entire access plan in<br />

one graph. In previous versions of Visual Explain, each graph displayed only one query block.<br />

In this version, you still have the option to view only one query block at a time. You can use<br />

Visual Explain to catalog and uncatalog databases on your local machine, to list DSNZPARM<br />

parameters by installation field name, alphabetically by parameter name, or by installation<br />

panel name. You maintain Visual Explain by deleting old records from the EXPLAIN tables.<br />

With <strong>DB2</strong> V8 Visual Explain, you can save the access path graph <strong>for</strong> later use, because<br />

Visual Explain uses XML to store the graph in<strong>for</strong>mation. Every time that you EXPLAIN a<br />

statement, the access path graph is displayed on the Access Plan page of the Tune SQL<br />

notebook. On this page, select File → Save XML File to save the XML file to your local work<br />

station. To retrieve the graph, select File → Open XML File. You can also send the XML file to<br />

other people. If they have <strong>DB2</strong> Visual Explain installed, they can also see the graph.<br />

Note: Visual Explain has enhanced capabilities related to qualified rows estimates. It<br />

provides a wealth of predicate in<strong>for</strong>mation, more partition scan in<strong>for</strong>mation, and parallelism<br />

details.<br />

Visual Explain uses some sample stored procedures:<br />

► DSNWZP<br />

This stored procedure is required to support the Browse Subsystems Parameters function.<br />

The stored procedure is also used by Service SQL <strong>for</strong> collection and transmission of<br />

subsystem parameter settings to <strong>IBM</strong> service.<br />

► DSN8EXP<br />

This stored procedure (see also APARs PQ90022 and PQ93821) supports the EXPLAIN with<br />

stored procedure option. The purpose of EXPLAIN with stored procedure is to allow you to<br />

EXPLAIN SQL against objects against which you do not have the authority to execute<br />

queries. For example, a developer may have responsibilities <strong>for</strong> SQL per<strong>for</strong>mance on a payroll<br />

application, but may not have SELECT, INSERT, UPDATE, and DELETE access to the object.<br />

The developer can use the stored procedure to execute the Explain against the object. The<br />

developer does not need access to the objects, but the authority to execute the stored<br />

procedure.<br />

► DSNUTILS<br />

Statistics Advisor generates RUNSTATS statements. These RUNSTATS statements can be<br />

executed dynamically if you have a license to execute RUNSTATS, the DSNUTILS stored<br />

procedure is installed, and you have appropriate authority to execute the RUNSTATS<br />

Chapter 3. SQL per<strong>for</strong>mance 111


3.15.1 Installation<br />

commands. Of course, the RUNSTATS input can also be copied into a batch job and executed<br />

outside of Statistics Advisor.<br />

Installing the Java Universal Driver on <strong>DB2</strong> V8 provides Visual Explain with the stored<br />

procedures used by Visual Explain. See APAR PQ62695. Additionally, the stored procedure<br />

SYS<strong>IBM</strong>.SQLCAMESSAGE is installed. This provides error message descriptions <strong>for</strong> SQL<br />

errors in Visual Explain. For more in<strong>for</strong>mation, see the book <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390:<br />

Ready <strong>for</strong> Java, SG24-6435.<br />

Visual Explain is available <strong>for</strong> download from the Web site:<br />

http://www.ibm.com/software/data/db2/zos/osc/ve/index.html<br />

It is also part of the <strong>DB2</strong> Management Client Package (no charge feature of <strong>DB2</strong>) on a<br />

CD-ROM. After the install, you need to set up a JDBC connection. You can do so by using the<br />

restricted-use copy of <strong>DB2</strong> Connect Personal Edition V8 <strong>for</strong> Windows which is provided with<br />

the Management Client Package.<br />

Instead of using the Configuration Assistant tool that comes with <strong>DB2</strong> Connect, you can set<br />

up your connection via Visual Explain. Make sure the <strong>DB2</strong> Connect packages have been<br />

previously bound on your target <strong>DB2</strong> system. If you are using a TCP/IP connection to the<br />

host, you need to have the port number from your subsystem. The configuration is very<br />

simple and straight<strong>for</strong>ward and all required in<strong>for</strong>mation can be entered on a single window.<br />

Visual Explain has a Help function which describes its features. For more details on the<br />

results provided by Visual Explain, and <strong>for</strong> more in<strong>for</strong>mation on how to use it, refer to section<br />

10.19, Visual Explain enhancements of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever<br />

Wanted to Know,... and More, SG24-6079.<br />

Note: When you run Visual Explain <strong>for</strong> the first time, Visual Explain tells you if you do not<br />

have the following tables: DSN_STATEMNT_TABLE, PLAN_TABLE,<br />

DSN_DETC<strong>OS</strong>T_TABLE, DSN_PREDICAT_TABLE, DSN_STRUCT_TABLE,<br />

DSN_FILTER_TABLE, DSN_SORT_TABLE, DSN_SORTKEY_TABLE,<br />

DSN_PGROUP_TABLE, DSN_PTASK_TABLE, DSN_PGRANGE_TABLE.<br />

And if you do not have them, Visual Explain creates them <strong>for</strong> you.<br />

3.15.2 Visual Explain consistency query analysis<br />

As an example, we are going to use Visual Explain to EXPLAIN one of the queries used <strong>for</strong><br />

catalog consistency checking. These queries are shipped in SDSNSAMP(DSNTESQ) to help<br />

you evaluate the health of your <strong>DB2</strong> catalog.<br />

But first we describe the access plan graph. This graph can contain three types of nodes:<br />

► Data source nodes<br />

A data source node represents a physical data store in the database, such as a table or<br />

index.<br />

► Operator nodes<br />

An operator node indicates an operation, such as a nested loop join, that is per<strong>for</strong>med on<br />

the data source, or on the result of a previous operation<br />

► Auxiliary nodes<br />

112 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


An auxiliary node includes any nodes that are neither data source nodes nor operator<br />

nodes.<br />

Both query nodes and query block nodes are classified as auxiliary nodes. Most of the nodes<br />

have corresponding descriptors, which store detailed in<strong>for</strong>mation about the data source,<br />

query, or operation that is represented by the node. The Descriptor window lists all of the<br />

attribute values <strong>for</strong> the data source, query, or operation that is represented by the node. From<br />

the Descriptor window, you can also link to any related descriptors. For example, from the<br />

descriptor <strong>for</strong> a table node, you can link to the descriptors <strong>for</strong> the indexes that are defined on<br />

that table.<br />

We use the consistency query 31, listed in Appendix 3-11, “Old consistency query 31” on<br />

page 113 to show an example of the EXPLAIN.<br />

Table 3-11 Old consistency query 31<br />

The old Query 31<br />

SELECT NAME<br />

FROM SYS<strong>IBM</strong>.SYSPLAN PL<br />

WHERE PLENTRIES = 0<br />

AND NOT EXISTS<br />

(SELECT * FROM SYS<strong>IBM</strong>.SYSDBRM WHERE PLNAME = PL.NAME);<br />

This query with correlated subquery selects the names of plans that have PLENTRIES=0 and<br />

have no DBRM pointing to the name of the plan. If you want more in<strong>for</strong>mation about the<br />

consistency query, take a look at 9.5, “Catalog consistency query DSNTESQ” on page 359.<br />

There you find some measurements and more details about it.<br />

Now let us analyze the Visual Explain from the Query 31. Figure 3-47 shows the EXPLAIN<br />

and tells us that the cost of CPU is 2 milliseconds (in service units the cost is 32).<br />

Chapter 3. SQL per<strong>for</strong>mance 113


Figure 3-47 Explain of the old consistency query 31<br />

Note: We are using a very small catalog, that is why the numbers are so small. But we want to give<br />

just an idea on how useful Visual Explain can be <strong>for</strong> tuning queries.<br />

If we click on the top node (1) QUERY, the attributes of the node QUERY appear on the left<br />

hand side window in<strong>for</strong>ming us that:<br />

► CPU cost (ms): 2<br />

► CPU cost (SU): 32<br />

► Cost category: A<br />

This in<strong>for</strong>mation is taken from the table DSN_STATEMNT_TABLE that has been updated by<br />

the EXPLAIN statement execution. The CPU cost in milliseconds is the cost in service units<br />

divided by the number of service units that the machine where <strong>DB2</strong> is running can do in one<br />

millisecond.<br />

The chart shows that this query has two query blocks. The first query block accesses the<br />

table SYSPLAN. If we click the node <strong>for</strong> table (6) SYSPLAN, the attributes of the table pop up<br />

in<strong>for</strong>ming us of:<br />

► Table Name: SYSPLAN<br />

► Creator Name: SYS<strong>IBM</strong><br />

► Correlation Name: PL<br />

► Cardinality: 61<br />

► Simple table space<br />

The attributes of the node appear on the left hand side of the graph showing as default the<br />

in<strong>for</strong>mation considered <strong>for</strong> cost estimation:<br />

► In<strong>for</strong>mation that appeared in the pop-up +<br />

► Qualifying rows: 14<br />

► Pages: 61<br />

114 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► Timestamp: 2004-11-15 13:44:36.771989 (RUNSTATS)<br />

► Explain time: 2004-11-19 14:56:24:34<br />

If we click the Index node (5) DSNPPH01, the in<strong>for</strong>mation about the index used to access<br />

SYSPLAN pops up: Fullkeycard of 61 and cluster ratio of 0.4918. The attribute side shows the<br />

number of leaf pages, number of levels, if the rows are clustered <strong>for</strong> this index, if the index is<br />

padded, and other in<strong>for</strong>mation.<br />

The index scan node (4) shows the number of input RIDs and output RIDs, scanned leaf<br />

pages, total filter factor, and number of matching columns <strong>for</strong> this scan.<br />

The fetch node shows a cardinality of 14. This is very interesting. The attribute of the fetch<br />

node shows:<br />

► Scanned rows: 61<br />

► Stage 1 predicate: PL. PLENTRIES=0. Filter factor: 0.459<br />

► Stage 1 returned rows: 28. If we calculate 61 * 0.459 = 27.999<br />

► Stage 2 predicate: NOT EXISTS(SELECT 1 FROM SYSDBRM WHERE<br />

SYSDBRM.PLNAME=PL.NAME); Filter factor: 0.5.<br />

► Stage 2 returned rows: 14<br />

For each entry in the index DSNPPH01 leaf page (no matching index scan) <strong>DB2</strong> has to go to<br />

the data portion to verify the predicate PL.PLENTRIES=0. PLENTRIES is the number of<br />

package list entries <strong>for</strong> the plan. The size of the row in SYSPLAN is 3613 bytes in a 4 KB<br />

page.<br />

Since this query is a correlated subquery, <strong>for</strong> each row in the outer table the inner query is<br />

re-executed. This subquery is an non-matching index-only scan, resulting in many scans to all<br />

leaf pages in the index PMSYSDBRM1 because the PLNAME is the second column of the<br />

index.<br />

So the largest impact comes from the time to scan all leaf pages <strong>for</strong> the entries in the index <strong>for</strong><br />

the table SYSDBRM. If the number of DBRMs is small, this can be a few pages, but if the<br />

catalog has a large number of DBRMs, <strong>for</strong> example, 20,000, and the index on columns<br />

PLCREATOR, PLNAME, has a key of 16 bytes, resulting in approximately 200 keys per page,<br />

there is a total of 100 leaf pages <strong>for</strong> each plan that has PLENTRIES=0.<br />

If there are 10,000 plans not using a package list, there are 10,000 scans of 100 pages.<br />

In this example we executed the query under Visual Explain and the output resulted in two<br />

rows.<br />

Let us take a look at the new Query 3, listed in Table 3-12.<br />

Table 3-12 Consistency Query 31 New<br />

The new Query<br />

SELECT NAME FROM SYS<strong>IBM</strong>.SYSPLAN<br />

WHERE PLENTRIES = 0<br />

AND NAME NOT IN<br />

(SELECT PLNAME FROM SYS<strong>IBM</strong>.SYSDBRM);<br />

The new query is a non-correlated query. In a non-correlated subquery case the subquery is<br />

executed only once and the result of the query is materialized in the work file. The validation<br />

of the clause NOT IN is made in the sorted work file.<br />

The optimizer uses the process (scan, sort, work file) to make the per<strong>for</strong>mance better as<br />

shown in Figure 3-48. This change makes a nice difference when we compare the CPU cost<br />

Chapter 3. SQL per<strong>for</strong>mance 115


in ms = 1 and the CPU cost is 16 service units. We save 1 millisecond, or 16 SUs on<br />

accessing a very small catalog.<br />

Figure 3-48 Consistency query - 31 New<br />

3.15.3 Statistics Advisor<br />

Statistics Advisor is a new function from the Web, available with Visual Explain. Its main<br />

purpose is to help you identify the RUNSTATS executions that help your SQL. Sometimes it is<br />

not simple at all to understand which statistics can help your queries. The Statistics Advisor<br />

builds the RUNSTATS statements <strong>for</strong> the correct set of statistics, gives you consistent and<br />

accurate in<strong>for</strong>mation, and you just need to run the RUNSTATS and per<strong>for</strong>m some tests, and<br />

the problem is solved. You can continue to run the Statistics Advisor until it no longer provides<br />

suggestions.<br />

The Statistics Advisor (SA) analyzes the predicates, column (groups) used as predicates,<br />

type of predicates, per<strong>for</strong>ms statistical analysis, checks missing statistics (default), conflicting<br />

statistics, missing appropriate correlations, and skew statistics. Based on all of that, the<br />

Statistics Advisor gives you suggestions on the RUNSTATS to execute. Furthermore, it gives<br />

you an explanation and a conflict report.<br />

We use the following simple SQL statement against the EMP table of the <strong>DB2</strong> V8 sample<br />

database:<br />

SELECT * FROM DSN8810.EMP WHERE HIREDATE < '2004-12-31' AND SALARY < 25000 AND SEX = 'M';<br />

We start SA from the main panel, shown in Figure 3-49, where we enter the statement to be<br />

analyzed, explained, or run.<br />

116 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 3-49 Starting to analyze a sample query<br />

You can create a category to save all the related SQL. The related SQL can be automatically<br />

saved in a current command history category and you can rerun it anytime.<br />

Note: Be<strong>for</strong>e you run an EXPLAIN, you can run the Analyzer. If Statistics Advisor suggests<br />

a RUNSTATS, you can execute the RUNSTATS, then execute the Analyzer again,<br />

iteratively. When no more RUNSTATS are suggested, run EXPLAIN. And if you want to<br />

execute the query, just click EXECUTE.<br />

We click the ANALYZE button. The screen that pops up, when the analysis is completed,<br />

shows the targeted RUNSTATS statements.<br />

Figure 3-50 reports the RUNSTATS suggestion <strong>for</strong> the SQL statement we analyzed. You can<br />

execute that RUNSTATS directly from Visual Explain (VE), after configuring a WLM<br />

environment, by invoking DSNUTILS from Statistics Advisor.<br />

Chapter 3. SQL per<strong>for</strong>mance 117


Figure 3-50 Suggested RUNSTATS statements<br />

You can click the Explanation tab <strong>for</strong> an explanation of why the suggestions were made.<br />

Figure 3-51 is the report which shows you the explanation why Statistics Advisor suggests<br />

you run the RUNSTATS listed in Figure 3-50. You can save the report in HTML <strong>for</strong>mat just <strong>for</strong><br />

in<strong>for</strong>mation, or understand how the optimizer works, and Analyze it at any time.<br />

Figure 3-51 Reason <strong>for</strong> RUNSTATS<br />

Note that the table and index statistics are old, and column statistics have not been collected.<br />

Figure 3-52 shows the history of the saved queries.<br />

118 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 3-52 Saved queries<br />

We now execute the RUNSTATS (<strong>for</strong> large tables, running RUNSTATS in batch is best), and<br />

then rerun the SQL through SA to see if there are further suggestions.<br />

There are cases when one suggestion is not sufficient and you need to run the Statistics<br />

Advisor again to uncover another layer of problems.<br />

SA uses the existing statistics to make determinations about potential correlation and skew. If<br />

some columns have default statistics, then SA does not make any suggestions until the<br />

defaults are resolved. In this case, SA now suggests you collect frequency statistics on<br />

column SEX, as shown in Figure 3-53.<br />

Figure 3-53 New suggested RUNSTATS<br />

Chapter 3. SQL per<strong>for</strong>mance 119


Looking at the explanation, we can see that column SEX has COLCARDF of 2. This is a low<br />

COLCARDF. Columns with low cardinality (relative to table cardinality) have significant<br />

opportunity <strong>for</strong> skew, <strong>for</strong> that reason frequencies are desirable. The purpose of this example<br />

is to illustrate it may take two runs of SA to get more robust suggestions if defaults are initially<br />

provided. We obtain the statistics shown in Figure 3-54.<br />

Figure 3-54 Statistical output<br />

To illustrate conflict statistic checking, FULLKEYCARDF has been set to 100,000. The table<br />

cardinality is much lower. Rerunning SA returns a complete recollection. When statistics are<br />

conflicting, the issue is often due to an inconsistent statistics collection approach.<br />

We have observed some customers collecting statistics very aggressively on the indexes, and<br />

not on the tables, or vice versa. When index and table statistics are inconsistent, it can result<br />

in inaccurate estimations of filtering <strong>for</strong> an index, or join size. This can lead to inefficient<br />

access paths. SA can solve this problem quickly by identifying and suggesting recollection of<br />

inconsistent statistics, as shown in Figure 3-55.<br />

120 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 3-55 Recollection of inconsistent statistics<br />

The conflicts tab shows the statistics which were in conflict. See Figure 3-56.<br />

Figure 3-56 Conflicting statistics<br />

The DBA could make a judgement call based on these conflicts. The DBA can determine that<br />

only the index is inconsistent with the table cardinality, and limit the recollection.<br />

Since repeated partial statistic collections could result in a cycle of collecting "inconsistent<br />

statistics", SA is designed to collect a more complete and consistent set of statistics when<br />

inconsistent statistics are present <strong>for</strong> a table.<br />

Chapter 3. SQL per<strong>for</strong>mance 121


The Plug-In Options screen of Statistics Advisor is provided in Figure 3-57:<br />

Figure 3-57 Statistics Advisor Plug-integrated with Visual Explain<br />

Predefined defaults (you can add your own business specific defaults):<br />

When Statistics Advisor observes a predicate using a default, SA recognizes that often<br />

default values are skewed. So even if a column has high COLCARDF, if the SQL searches <strong>for</strong><br />

a ‘typical default’ (ACCT_NO = 0), then SA suggests collection of a single frequency on that<br />

column. On the screen presented on Figure 3-58, you can define the collection parameters<br />

<strong>for</strong> RUNSTATS, report type, collection type, check obsolete statistics dates, and enable<br />

logging <strong>for</strong> Statistics Advisor. Logging means saving files with the name ssa.log, ssa.log.1,<br />

ssa.log.2, and so on, and creates a trace.txt file, with the in<strong>for</strong>mation you need to analyze VE<br />

problems.<br />

Figure 3-58 Predefined default values<br />

Conflict thresholds tab:<br />

We recognize that you run RUNSTATS with SHRLEVEL CHANGE on online systems. So it is<br />

possible <strong>for</strong> table, index, and column statistics to be slightly inconsistent without causing<br />

122 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


problems with optimization. The conflicts threshold tab allows you to control how aggressively<br />

SA can en<strong>for</strong>ce inconsistencies. See Figure 3-59.<br />

Figure 3-59 Conflict statistics threshold setup<br />

Summarizing what the Statistics Advisor can do:<br />

► Automate the analysis of the statistics required <strong>for</strong> an SQL statement. Often a query can<br />

have inefficient or unstable per<strong>for</strong>mance due to lack of statistics.<br />

► Generate a report explaining why you need the recommended RUNSTATS<br />

► Show the statistics conflict that you have in your catalog<br />

► Submit the RUNSTATS using a stored procedure<br />

► Automate the solution to many common SQL per<strong>for</strong>mance problems and solve SQL<br />

per<strong>for</strong>mance problems quickly and easily.<br />

3.15.4 Visual Explain and Statistics Advisor on MQTs<br />

To illustrate, we show screens from Visual Explain and Statistics Advisor taken using one<br />

query from the member DSNTEJ3M (from SDSNSAMP).<br />

Table 3-13 Query using MQT table<br />

Query MQT table<br />

Note: Do not <strong>for</strong>get to set the Current Refresh Age Parameters = Any (from the Visual<br />

Explain - Tune SQL Screen); otherwise, EXPLAIN does not show you the MQTs you are<br />

using.<br />

We put the whole query on Table 3-13 in case you want to do the same tests we did.<br />

SELECT R1.DAY, R1.MONTH, R1.YEAR, R10.CITYID, R7.DIVISIONID, SUM(R15.QUANTITY) SUMQTY,<br />

SUM(R15.C<strong>OS</strong>T) SUMC<strong>OS</strong>T, SUM(R15.AMOUNT) SUMAMT, SUM(R15.AMOUNT) - SUM(R15.C<strong>OS</strong>T) GPROFIT<br />

FROM DSN8810.TIME R1, DSN8810.PRODUCT R5, DSN8810.LOCATION R10, DSN8810.PCATEGORY R6,<br />

DSN8810.SALESFACT R15, DSN8810.PFAMILY R7<br />

WHERE R1.TIMEID = R15.TIMEID AND R5.PRODUCTID = R15.PRODUCTID<br />

AND R5.CATEGORYID = R6.CATEGORYID AND R6.FAMILYID = R7.FAMILYID<br />

AND R10.STOREID = R15.STOREID AND R1.YEAR >= 2000<br />

GROUP BY R1.DAY, R1.MONTH, R1.YEAR, R10.CITYID, R7.DIVISIONID;<br />

Chapter 3. SQL per<strong>for</strong>mance 123


Be<strong>for</strong>e the introduction of MQTs, <strong>DB2</strong> had to struggle through long data warehouse queries.<br />

And the DBA had to pre-elaborate complex SELECTs with lots of UNIONs and JOINS in<br />

order to create intermediate tables to be used by application people.<br />

Figure 3-60 shows the graph <strong>for</strong> the query in Figure 3-13 (no MQT).<br />

Figure 3-60 Explain without using an MQT table by Visual Explain<br />

<strong>DB2</strong> accesses an MQT the same way it accesses a base table with one exception: <strong>DB2</strong><br />

cannot use a direct fetch to access a materialized query table.<br />

When underlying data changes, <strong>DB2</strong> does not automatically refresh MQTs. To keep the MQT<br />

data current, you must issue a REFRESH TABLE statement if the table is system-maintained,<br />

or, if the materialized query table is user-maintained, you must issue INSERT, UPDATE, and<br />

DELETE statements as needed. To control the use of MQTs, use the CURRENT REFRESH<br />

AGE and CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION special registers.<br />

An MQT node is labeled with the name of the MQT and is, by default, displayed as an<br />

upside-down trapezoid. The table's correlation name, creator name, or cardinality can also be<br />

displayed on the label. If the RUNSTATS utility has not collected statistics <strong>for</strong> the table, the<br />

node is outlined in red. If the optimizer uses the default value <strong>for</strong> the cardinality, the cardinality<br />

is marked as the default.<br />

On Figure 3-61 you can see the EXPLAIN graph generated by the VE of a query using the<br />

MQT table with the name MATPROC ID = 14 and Cardinality = 6.<br />

124 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 3-61 Explain using an MQT table by Visual Explain<br />

Chapter 3. SQL per<strong>for</strong>mance 125


126 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance<br />

4<br />

In this chapter, we discuss the following topics and related per<strong>for</strong>mance enhancements that<br />

affect <strong>DB2</strong> subsystem per<strong>for</strong>mance:<br />

► <strong>DB2</strong> CPU experiences: With every new release of <strong>DB2</strong>, per<strong>for</strong>mance is always a<br />

challenge. <strong>DB2</strong> V8 is no different. Here we discuss general subsystem per<strong>for</strong>mance<br />

considerations and what we have seen in V8 in terms of CPU utilization.<br />

► Virtual storage constraint relief: <strong>DB2</strong> V8 supports 64-bit storage in the DBM1 address<br />

space. This provides significant virtual storage constraint relief (VSCR). We first explain<br />

what has changed in V8, then evaluate the impact of these enhancements on virtual<br />

storage usage.<br />

► Distributed thread storage: Although 64-bit addressing is exploited by DBM1 and IRLM,<br />

the distributed address space does not use 64-bit in <strong>DB2</strong> V8. In general we experience an<br />

increase in virtual storage requirements of the distributed address space due to the<br />

architectural changes in <strong>DB2</strong> V8.<br />

► Monitoring DBM1 storage: It is important to proactively monitor virtual storage usage<br />

taking advantage of the enhanced instrumentation available to <strong>DB2</strong> V7 and V8.<br />

► Buffer pool long term page fixing: <strong>DB2</strong> V8 allows you to fix the buffer pool pages once<br />

in memory and keep them in real storage. This avoids the processing time that <strong>DB2</strong> needs<br />

to fix and free pages each time there is an I/O. This applies to CM and NFM.<br />

► IRLM V2.2: <strong>DB2</strong> V8 requires IRLM V2.2, which is a 64-bit application. With IRLM V2.2,<br />

locks always reside above the 2 GB bar. You no longer have the option to request the<br />

IRLM to manage the locks in ECSA by specifying PC=NO.<br />

► Unicode: <strong>DB2</strong> V8’s increased exploitation of Unicode dictates that <strong>DB2</strong> must per<strong>for</strong>m far<br />

more conversions to and from Unicode than in the past. Here, we discuss recent<br />

enhancements that have been made, both inside <strong>DB2</strong> and external to <strong>DB2</strong>, to improve the<br />

per<strong>for</strong>mance of these conversions.<br />

► Data encryption: We introduce both <strong>DB2</strong> encryption and the <strong>IBM</strong> Data Encryption Tool<br />

and discuss some recent hardware enhancements that improve encryption per<strong>for</strong>mance.<br />

► Row level security: <strong>DB2</strong> introduces support <strong>for</strong> row level security <strong>for</strong> more granular<br />

security of <strong>DB2</strong> data which simplifies row level security implementation and management<br />

significantly.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 127


► Larger VSAM CI sizes: <strong>DB2</strong> V8 introduces support <strong>for</strong> VSAM CI sizes of 8, 16, and 32<br />

KB, which potentially reduces the elapsed time <strong>for</strong> all I/O bound workloads.<br />

► Instrumentation enhancements: Significant enhancements to <strong>DB2</strong> instrumentation have<br />

been added in V8.<br />

► Miscellaneous items:<br />

– <strong>DB2</strong> logging enhancements: <strong>DB2</strong> V8 increases the amount of active log data set pairs<br />

from 31 to 93, as well as increases the number of archive log data sets from 1,000 to<br />

10,000. This enhancement increases the amount of log data <strong>DB2</strong> has available online<br />

<strong>for</strong> recovery, which can have a dramatic impact on recovery per<strong>for</strong>mance and data<br />

availability.<br />

– Up to 65,041 open data sets: <strong>DB2</strong> V8 increases the number of open data sets from 32k<br />

to 65,041 by exploiting z/<strong>OS</strong> 1.5 which allows open data set control blocks to be<br />

allocated above the 16 MB line. This enhancement does not only provide virtual<br />

storage relief, it also removes a potential scalability problem with growing systems and<br />

growing machine capacity.<br />

– SMF Type 89 record collection enhancements: <strong>DB2</strong> V8 provides a new DSNZPARM<br />

parameter, SMF89, which lets you specify whether or not <strong>DB2</strong> is to do detailed tracking<br />

<strong>for</strong> measured usage pricing. Previous releases of <strong>DB2</strong> automatically used detailed<br />

tracking of measured usage if SMF type 89 records were activated. This is available in<br />

CM.<br />

– Lock avoidance enhancements: <strong>DB2</strong> V8 avoids taking locks on overflow records if a row<br />

has been relocated to another page. In addition, <strong>DB2</strong> per<strong>for</strong>ms lock avoidance <strong>for</strong><br />

singleton SELECT statements with ISOLATION(CS) and CURRENTDATA(YES). This<br />

is available in CM.<br />

128 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.1 <strong>DB2</strong> CPU considerations<br />

With every new release of <strong>DB2</strong>, per<strong>for</strong>mance is always a challenge. <strong>DB2</strong> V8 is no different.<br />

For those applications not taking advantage of any V8 per<strong>for</strong>mance enhancements, some<br />

CPU time increase is unavoidable to support a dramatic improvement in user productivity,<br />

availability, scalability, portability and family consistency of <strong>DB2</strong>. In particular, enhancements<br />

in:<br />

► DBM1 virtual storage constraint relief with 64-bit addressing. A number of <strong>DB2</strong> structures,<br />

<strong>for</strong> example, buffer pools, have moved above the 2 GB bar.<br />

► Long names and long index keys. Many <strong>DB2</strong> names change from CHAR(8) or<br />

VARCHAR(18) to VARCHAR(128). Maximum index key size also moves from 255 to 2000<br />

bytes.<br />

► Longer and more complex SQL statements. The maximum SQL statement size moves<br />

from 32 KB to 2 GB.<br />

► Extended support <strong>for</strong> Unicode. The <strong>DB2</strong> catalog is now Unicode and you can combine<br />

multiple CCSIDs in the same SQL statement.<br />

In this section we discuss general subsystem per<strong>for</strong>mance considerations and what you may<br />

see in V8 in terms of CPU utilization.<br />

As processor power continues to improve, linear scalability, or the ability to exploit increasing<br />

processor power without encountering a bottleneck that prevents the full CPU usage,<br />

becomes more important. Bigger buffer pools and cache reduce the I/O bottleneck and CPU<br />

overhead. Although most of the thread-related storage is still below the 2 GB bar, more<br />

concurrent active threads could be supported in V8 as other storage areas are moved above<br />

the 2 GB bar. However, whether more threads can be supported in V8 critically really<br />

depends on how much thread storage is being used in V7. If the thread storage takes up the<br />

majority of virtual storage in V7, there is no relief in V8.<br />

Exploiting bigger and faster hardware without premature constraint is a major driver to the<br />

virtual storage constraint relief enhancements in <strong>DB2</strong> V8. For example, the z990 (GA in<br />

05/03) is:<br />

► 1.3 to 1.6 times higher MIPS compared to z900 turbo<br />

► 1.8 to 2 times higher MIPS compared to z900<br />

► 256 GB real storage up from 64 GB <strong>for</strong> z900<br />

From V1R1 1984 to the present, real storage usage has grown in <strong>DB2</strong> at about 20 to 30% per<br />

release to support enhancements in per<strong>for</strong>mance and scalability, more and bigger buffer<br />

pools, larger sort pools, and more concurrent threads. <strong>DB2</strong> V8 continues this trend, by<br />

removing bottlenecks which would have prevented the exploitation of bigger real storage.<br />

64-bit addressing has brought its own per<strong>for</strong>mance challenges to <strong>DB2</strong>. For example, 64-bit<br />

instructions are typically 50% bigger than 31-bit instructions. 64-bit addresses are twice as<br />

big as 31-bit addresses. So, hardware registers and software control blocks which contain<br />

virtual addresses all need to be bigger. All these bigger instructions and bigger registers take<br />

longer to load and execute, (more bits and bytes must be staged into registers, destaged and<br />

moved around the hardware). Studies have shown some 64-bit instructions can take as much<br />

as 15% more CPU to execute. Other studies have shown that the same path length coded in<br />

64-bit mode can take as much as 10% more CPU than coded in 31-bit mode.<br />

The biggest difference is when 31-bit pointers have to be converted to 64-bit be<strong>for</strong>e being<br />

used in AMODE(64). That overhead does not exist in V7, but is unavoidable since not all<br />

components have been converted to 64-bit. Finally, it should be pointed out that the Unicode<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 129


4.1.1 Per<strong>for</strong>mance<br />

support caused almost as much CPU degradation as the 64-bit conversion, and support <strong>for</strong><br />

variable length indexes was not far behind.<br />

Hopefully you can now appreciate how the new 64-bit architecture, combined with all the<br />

enhancements in <strong>DB2</strong> V8, have added much more code than V7 and have also presented<br />

some significant per<strong>for</strong>mance challenges which have had to be overcome in order to minimize<br />

the CPU regression of V8 compared with V7.<br />

We reviewed the per<strong>for</strong>mance of <strong>DB2</strong> V8, compared with <strong>DB2</strong> V7, <strong>for</strong> a variety of different<br />

workloads, to understand the impact V8 may have on CPU <strong>for</strong> your workload. The<br />

per<strong>for</strong>mance measurements we compared <strong>for</strong> each workload were the ITR (Internal<br />

Throughput Rate, inversely proportional to CPU seconds used) and CPU.<br />

We begin our discussion by having a look at OLTP workloads. The variety of OLTP workloads<br />

we studied include the IRWW (<strong>IBM</strong> Relational Warehouse Workload, described in <strong>DB2</strong> <strong>for</strong><br />

MVS/ESA <strong>Version</strong> 4 Data Sharing Per<strong>for</strong>mance <strong>Topics</strong>, SG24-4611), both in a data sharing<br />

and non-data sharing environment, a number of DRDA client/server transaction workloads, a<br />

number of SAP workloads and a CICS/<strong>DB2</strong> transaction workload. Each workload studied had<br />

a different SQL structure and there<strong>for</strong>e revealed different per<strong>for</strong>mance strengths and<br />

weaknesses. For example, some workloads executed reasonably simple SQL while other<br />

workloads executed more complex SQL.<br />

A number of query-based workloads have been studied to compare query per<strong>for</strong>mance. Over<br />

200 queries gathered from a number of customer sites have been used. Some of these<br />

queries achieved up to 20% reduction in CPU, due primarily to improved access path<br />

enhancements. For example, a data warehouse application achieved over 30% improvement<br />

in CPU, primarily due to star join enhancements.<br />

A number of batch workloads were also studied, including a sampling of commonly used<br />

utilities.<br />

Figure 4-1 summarizes some general measurements of V8 CPU consumption compared with<br />

V7 <strong>for</strong> various workloads. These comparisons are made with no application changes to<br />

exploit any V8 new function, nor any aggressive configuration changes.<br />

This chart has been compiled from a number of different laboratory tests running various <strong>DB2</strong><br />

workloads. A ‘+’ means a CPU increase and a ‘-’ means a CPU decrease in V8 compared<br />

with V7. Be reminded that these trends can only be used as a guide. As always, “your<br />

mileage may vary”, since all <strong>DB2</strong> installations and workloads are different.<br />

130 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


oltp<br />

oltp in data sharing<br />

batch insert<br />

batch select<br />

batch fetch/update<br />

batch data sharing<br />

batch drda<br />

utility<br />

query<br />

Figure 4-1 CPU workload summary<br />

CPU range by workload<br />

-20% -10%<br />

0% +10% +20%<br />

The typical customer CPU regression of <strong>DB2</strong> V8 is anticipated to be 0 to 10% more than V7<br />

on average. This CPU degradation is the result of the new functionality that is provided in <strong>DB2</strong><br />

V8, together with the overhead that comes with 64-bit addressing.<br />

Looking at it a little closer, the CPU delta is:<br />

► 0 to +15% regression <strong>for</strong> online transaction workloads<br />

Remember, we have much more code and function in V8 compared with V7, as well as<br />

dealing with the added complication of 64-bit addressing in the DBM1 address space.<br />

► -5 to +10% regression <strong>for</strong> online transaction workloads in data sharing environments<br />

The reason why we are able to achieve less CPU degradation in data sharing is because<br />

there are a number of per<strong>for</strong>mance enhancements in V8 that apply specifically to data<br />

sharing environments. For example, Lock Protocol Level 2 to reduce global lock<br />

contention. See Chapter 8, “Data sharing enhancements” on page 319 <strong>for</strong> more details.<br />

► -5 to +20% regression in batch workloads<br />

– -5 to +5% with a heavy INSERT workload<br />

This does not represent a significant change and is comparable to <strong>DB2</strong> V7.<br />

– -5 to +20% with a heavy SELECT workload<br />

We are able to achieve some CPU reduction <strong>for</strong> SELECT workloads because the<br />

SELECT workloads benefit from the new lock avoidance techniques used in V8. See<br />

4.13.4, “Lock avoidance enhancements” on page 214 <strong>for</strong> more details. Applications<br />

using CURRENTDATA(YES) receive the most benefit as these do not exploit lock<br />

avoidance in <strong>DB2</strong> V7. We see more CPU degradation (up to a 20%) as the number of<br />

columns increases.<br />

– +5% to +20% with a heavy FETCH and UPDATE workload<br />

This increase in CPU varies greatly based on the number of columns being processed.<br />

The more columns, the more CPU used. In fact, you may see as much as 20% more<br />

CPU consumed in V8 when you are processing over 100 columns in the SQL.<br />

► -10% to +15% regression in batch workloads in a data sharing environment<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 131


Regression is about 5% better than non-data sharing. V8 can achieve significant<br />

per<strong>for</strong>mance improvements over V7 primarily due to some data sharing specific<br />

enhancements such as CF Request Batching and protocol 2. See Chapter 8, “Data<br />

sharing enhancements” on page 319 <strong>for</strong> more details.<br />

► -20 to +15% regression in batch DRDA workloads<br />

These huge gains over V7 are primarily due to API reduction <strong>for</strong> multi-row fetch in a<br />

distributed environment. See Chapter 7, “Networking and e-business” on page 281 <strong>for</strong><br />

more details.<br />

► -5% to +10% regression <strong>for</strong> utilities<br />

See Chapter 6, “Utilities” on page 261 <strong>for</strong> details.<br />

► -20% to +15% regression <strong>for</strong> query workloads<br />

Simple and short queries tend to increase in CPU while long running queries tend to<br />

decrease in CPU. However, the gains in per<strong>for</strong>mance can be quite substantial. They are<br />

primarily due to access path enhancements in V8. See Chapter 3, “SQL per<strong>for</strong>mance” on<br />

page 29 <strong>for</strong> more details.<br />

Now, let us have a brief overview of <strong>DB2</strong> utilities, where we found a wide variety of results.<br />

Figure 4-2 summarizes these results. Once again, a ‘+’ means a CPU increase and a ‘-’<br />

means a CPU decrease.<br />

reorg index<br />

check index<br />

recover tablespace<br />

unload<br />

online reorg<br />

Figure 4-2 V7 vs. V8 Utility CPU measurements<br />

All these utilities were executed with no new V8 function, except where the defaults changed<br />

from V7 to V8. We saw that:<br />

► LOAD achieved a 2% reduction in CPU<br />

► REORG achieved a 2% increase in CPU<br />

► REBUILD INDEX varied from a 9% reduction, to a 13% increase in CPU<br />

► RUNSTATS varied from a huge 45% reduction, to a 7% increase in CPU<br />

132 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

V7 vs. V8 Utility CPU measurements<br />

load<br />

reorg<br />

rebuild index<br />

runstats<br />

copy<br />

-40%<br />

-20%<br />

0% +20%


► COPY varied from a 0% reduction, to a 10% increase in CPU<br />

► REORG INDEX varied from a 10% to 17% reduction in CPU<br />

► CHECK INDEX achieved a 3% increase in CPU<br />

► RECOVER TABLESPACE also achieved a 3% increase in CPU<br />

► UNLOAD achieved no increase CPU<br />

► ONLINE REORG achieved a 4% increase in CPU<br />

Refer to Chapter 6, “Utilities” on page 261 <strong>for</strong> a discussion of utility per<strong>for</strong>mance<br />

enhancements in V8.<br />

Overall, the utilities we studied achieved a -5% to +10% regression in CPU used in V8<br />

compared with V7.<br />

The RUNSTATS utility was by far the most variable. RUNSTATS TABLESPACE was generally<br />

the best per<strong>for</strong>mer with its CPU to the left of the RUNSTATS bar. This was followed by<br />

RUNSTATS TABLESPACE and TABLE, then RUNSTATS TABLESPACE and INDEX, with<br />

RUNSTATS INDEX generally appearing to the right of the bar.<br />

Important: The numbers we have presented in this section represent what we observed<br />

from the laboratory measurements using a variety of different workloads. Your<br />

per<strong>for</strong>mance studies most certainly vary. <strong>DB2</strong> per<strong>for</strong>mance is very application and<br />

workload dependent. Also remember that <strong>DB2</strong> per<strong>for</strong>mance may vary every time<br />

maintenance is applied to <strong>DB2</strong>.<br />

Let us have a closer look at the IRWW workload, running in <strong>DB2</strong> V7, <strong>DB2</strong> V8 in CM and <strong>DB2</strong><br />

V8 running in NFM. Table 4-1 summarizes these results.<br />

Table 4-1 CM vs. NFM - Non-data sharing<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

CM<br />

Page-fixed Buffer Pools No Yes Yes<br />

ETR<br />

(commits / sec)<br />

CPU<br />

(%)<br />

ITR<br />

(commits / sec)<br />

<strong>DB2</strong> class 2 time<br />

(msec / commit)<br />

<strong>DB2</strong> V8<br />

NFM<br />

Delta<br />

(CM / V7)<br />

Delta<br />

(NFM / CM)<br />

386.00 386.50 385.50 + < 1‘% + < 1%<br />

63.79 64.41 64.11 + 1% - < 1%<br />

605.11 600.06 601.31 - 1% + < 1%<br />

Elapsed 15.148 15.922 15.462 + 5% - < 3%<br />

CPU 1.713 1.842 1.815 + 7% - < 2%<br />

<strong>DB2</strong> class 2 CPU time<br />

(msec / commit)<br />

MSTR 0.096 0.107 0.107 + 11% 0%<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 133


The results indicate no significant difference in throughput <strong>for</strong> our workload running in CM<br />

compared with NFM. We recorded less than 1% variation which is not significant.<br />

We see 7% more class 2 accounting CPU consumed in V8 compared with V7 and slightly<br />

less CPU used in NFM compared to CM, with a less than 2% improvement. We can there<strong>for</strong>e<br />

conclude there is no significant difference in CPU consumed by using <strong>DB2</strong> V8 in CM over<br />

NFM.<br />

We also see a modest increase of 2% CPU consumed by each transaction in <strong>DB2</strong> V8 CM<br />

compared with <strong>DB2</strong> V7. This would have been a little higher if CPU consumed by the DBM1<br />

address space had not decreased by 20% compared with V7. The DBM1 address space<br />

used less CPU because all the buffer pools were long term page-fixed and all the plans and<br />

packages were bound in the V8 <strong>for</strong>mat.<br />

In addition, we see a 7% increase in class 2 CPU time used by each transaction in <strong>DB2</strong> V8<br />

CM compared with <strong>DB2</strong> V7. This increase is caused in part by the extra CPU required to<br />

process the 64-bit instructions necessary to access the DBM1 memory structures which are<br />

now above the 2 GB bar.<br />

Table 4-2 compares the IRWW workload running in <strong>DB2</strong> V8 compatibility mode, with <strong>DB2</strong> V8<br />

new-function mode, in a data sharing environment.<br />

Table 4-2 CM vs. NFM - Data sharing<br />

DBM1 0.407 0.324 0.321 - 20% - 1%<br />

IRLM n/c n/c n/c<br />

Total 0.503 0.431 0.428 - 14% - < 1%<br />

<strong>DB2</strong> class 2 CPU<br />

+ Total<br />

134 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

CM<br />

<strong>DB2</strong> V8<br />

NFM<br />

Delta<br />

(CM / V7)<br />

Delta<br />

(NFM / CM)<br />

2.216 2.273 2.246 + 2% - < 2%<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8 CM <strong>DB2</strong> V8 NFM Delta<br />

(CM / V7)<br />

Page-fixed Buffer Pools No Yes Yes<br />

Locking Protocol Level 1 1 2<br />

ETR<br />

(commits / sec)<br />

287.83 287.50 285.33 283.67 290.00 289.83 - 1% + 2%<br />

CPU (%) 67.32 72.60 65.33 70.22 62.29 61.95 - 3% - 8%<br />

Group ITR<br />

(commits / sec)<br />

<strong>DB2</strong> class 2 time<br />

(msec / Commit)<br />

Delta<br />

(NFM / CM)<br />

823.56 840.72 933.41 + 2% + 11%<br />

Elapsed 34.272 34.859 36.713 39.179 19.415 19.442 + 9% - 49%<br />

CPU 2.204 2.380 2.440 2.643 2.525 2.508 + 8% - 1%


<strong>DB2</strong> AS class 2 CPU time<br />

(msec / commit)<br />

MSTR 0.309 0.336 0.135 0.150 0.150 0.150 - 56% + 0%<br />

DBM1 0.603 0.621 0.451 0.447 0.436 0.434 - 27% - 3%<br />

IRLM 0.330 0.371 0.331 0.337 0.014 0.014 - 5% - 96%<br />

Total 1.243 1.328 0.917 0.974 0.600 0.597 - 27% - 63%<br />

<strong>DB2</strong> class 2 CPU<br />

+ Total<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8 CM <strong>DB2</strong> V8 NFM Delta<br />

(CM / V7)<br />

3.447 3.708 3.357 3.617 3.125 3.105 - 3% - 11%<br />

Delta<br />

(NFM / CM)<br />

In these measurements, we see a large 11% decrease in overall CPU used in NFM compared<br />

to CM. This is not due to the extra overhead in running in CM over NFM, but as a direct result<br />

of Locking Protocol Level 2 being used in NFM, but not available in CM. These savings are<br />

realized through a dramatic reduction in the IRLM CPU times. See 8.2, “Locking protocol level<br />

2” on page 325. We can also see the positive impact the Locking Protocol Level 2 has on<br />

transaction response times, with quite a significant savings in transaction elapsed time. The<br />

drop in transaction elapsed time is caused by a similar drop in application class 3 suspend<br />

time, which is not listed in the table.<br />

We see a slight decrease in overall CPU (3%) used in <strong>DB2</strong> V8 CM compared with <strong>DB2</strong> V7.<br />

This is a better result than with non-data sharing. In addition to the per<strong>for</strong>mance gains we see<br />

through Long Term Page Fixing the buffer pools, data sharing offers more CPU savings<br />

through functions such as CF Request Batching which are specific to data sharing. See<br />

Chapter 8, “Data sharing enhancements” on page 319 <strong>for</strong> a more detailed discussion of these<br />

enhancements. All these enhancements combine to offer a far greater offset to the CPU<br />

increase in <strong>DB2</strong> V8.<br />

Compatibility mode versus new-function mode<br />

<strong>DB2</strong> V8 brings a new strategy to move an existing <strong>DB2</strong> V7 environment to <strong>Version</strong> 8. You<br />

must first ‘migrate’ your <strong>DB2</strong> environment from <strong>Version</strong> 7 to <strong>Version</strong> 8 compatibility mode<br />

(CM). You can fallback to <strong>DB2</strong> V7 if you need to, and only partial new <strong>Version</strong> 8 function is<br />

enabled. Once you are com<strong>for</strong>table with the function, stability and per<strong>for</strong>mance of <strong>DB2</strong> V8 in<br />

CM, you then move through enabling-new-function mode (ENFM) and into new-function<br />

mode (NFM). Once in NFM, you can now exploit all the new function in <strong>DB2</strong> V8, but you<br />

cannot return to CM or <strong>Version</strong> 7. See Chapter 9, “Installation and migration” on page 341.<br />

Some users may choose to remain in CM <strong>for</strong> a period of a few weeks or even a month or two.<br />

While other users may choose to migrate to NFM at their earliest opportunity.<br />

Once in CM, <strong>DB2</strong> parses all SQL statements in Unicode. In addition, <strong>DB2</strong> V8, both in CM and<br />

NFM, uses a different <strong>for</strong>mat <strong>for</strong> its DBDs, packages and plans. <strong>DB2</strong> V8 requires a new<br />

<strong>for</strong>mat <strong>for</strong> DBDs, plans and packages to support the new function such as Unicode and Long<br />

Names. So, be<strong>for</strong>e <strong>DB2</strong> can use a DBD, plan or package from an earlier release of <strong>DB2</strong>, it<br />

must first expand it into the new V8 <strong>for</strong>mat. In CM, <strong>DB2</strong> must also convert the DBDs, plans<br />

and packages to the old <strong>for</strong>mat be<strong>for</strong>e it can store them in the catalog. This extra overhead is<br />

recorded in <strong>DB2</strong> class 2 CPU times, and is extra overhead that exists while running in CM and<br />

NFM without which you can easily function.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 135


Important:<br />

4.1.2 Conclusion<br />

If you plan to stay in CM <strong>for</strong> some time and are interested in finding out the per<strong>for</strong>mance of<br />

V8 on your per<strong>for</strong>mance-sensitive workload, you should definitely rebind. Rebinding will<br />

give you a sense of the V8 per<strong>for</strong>mance.<br />

After you have entered NFM, we recommend that you plan to rebind all of your plans and<br />

packages. <strong>DB2</strong> then stores these plans and packages in the <strong>DB2</strong> catalog in the new<br />

<strong>for</strong>mat. <strong>DB2</strong> will then no longer need to expand the plans and packages each time it needs<br />

to use them.<br />

For most workloads, our measurements have shown a less than 10% increase in CPU<br />

consumed by moving from V7 to V8, and we did not even change applications to take<br />

advantage of any new function or make any aggressive configuration changes. In addition,<br />

the difference in CPU consumption between <strong>DB2</strong> V8 CM and NFM is only minor and<br />

there<strong>for</strong>e should not be considered significant.<br />

Generally, you should experience less CPU regression if, under <strong>DB2</strong> V7:<br />

► You are already using IRLM PC=YES and LOCKPART YES.<br />

In V8 these are required.<br />

► You are heavily using hiperpools or buffers in data spaces in V7.<br />

You are taking advantage of simplified buffer pool management above the bar.<br />

► You already use CURRENTDATA(NO) in your BIND options.<br />

CURRENTDATA(NO) already exploits lock avoidance in V7.<br />

► You collect SMF type 89 records.<br />

V7 generates these records after every SQL statement while V8 generates these records<br />

on each commit. In some environments, this has the potential of saving up to 15% in CPU<br />

consumed by <strong>DB2</strong> V8 (extreme stress environment).<br />

► You heavily use DSNTEP2 (now DSNTEP4) and DSNTIAUL which now exploit multi-row<br />

operation. This is applicable to NFM only.<br />

► You heavily use DRDA which now automatically exploits multi-row operation. This is<br />

applicable to CM as well as NFM.<br />

Multi-row FETCH/INSERT/UPDATE have the potential to save considerable CPU,<br />

especially in DRDA applications.<br />

► You have the DSNZPARM MINSTOR and CONTSTOR parameters set to YES and are not<br />

thread storage constrained.<br />

Having these parameters set to YES in V7 uses extra CPU cycles. Once in V8, if you can<br />

set them to NO, this improves the CPU time.<br />

► You use BIND RELEASE(COMMIT) in data sharing.<br />

In V8 there is potentially less global lock contention as a result of the Locking Protocol<br />

Level 2. <strong>DB2</strong> V7 must use more CPU cycles to resolve more global lock contention than<br />

V8, which potentially has less global lock contention.<br />

► You have I/O intensive workloads.<br />

I/O intensive workloads tend to benefit from long term page fix option and 180 CI limit<br />

removal. Sequential processing with larger CIs can also benefit.<br />

136 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Generally, you should experience more CPU regression if:<br />

► You use non-padded indexes (the default in V8 install) with small varchar columns.<br />

There is a fixed CPU overhead in processing varchar columns in INDEX KEY. As the size<br />

of each varchar column increases, the overhead gets not only diluted but eventually it can<br />

result in positive per<strong>for</strong>mance gain. See Chapter 5, “Availability and capacity<br />

enhancements” on page 217 <strong>for</strong> more details and in<strong>for</strong>mation about changing the default.<br />

► You use DPSIs in some SQL statements.<br />

DPSIs can currently only be non-unique. Some queries, <strong>for</strong> example, queries with<br />

predicates which only reference indexed columns of the index, may experience some<br />

per<strong>for</strong>mance degradation. These types of queries may need to probe each partition of the<br />

DSPI, where only one probe was needed <strong>for</strong> an NPI. Additional qualifiers might help.<br />

► You manipulate lots of columns in your SQL.<br />

This code has already been heavily optimized over the years and in V8 it carries the<br />

overhead due to 64-bit processing. Reducing the number of columns to the ones really<br />

needed is always advisable.<br />

Impact on class 2 CPU time<br />

As you begin to review the CPU utilization <strong>for</strong> your workload in V8 compared with V7, keep in<br />

mind that you may see a slightly higher accounting class 2 CPU time in V8. However the news<br />

is not all bad. Table 4-3 compares the increase in accounting class 2 CPU times to the overall<br />

CPU consumed.<br />

Table 4-3 Accounting class 2 CPU time increase<br />

Accounting class 2<br />

CPU time<br />

MSTR/DBM1/IRLM<br />

CPU time<br />

Non-data<br />

sharing<br />

+6% +14%<br />

-14% -51%<br />

Total +1% -9%<br />

Data sharing<br />

We can see that <strong>for</strong> our tests Accounting class 2 CPU times have increased by 6% <strong>for</strong><br />

non-data sharing and 14% <strong>for</strong> data sharing in V8 compared to V7.<br />

As we have mentioned earlier, 64-bit addressing has brought its own per<strong>for</strong>mance challenges<br />

to <strong>DB2</strong>. 64-bit instructions are typically twice as big as 31-bit instructions and some 64-bit<br />

instructions can take as much as 15% more CPU to execute. This impacts class 2 CPU time.<br />

This is what contributed to driving the accounting class 2 CPU times higher in <strong>DB2</strong> V8.<br />

New <strong>DB2</strong> V8 function, like removing the 180 CI limit <strong>for</strong> list prefetch and castout processing,<br />

and long term page fixing of <strong>DB2</strong> buffers, works to decrease the overall SRB CPU time, which<br />

in turn offsets the increase in accounting class 2 CPU times.<br />

The higher class 2 CPU time in data sharing compared with non-data sharing (14%<br />

compared with 6%) is largely attributed to the changes V8 has introduced to the<br />

IMMEDWRITE BIND option. In V7, <strong>DB2</strong> charges the CPU <strong>for</strong> writing changed pages to the<br />

group buffer pool at commit, to the MSTR address space. In V8, this cost is charged to the<br />

allied address space. The cost of writing these changed pages has moved from the MSTR<br />

address space to the allied agents Accounting class 2 CPU times. See the discussion on<br />

IMMEDWRITE in Chapter 8, “Data sharing enhancements” on page 319 <strong>for</strong> more details.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 137


However, the combined impact of other V8 enhancements in data sharing (<strong>for</strong> example, CF<br />

Request Batching <strong>for</strong> castout processing and Locking Protocol Level 2 which also reduce the<br />

overall SRB CPU time), offsets the increase in CPU times seen by the Accounting class 2<br />

reports and produces a lower percentage increase in CPU overall.<br />

Important: Do not just take the accounting class 2 CPU times to compare V7 to V8<br />

per<strong>for</strong>mance. You must also factor in any CPU time reduction in the <strong>DB2</strong> address spaces<br />

from statistics reports.<br />

4.1.3 Recommendations<br />

Even though we have found that the relative overhead of running <strong>DB2</strong> V8 in NFM is negligible<br />

compared to CM and the extra cost of running a <strong>DB2</strong> V7 bound plan/package in V8 is also<br />

negligible compared to V7, the following recommendations still apply.<br />

Unless you go to NFM immediately, consider rebinding your plans and packages in V8 CM as<br />

soon as you are com<strong>for</strong>table you will not fallback to V7. This gives <strong>DB2</strong> the opportunity to<br />

select a better access path which potentially benefits your SQL per<strong>for</strong>mance, especially <strong>for</strong><br />

more complex queries. The <strong>DB2</strong> Optimizer progressively becomes smarter and smarter with<br />

each new release of <strong>DB2</strong>. You are able to experience the real V8 per<strong>for</strong>mance.<br />

Tuning <strong>for</strong> CPU usage in V8<br />

It you were virtual storage constrained in V7 and took initiatives to resolve the virtual storage<br />

problems, you may choose to reconsider these initiatives in V8. Some of these actions taken<br />

to reduce virtual storage usage have a cost of additional CPU. You may no longer need to<br />

have these initiatives in place in V8, since you are less likely to be constrained by storage in<br />

V8:<br />

► Increase again the size of buffer pools and other pools you reduced in V7, to once again<br />

improve overall per<strong>for</strong>mance.<br />

► Consider rebinding some critical plans and packages with RELEASE(DEALLOCATE)<br />

again, only if you were using this bind parameter to improve per<strong>for</strong>mance of some key<br />

applications in V7. (Remember, however, there is less of a need to have plans and<br />

packages bound with RELEASE(DEALLOCATE) in <strong>DB2</strong> V8 data sharing than V7 data<br />

sharing. See Chapter 8, “Data sharing enhancements” on page 319 <strong>for</strong> a more detailed<br />

discussion of why RELEASE(DEALLOCATE) is less necessary in V8.)<br />

► Consider turning on thread reuse again, to improve per<strong>for</strong>mance of your critical<br />

applications.<br />

► Consider turning off the DSNZPARM EDMBFIT parameter which concerned EDM pool<br />

space.<br />

► Consider turning off the DSNZPARM CONTSTOR parameter which regularly contracts<br />

thread local storage pools.<br />

► Consider turning off the DSNZPARM MINSTOR parameter which changes the way <strong>DB2</strong><br />

allocates local storage <strong>for</strong> thread use.<br />

Other options with significant potential to offset a possible increase in CPU include:<br />

► Rebind all your plans and packages.<br />

See the above discussion.<br />

► Long term page fixing your buffer pools<br />

This is a strong recommendation as it has the potential to save a much as 8% in CPU.<br />

However, only consider this if you have enough real storage available to back 100% of<br />

138 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


your buffer pools. We recommend you implement long term page fixing, buffer pool by<br />

buffer pool, <strong>for</strong> I/O intensive profiles. See 4.5, “Buffer pool long term page fixing” on<br />

page 169, <strong>for</strong> a more detailed discussion on long term page fixing.<br />

► Multi-row FETCH and INSERT<br />

Although this <strong>DB2</strong> V8 enhancement requires you to modify your application, it has a<br />

significant potential to save CPU cycles. See the sections on Multi-row FETCH and<br />

INSERT in Chapter 3, “SQL per<strong>for</strong>mance” on page 29 <strong>for</strong> more details.<br />

4.2 Virtual storage constraint relief<br />

<strong>DB2</strong> V8 exploits 64-bit storage in the DBM1 address space which provides significant virtual<br />

storage constraint relief (VSCR).<br />

By way of background, MVS addressing is represented in the power of 2 closest to the<br />

corresponding power of 10. Refer to the z/Architecture Principles of Operation, SA22-7832 <strong>for</strong><br />

a more detailed discussion.<br />

2#10 Kilo (1024 bytes)<br />

2#20 Mega (1024 * 1024 bytes)<br />

2#30 Giga (1024 * 1024 * 1024 bytes)<br />

2#40 Tera (1024 * 1024 * 1024 * 1024 bytes)<br />

2#50 Peta (a really big number)<br />

2#60 Exa (an even bigger number)<br />

2#70 Zetta (too big a number)<br />

2#70 Yotta (the “Restaurant at the end of the Universe!”)<br />

So 2#64 is 16EB -- and the largest z/Architecture address is 16E-1. <strong>DB2</strong> now supports a<br />

16-exabyte DBM1 address space. A 16-exabyte address space is 8 billion times larger than a<br />

2-gigabyte (GB) address space. The new virtual storage area above the old 2 GB limit is<br />

referred to as above the bar.<br />

Figure 4-3 provides a simplified introductory description of the major storage areas that have<br />

moved above the 2 GB bar in the DBM1 address space. The 64-bit storage exploitation in<br />

<strong>DB2</strong> V8 provides a number of per<strong>for</strong>mance improvements to <strong>DB2</strong> which we discuss in this<br />

section.<br />

The entities which have been moved above the bar in the <strong>DB2</strong> V8 DBM1 address space<br />

include:<br />

► 64-bit virtual buffer pool and their control blocks<br />

Larger buffer pools enable I/O reduction <strong>for</strong> random access, and enable larger page sizes<br />

which benefit sequential access. Buffer pool management is also made simpler.<br />

► DBDs in the EDM pool<br />

More database objects can be defined and I/O to the <strong>DB2</strong> directory is reduced because<br />

the pool can be larger.<br />

► EDM statement cache<br />

A larger cache may avoid dynamic SQL PREPAREs.<br />

► Compression dictionaries<br />

You no longer need to manage the open and close <strong>for</strong> table spaces to manage the amount<br />

of DBM1 storage which is required by compression dictionaries <strong>for</strong> open compressed table<br />

spaces.<br />

► Sort pools<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 139


Frees up space below the bar <strong>for</strong> other uses, as well as allowing <strong>for</strong> larger sorts.<br />

► RIDLISTs <strong>for</strong> the RID pool<br />

Frees up space below the bar <strong>for</strong> other uses, as well as allowing <strong>for</strong> larger RID lists to be<br />

processed.<br />

► Castout buffers<br />

In case your environment is data sharing.<br />

16 EB<br />

2 GB<br />

16 MB<br />

0<br />

RID Lists<br />

Buffer Pools<br />

Figure 4-3 DBM1 virtual storage constraint relief (no data spaces nor hiper pools)<br />

By moving storage above the bar, more room is made available below the bar <strong>for</strong> other<br />

entities that must remain there in <strong>DB2</strong> V8, such as thread-related storage and storage <strong>for</strong><br />

plans and packages.<br />

In addition, by moving these structures above the bar, <strong>DB2</strong> V8 can support many<br />

improvements in scalability, such as larger buffer pools, more compression dictionaries, larger<br />

sorts and RID pools.<br />

Likewise, the IRLM address space now exploits 64-bit storage and allows many more locks.<br />

140 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Sort Pool<br />

DSC<br />

Compression<br />

Dictionaries<br />

DBDs


Attention:<br />

4.2.1 The <strong>DB2</strong> pools<br />

LOBs use data spaces with versions prior to V8, and go above the bar in the DBM1<br />

address space with <strong>DB2</strong> V8, so they are not influential with respect to VSCR.<br />

If you were using data spaces (max 8 M pages each), and have allocated their buffer pools<br />

and global dynamic statements cache (DSC) instead of below the bar in the DBM1<br />

address space, then the VSCR would be less.<br />

If you were using hiper pools (max 8 GB total) to work as cache <strong>for</strong> your virtual buffer pools,<br />

then the VSCR would be less.<br />

The GETMAIN and FREEMAIN processes to acquire and release virtual storage in z/<strong>OS</strong> can<br />

be quite expensive in terms of instructions. So, <strong>DB2</strong> tends to GETMAIN large blocks of<br />

storage from z/<strong>OS</strong> and then manage the sub-allocation and usage directly.<br />

<strong>DB2</strong> maintains two main types of storage pools:<br />

► Stack storage (SKB): Used <strong>for</strong> very active thread-related storage.<br />

► Getmained block (GMB) storage: Used <strong>for</strong> specific purposes such as buffer pools,<br />

compression dictionaries, and so on. With <strong>DB2</strong> V7 this is generally the largest user of<br />

storage below the bar in the DBM1 address space. Storage in the GMB pool includes:<br />

– Buffer pools and buffer pool control blocks<br />

– EDM pool<br />

– Compression dictionaries<br />

– Data space lookaside buffers (V7)<br />

– Data space buffer pool control blocks (V7)<br />

– Hiper pool control blocks (V7)<br />

Pools can also be fixed pools, in which the storage is sub-allocated into the same length<br />

blocks and optimized <strong>for</strong> per<strong>for</strong>mance or variable pools, which are general use pools of<br />

storage, sub-allocated into variable length blocks.<br />

Some storage pools are global and shared by multiple threads, <strong>for</strong> example buffer pools and<br />

the EDM pool. In these pools fragmentation is generally smaller, however contention can<br />

sometimes be a problem. While other types of storage are thread-related and only used by a<br />

single thread, <strong>for</strong> example, stack, storage and variable pools. In these other types of pools,<br />

fragmentation is a bigger problem but contention is much lower. Generally the largest<br />

contributors to virtual storage usage are GETMAINed and variable pools; however, the trend<br />

in the last few years has been toward growing usage of stack, thread-related, and storage.<br />

We now examine what has changed with <strong>DB2</strong> V8 in terms of storage management.<br />

64-bit virtual buffer pool support<br />

The buffer pools are used by <strong>DB2</strong> to reduce disk accesses. With more and more data needed<br />

by the applications, larger buffer pools have become necessary. The 64-bit virtual addressing<br />

is seen as the third major step in the evolution of MVS in the last 30 years. The first step was<br />

the transition from MVS/370 (24-bit) to MVS/XA (31-bit). The second step was the<br />

transition to MVS/ESA (including data spaces and hiper pools).<br />

<strong>DB2</strong> V7 supported buffer pools in data spaces and hiperpools. They both facilitated larger<br />

buffer pools. They each had their advantages and disadvantages. We could not do I/O directly<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 141


from the hiperpools, they were not byte-addressable, and their pages could be stolen any<br />

time. Data spaces were technically byte-addressable, but, <strong>for</strong> per<strong>for</strong>mance reasons, a<br />

lookaside pool was used instead to copy the page. Whenever an application tried to read data<br />

from a data space buffer page, the page was copied from the data space into this temporary<br />

work area within the 2 GB address space.<br />

Another disadvantage of data spaces and hiperpools is that the control blocks representing<br />

these buffers resided in the 2 GB address space. These control blocks created a practical<br />

limit to the size of the buffer pools, depending on other demands <strong>for</strong> virtual storage in the<br />

DBM1 region. Given the control block storage requirements, it is unlikely that a single <strong>DB2</strong><br />

member could exploit all of the central storage that a z/Series processor is capable of<br />

supporting, which is now up to 256 GB, and growing.<br />

<strong>DB2</strong> V8 no longer supports data spaces or hiper pools since 64-bit addressing makes them<br />

obsolete. <strong>DB2</strong> V8 stores all buffers above the bar. <strong>DB2</strong> does I/O directly into and out of the<br />

buffers and never has to copy the data merely to facilitate byte addressability. <strong>DB2</strong> systems<br />

management and operations tasks are simplified and the cost of data moves is reduced.<br />

As of <strong>DB2</strong> V8, the terms buffer pool and virtual pool become synonymous, with the tendency<br />

to use just the term buffer pools.<br />

Buffer pools can now scale to extremely large sizes, constrained only by the physical memory<br />

limits of the machine (64-bit allows <strong>for</strong> 16 exabytes of addressability). However <strong>DB2</strong> imposes<br />

a 1 TB limit, as a safety valve <strong>for</strong> real storage available, as follows:<br />

► The maximum size <strong>for</strong> a single buffer pool is 1 TB.<br />

► The maximum size <strong>for</strong> summation of all active buffer pools is 1 TB.<br />

The buffer pool control blocks, also known as page manipulation blocks (PMBs), are also<br />

moved above the 2 GB bar. Castout buffers used <strong>for</strong> data sharing, are also relocated above<br />

the bar.<br />

When you first migrate to V8, <strong>DB2</strong> determines the buffer pool size based on the following<br />

equation:<br />

VPSIZE + HPSIZE = BPSIZE<br />

We there<strong>for</strong>e recommend you review your virtual buffer pool sizes and your hiperpool buffer<br />

sizes be<strong>for</strong>e you migrate to V8 to make sure you have enough real storage to fully back the<br />

new default buffer pool sizes (see 2.7, “New installation default values” on page 24.).<br />

You also need to adjust down the buffer pool thresholds, since they were initially set up <strong>for</strong> the<br />

write activity of just the relatively small virtual pools.<br />

The EDM pool<br />

The Environmental Descriptor Manager (EDM) deals with the <strong>DB2</strong> metadata of your<br />

databases and applications. It caches and manages the following objects in the EDM pool:<br />

► Data base descriptors (DBDs), skeleton cursor tables (SKCTs), skeleton plan tables<br />

(SKPTs), cache blocks <strong>for</strong> plans, and skeleton dynamic statements (SKDSs)<br />

► Private user versions of the plan (CTs and PTs) during execution<br />

► Authorization cache<br />

DBDs in the EDM pool<br />

In V8, almost all of the storage related to managing DBDs is allocated above the 2 GB bar.<br />

This gives the DBDs the needed space to grow and relieves contention with other objects in<br />

the EDM pool. DBDs are also larger in <strong>DB2</strong> V8 in new-function mode. The size of the DBD<br />

142 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


cache is governed by the DSNZPARM EDMDBDC parameter, with a size between 5 MB and<br />

2 GB.<br />

There is little overhead in below the bar storage to support this new DBD pool above the bar.<br />

So, make sure you adequately size the EDMDBDC parameter in order to avoid continually<br />

loading DBDs from disk.<br />

Storage <strong>for</strong> plans and packages<br />

Plans and packages (SKCT, CT, SKPT, and PT) and the authorization cache are the only<br />

control blocks that are stored in the EDM pool that remains below the bar. The DSNZPARM is<br />

EDMPOOL as be<strong>for</strong>e. As other <strong>DB2</strong> structures have moved above the bar in the DBM1<br />

address space, more space may become available below the bar to accommodate more<br />

plans and packages in the EDM pool.<br />

Remember that if you plan to use the current V7 size of the DSNZPARM EDMPOOL<br />

parameter in V8, the EDM pool may be over-allocated, since the DBDs (and potentially also<br />

the dynamic statement cache) no longer reside in that storage area in V8. However, we<br />

suggest you monitor your EDM pool per<strong>for</strong>mance be<strong>for</strong>e making any changes. Plans and<br />

packages are bigger in <strong>DB2</strong> V8 and consume some of the space in the EDM pool that was<br />

vacated by the DBDs. You can monitor the health of the EDM pool by using the pertinent <strong>DB2</strong><br />

PE report fields monitoring. If SKPT and SKCT I/O are to be eliminated, oversizing the EDM<br />

pool and monitoring SKPT and SKCT requests are best.<br />

The recommendations when monitoring are:<br />

► Failure due to EDM pool full should be 0<br />

► Request not found in EDM pool < 1 to 5%<br />

► CT + PT < 80% of pool<br />

Global dynamic statement cache<br />

In V7, if global dynamic statement caching is active (DSNZPARM CACHEDYN=YES<br />

parameter), the statements can be cached in a data space (if the DSNZPARM EDMDSPAC<br />

parameter is also >0), or in the normal EDM pool. In V8, cached, dynamic SQL statements<br />

are always cached in the EDM statement cache pool above the 2 GB bar. The maximum EDM<br />

Statement Cache size, specified by the DSNZPARM EDMSTMTC parameter, is 1 GB.<br />

The default value <strong>for</strong> EDM STATEMENT CACHE is taken from the EDMPOOL STORAGE<br />

SIZE field on panel DSNTIPC, or 5000 K, whichever is larger. The maximum size is 1048576<br />

KB.<br />

Storage <strong>for</strong> the dynamic statement cache is always allocated (at least 5 MB), and is no longer<br />

related to whether CACHEDYN is YES or NO. This is because the DSNZPARM CACHEDYN<br />

parameter can be changed online in V8, and <strong>DB2</strong> needs an initial size to be allocated at<br />

startup time to allow the size to be changed online.<br />

Although the EDM Statement Cache pool is located above the bar, its size has a real impact<br />

on storage below the bar. It impacts the Statement Cache Blocks pool, which contains various<br />

control blocks <strong>for</strong> dynamic SQL statements that are cached in the EDM Statement Cache<br />

pool above the bar. It impacts the dynamic SQL pools (local cache) below the bar that are<br />

used <strong>for</strong> statement execution and locally cached statements resulting from<br />

KEEPDYNAMIC(YES). The storage consumed below the bar is not only dependent on the<br />

size of the EDM Statement Cache above the bar, but is also dependent on the number of SQL<br />

statements in the cache.<br />

Note that the PTF <strong>for</strong> APAR PQ96772 further relieves virtual storage constraint <strong>for</strong> systems<br />

that are very active with dynamic statement caching by moving statement control blocks<br />

above the bar.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 143


So, we advise you to not overallocate the EDM Statement Cache, but choose a size based on<br />

your needs. Otherwise use the default values. Monitor the EDM Statement Cache and tune it<br />

so that it only contains statements which are frequently in use. Having statements in the<br />

cache which are rarely used can lead to an impact on per<strong>for</strong>mance.<br />

Finally, it is worth noting that SQL statements cached in the EDM Statement Pool Cache may<br />

be much larger in V8 than SQL statements cached in V7. This is primarily due to <strong>DB2</strong> V8<br />

support <strong>for</strong> larger names and Unicode.<br />

Compression dictionaries<br />

The compression dictionary <strong>for</strong> a compressed table space is loaded into virtual storage <strong>for</strong><br />

each compressed table space or partition as it is opened. Each compression dictionary<br />

occupies 64 KB bytes of storage (sixteen 4 KB pages).<br />

Moving the dictionary above the 2 GB bar provides significant storage relief <strong>for</strong> customers<br />

making extensive use of compression. Remember that <strong>DB2</strong> V8 can further increase the<br />

compression dictionary storage requirement as V8 also implements support <strong>for</strong> 4096<br />

partitions <strong>for</strong> a single table; if they are all compressed and open, you would have 4096<br />

compression dictionaries in memory. Notice that most of the open data set <strong>DB2</strong> control blocks<br />

are also above the bar.<br />

The compression dictionary is loaded above the bar after it is built. All references to the<br />

dictionary now use 64-bit pointers. Compression uses standard 64-bit hardware compression<br />

instructions.<br />

SORT pools<br />

Sorting requires a large amount of virtual storage, because there can be several copies of the<br />

data being sorted at a given time.<br />

The <strong>DB2</strong> Sort pool is allocated on a per thread basis up to a maximum of 128 MB depending<br />

on the DSNZPARM SRTPOOL parameter. For example, if SRTPOOL=10, then each<br />

concurrent thread doing an RDS sort could allocate up to 10 MB.<br />

Two kinds of storage pools are used <strong>for</strong> <strong>DB2</strong> V8 sort (also known as RDS sort) to store<br />

various control structures and data records. One is a thread-related local storage pool below<br />

the bar, and the other is a thread-related storage pool sort pool above the bar. We estimate<br />

that over 90% of the sort pool is moved above the 2 GB bar.<br />

To take advantage of the 64-bit addressability, some high level sort control structures remain<br />

in thread-related storage below the 2 GB bar. These structures contain 64-bit pointers to<br />

areas in the thread-related storage pool above the 2 GB bar. Sort tree nodes and data<br />

buffers, which comprise 90% of the Sort pool, are located above the 2 GB bar. The maximum<br />

Sort pool size, specified by the DSNZPARM SRTPOOL parameter is 128 MB. In V7 it was 64<br />

MB.<br />

In V7 the RDS OP pool is allocated as a single global storage pool. In V8 this has changed.<br />

The thread-related local storage pool below the bar is now allocated per thread rather than<br />

global. Storage fragmentation can be higher, but contention is reduced since there is no RDS<br />

OP pool anymore.<br />

RID lists <strong>for</strong> the RID pool<br />

The RID pool is split into two parts. The RID pool part below the 2 GB bar stores the RID<br />

maps which are usually small in number, and the RID pool part above the 2 GB bar contains<br />

the RID lists which normally comprise the bulk of the RID pool storage. Storage size<br />

144 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


elationship between RID map and RID list varies from 1 to 1 to 1 to many. For a typical <strong>DB2</strong><br />

subsystem with heavy RID pool usage, the great majority of RID pool usage is <strong>for</strong> RID lists.<br />

The RID map, which is 10% of the RID pool, is located below the 2 GB bar. The RID list,<br />

which is 90% of the RID pool, is located above the 2 GB bar. The maximum RID pool size,<br />

specified by the DSNZPARM MAXRBLK parameter, is now 10 GB, in <strong>DB2</strong> V7, it was 1 GB.<br />

Because of these changes, there are some slight modifications in estimating the size <strong>for</strong> the<br />

RID pool. The same size RIDMAPs would have held half as many RIDLISTs, (because they<br />

need to contain pointers to 64-bit memory addresses). The RIDMAP size is doubled to<br />

accommodate the same number of 8 byte RIDLISTs, and each RIDLIST now holds twice as<br />

many RIDs. Each RIDBLOCK is now 32 KB in size.<br />

If you have a large RID pool, much less storage is used below 2 GB.<br />

LOB data<br />

With V7, when LOBs need to be materialized, <strong>DB2</strong> does so using data spaces. With V8,<br />

storage above the 2 GB bar inside the DBM1 address space is used instead. Storage<br />

allocation is limited by the DSNZPARM parameters previously used <strong>for</strong> materializing LOBs in<br />

data spaces:<br />

► LOBVALA (the size per user)<br />

► LOBVALS (the size per system)<br />

Other virtual storage topics<br />

There are also several other virtual storage-related enhancements such as the star join<br />

memory pool, DSNZPARM CONTSTOR parameter, DSNZPARM MINSTOR parameter,<br />

DSNZPARM MAXKEEPD parameter, and the short prepare per<strong>for</strong>mance enhancement.<br />

► Star join memory pool<br />

The star join memory pool is a new pool of storage in <strong>DB2</strong> V8, which only exists when star<br />

join is enabled. This new pool is allocated above the 2 GB bar. The star join memory pool<br />

extends <strong>DB2</strong> V8 support <strong>for</strong> sparse indexes <strong>for</strong> star join work files to allow caching data in<br />

virtual memory as well as the keys <strong>for</strong> star join queries. When the star join memory pool is<br />

allocated, the in-memory index is no longer sparse because data caching is most effective<br />

when the entire work file data is cached. See 3.3, “Star join processing enhancements” on<br />

page 53.<br />

A new DSNZPARM parameter, SJMXPOOL, allows you to specify the maximum extent of<br />

the new memory pool <strong>for</strong> star join and can range from 0 to 1024 MB. <strong>DB2</strong> may use a<br />

smaller portion of the space depending on the number of work files kept in the pool at a<br />

certain point of the time. For example, if a value 20 is specified, (which is the default), the<br />

total amount of up to 20 MB of data is stored in the pool at a time. When a value of 0 (zero)<br />

is specified, the star join memory pool is not allocated. In this case, workfiles are not<br />

cached in memory <strong>for</strong> any star join-qualified queries.<br />

If a non-zero positive value is specified <strong>for</strong> the SJMXPOOL, the initial allocation size <strong>for</strong><br />

the pool is the smaller of the specified value and 4 MB. If the specified value is larger than<br />

4 MB, the actual maximum is rounded up to a multiple of 4. For example, if 21 is specified,<br />

the pool expands up to 24 MB. One block is allocated <strong>for</strong> a workfile, if enough space exists<br />

in the pool. When the execution of a star join-qualified query finishes, the allocated blocks<br />

in the pool to process the statement are freed from the pool. If the memory pool is not<br />

created, or the allocation of an individual work file space fails due to the limitation of the<br />

pool size, the star join process continues without using the data caching feature. A sparse<br />

index (the existing feature <strong>for</strong> inside-out processing) may be used, instead.<br />

The star join memory pool is externalized in IFCID 225 records.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 145


See 4.3, “Monitoring DBM1 storage” on page 157 <strong>for</strong> the contents of the 225 record.<br />

► The DSNZPARM CONTSTOR parameter<br />

The CONTSTOR parameter determines whether or not thread storage contraction is to be<br />

per<strong>for</strong>med. Storage contraction tries to free up allocated storage that is no longer in use by<br />

attempting to contract thread local storage pools at commit. If CONTSTOR is set to YES,<br />

two other thresholds are used to govern when storage contraction is per<strong>for</strong>med <strong>for</strong> a<br />

thread.<br />

– SPRMSTH provides a threshold <strong>for</strong> the amount of storage allocated to a thread be<strong>for</strong>e<br />

contraction occurs.<br />

– SPRMCTH provides a threshold <strong>for</strong> the number of commits per<strong>for</strong>med by a thread<br />

be<strong>for</strong>e contraction occurs.<br />

► The DSNZPARM MINSTOR parameter<br />

The MINSTOR parameter is used to direct <strong>DB2</strong> to use storage management algorithms<br />

that minimize the amount of working storage consumed by individual threads, when <strong>DB2</strong><br />

allocates thread-related storage from local storage pools <strong>for</strong> threads. Essentially, a best fit<br />

storage search algorithm is used instead of a first fit algorithm. The trade-off is less<br />

storage fragmentation however slightly more CPU may be consumed.<br />

MINSTOR should normally be set to its default, NO. However, <strong>for</strong> subsystems that have<br />

many long-running threads and are constrained on storage in the DBM1 address space,<br />

specifying YES may help reduce the total storage used in the DBM1 address space.<br />

► The DSNZPARM MAXKEEPD parameter<br />

The MAXKEEPD parameter indirectly controls the size of the Local Dynamic Statement<br />

Cache, which is allocated at the thread level. MAXKEEPD specifies the total number of<br />

prepared, dynamic SQL statements to be saved past commit. This is a system wide limit,<br />

which is en<strong>for</strong>ced at the thread level when the next commit point is reached <strong>for</strong> the thread.<br />

The Local Dynamic Statement Cache provides <strong>for</strong> prepare avoidance and the Global<br />

Dynamic Statement Cache (now above the bar in V8) provides <strong>for</strong> short prepares. Prepare<br />

avoidance is cheaper than a short prepare, but the cost of a short prepare is much<br />

cheaper (100x) than a typical long prepare.<br />

A suggested tuning approach based on trading CPU <strong>for</strong> virtual storage constraint relief is<br />

to incrementally reduce the size of the Local Dynamic Statement Cache by reducing<br />

MAXKEEPD, even setting it to zero, and then monitor per<strong>for</strong>mance and storage utilization.<br />

You may have to increase the Global Dynamic Statement Cache to compensate, if the<br />

Global Dynamic Statement Cache Hit Ratio starts to deteriorate.<br />

In V7, MAXKEEPD has a default of 5000 statements. As the MAXKEEPD threshold is only<br />

evaluated at commit, it is common to see the number of SQL statements cached exceed<br />

this limit. This is not a problem. For a description of MAXKEEPD at V7 level, see the article<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> <strong>OS</strong>/390 Storage Management by John Campbell and Mary Petras, published<br />

in The IDUG Solutions Journal Spring 2000 - Volume 7, Number 1.<br />

► Short prepare per<strong>for</strong>mance enhancement<br />

The short prepare copies a referenced statement from the EDM statement cache pool into<br />

the Local Dynamic Statement Cache and sets it up <strong>for</strong> execution. The overhead varies<br />

depending on the statement execution time but may be 1-2% <strong>for</strong> long running statements.<br />

There is one Local Dynamic Statement Cache pool allocated <strong>for</strong> each thread in <strong>DB2</strong> V7.<br />

This has changed in V8. Now the Local Dynamic Statement Cache is allocated in an array<br />

of 30 global pools. This change should reduce the storage fragmentation below the bar,<br />

however some contention may occur as a result.<br />

The new approach aims to reduce the cost of the <strong>OS</strong> level GETMAINs and FREEMAINs<br />

by going to a centralized storage approach. With this approach, <strong>DB2</strong> uses a number of<br />

146 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.2.2 Per<strong>for</strong>mance<br />

storage pools that are owned by the system, not a particular thread. The new<br />

implementation uses a fixed number of pools.<br />

The size of the local cache <strong>for</strong> dynamic statement associated to a long running thread is<br />

governed by the MAXKEEPD DSNZPARM.<br />

When a new piece of storage is needed, a hash function is used, to randomly assign a<br />

pool. The hash uses the statement identifier as input. Each of the pools is a best fit pool<br />

and it extends its size as needed, in 1 MB chunks. With this approach, <strong>DB2</strong> relies on the<br />

best fit logic to keep the pools at a minimum size. With the thread-based storage model,<br />

further reductions in contractions would have led to some storage increase.<br />

The EDM statement cache contains the skeletons of dynamic SQL if your installation has<br />

YES <strong>for</strong> the CACHE DYNAMIC SQL field of installation panel DSNTIP4. The EDM storage<br />

statistics have in<strong>for</strong>mation that can help you determine how successful your applications<br />

are at finding statements in the cache. KEEPDYNAMIC (YES) specifies that <strong>DB2</strong> keeps<br />

dynamic SQL statements after commit points.<br />

Per<strong>for</strong>mance measurements show:<br />

– Moving prepared statements from agent pools to multiple shared pools. At<br />

MAXKEEPD=12K, the ITR improvement was marginal at 1.4% with negligible delta in<br />

DBM1 VSTOR usage.<br />

– The advantage of the new code becomes more apparent at MAXKEEPD=0. There is<br />

an ITR improvement of 3.9% with a net DBM1 VSTOR savings of 108 MB.<br />

– Most of the ITR gain comes from the reduction of GETMAINs and FREEMAINs issued.<br />

In <strong>DB2</strong> installations using long running threads with a big number of SQL short prepares<br />

<strong>for</strong> dynamic SQL statements, the per<strong>for</strong>mance can be improved using MAXKEEPD=0 in<br />

V8.<br />

A short prepare is always more expensive than simply using the prepared statement in the<br />

centralized shared pools. Short prepare costs 1% or more over prepare avoidance.<br />

MAXKEEPD=0 means do not keep any statements in local dynamic statement cache after<br />

commit. In this particular experiment, we are interested in the effectiveness of the new<br />

code to support more efficient short prepare. With MAXKEEPD=0, all prepares are short<br />

prepare rather than avoiding PREPARE, thereby maximizing any impact from the new<br />

code change. This is not the best per<strong>for</strong>ming option, you can see on “KEEPDYNAMIC<br />

YES” on page 304 that using KEEPDYNAMIC instead can bring 20% ITR improvement.<br />

However MAXKEEPD=0 is good if the environment is virtual storage constrained.<br />

We examine <strong>DB2</strong> real and virtual storage usage by comparing storage usage between V7<br />

and V8 with the same workload at equivalent thread levels. We used various distributed<br />

workloads, as well as a local workload and a data sharing workload.<br />

The per<strong>for</strong>mance tests used here are <strong>for</strong> a common workload running with 500 concurrent<br />

threads <strong>for</strong> both <strong>DB2</strong> V7 and V8, in all of our comparisons. The IRWW workload with different<br />

transaction characteristics was used in order to evaluate the storage considerations when<br />

moving different workloads from <strong>DB2</strong> V7 to V8.<br />

Note that in all the measurement data we present in this section, we removed the buffer pool<br />

storage to get a more accurate picture of the effect on virtual storage.<br />

The <strong>DB2</strong> V7 and V8 system storage configuration we used is documented in Table 4-4.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 147


Table 4-4 System storage configuration <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8<br />

<strong>DB2</strong> V7 uses a data space <strong>for</strong> the dynamic statement cache. In addition, there is a negligible<br />

use of the Sort pool, RID pool, and global dynamic statement cache in the EDM pool (less<br />

than 1 MB). The parameter KEEPDYNAMIC was set to NO so there is no local dynamic<br />

statement cache.<br />

Here are the different types of workloads we examined to understand the impact of static vs.<br />

dynamic SQL:<br />

► Dynamic SQL using CLI and OBDC on AIX, connecting to <strong>DB2</strong> Connect and using DRDA<br />

to communicate with <strong>DB2</strong>.<br />

► Dynamic SQL using the <strong>DB2</strong> Universal Driver Type 4 on AIX, connecting to <strong>DB2</strong> Connect<br />

and using DRDA to communicate with <strong>DB2</strong>.<br />

► Static SQL embedded in a local application running on AIX, connecting to <strong>DB2</strong> Connect<br />

and using DRDA to communicate with <strong>DB2</strong>.<br />

► Static SQL using the <strong>DB2</strong> Universal Driver Type 4 on AIX, using DRDA to directly connect<br />

to <strong>DB2</strong>.<br />

► A local IRWW OLTP workload directly connecting to <strong>DB2</strong> using IMS attach.<br />

► A local IRWW OLTP workload directly connecting to a two member data sharing group<br />

running <strong>DB2</strong> using IMS attach.<br />

During the per<strong>for</strong>mance tests, RMF storage statistics were gathered as well as <strong>DB2</strong> storage<br />

statistics using IFCID 225. In order to validate the storage statistics reported by <strong>DB2</strong> PE, and<br />

storage in<strong>for</strong>mation collected from the RMF monitor reports, system dumps were taken of all<br />

<strong>DB2</strong> address spaces. In addition, SDSF DA (Display Active) real storage usage was<br />

captured. As a result, we were able to compare the difference between <strong>DB2</strong> V7 and V8 DBM1<br />

and DIST virtual and real storage per DBAT and active connection. The results are presented<br />

here.<br />

Remember that your results may be very different as most customer workloads do not<br />

resemble this configuration; usually customers have a mix of different applications all running<br />

in a single <strong>DB2</strong> subsystem. Take this into consideration as you examine the potential impact<br />

of your migration to <strong>DB2</strong> V8.<br />

Virtual and real storage comparison <strong>for</strong> DBM1<br />

We first look at virtual storage used by the DBM1 address space.<br />

Figure 4-4 compares the total virtual storage usage <strong>for</strong> the DBM1 address space <strong>for</strong> all of<br />

these different workloads with <strong>DB2</strong> V7 vs. V8. However, to be fair, the virtual buffer pools were<br />

removed from the equation; you can see that GETMAINed storage is represented by GM - BP<br />

in the graph where the storage <strong>for</strong> these buffer pools were removed.<br />

A significant decrease in storage below the 2 GB bar is possible. With V8, several DBM1<br />

address space structures that consume large amounts of storage below the bar, have moved<br />

148 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

BP type Primary (MB) Above 2 GB bar (MB)<br />

4 KB BPs 438 438<br />

8 KB BPs 16<br />

16 KB BPs 16<br />

EDM pool 146 146


to above the bar, <strong>for</strong> example, buffer pools, compression dictionaries, DBDs in the EDM pool<br />

and some Sort pool and RID list storage. These all come from GETMAINed storage.<br />

The GETMAINed storage after the virtual buffer pools are subtracted in <strong>DB2</strong> V7 does not<br />

change significantly. The predominant storage areas that increase as you migrate from V7 to<br />

V8 in all cases are stack and variable storage. This is primarily thread-related storage which<br />

must be larger to support new V8 functionality such as long names, Unicode support and<br />

some 64-bit addressing requirements. In addition, in V8 the RDS OP Pool used during bind<br />

has been replaced by thread variable storage.<br />

Getmained area is shown as constant <strong>for</strong> all distributed workloads, but in reality V8 is smaller.<br />

The problem is that virtual pool size is artificially subtracted without accounting <strong>for</strong> an<br />

overhead associated with data space buffer pool, such as lookaside buffer and data space<br />

buffer control blocks.<br />

KB<br />

450000<br />

400000<br />

350000<br />

300000<br />

250000<br />

200000<br />

150000<br />

100000<br />

50000<br />

0<br />

DBM1 below 2 GB<br />

Virtual Storage Comparison<br />

V7 CLI<br />

V8 CLI<br />

Figure 4-4 DBM1 below 2 GB virtual storage comparison <strong>for</strong> different workloads<br />

Non-distributed per<strong>for</strong>mance<br />

Here we report on the IRWW workload <strong>for</strong> a non-distributed environment comparing the<br />

DBM1 virtual storage consumption <strong>for</strong> the different main virtual storage areas in V7 and V8<br />

<strong>for</strong> a non-data sharing environment and a data sharing environment.<br />

Table 4-5 Non-distributed DBM1 virtual storage comparison<br />

V7 JDBC<br />

V8 JDBC<br />

V7 EMB<br />

V8 EMB<br />

V7 SQLJ<br />

V8 SQLJ<br />

V7 IRWW<br />

V8 IRWW<br />

V7 IRWW DSHR<br />

V8 IRWW DHSR<br />

V7 IRWW V8 IRWW % change V7 IRWW V8 IRWW % change<br />

Non-data sharing Data sharing<br />

GM - BP 33075 21146 -36% 50248 22830 -55%<br />

Variable 47565 71967 51% 38738 33669 -13%<br />

Stack<br />

Fixed<br />

Variable<br />

GM-BP<br />

Fixed 102 328 322% 87 195 124%<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 149


Stack 11356 21033 85% 8648 19799 129%<br />

Total 92098 114473 24% 97721 76493 -22%<br />

Here we observe that the data sharing virtual storage overall decreases by 22% whereas the<br />

virtual storage increase in a non-data sharing environment is 24% more. This is also seen<br />

visually in Figure 4-4 on page 149.<br />

Part of the increase in total virtual storage in non-data sharing is because <strong>DB2</strong> V8 increases<br />

the number of deferred write engines from 300 to 600, (however storage <strong>for</strong> deferred write<br />

engines is only allocated as the high water mark <strong>for</strong> in use deferred write engines increase).<br />

This is in addition to larger plan/package/SQL-related structures in <strong>DB2</strong> V8 which are<br />

required to support long names, Unicode and some 64-bit addressing.<br />

Important: PTF UK14283 <strong>for</strong> APAR PK21237 has modified the buffer manager engines to<br />

use a single common above-the-bar storage pool, rather than having a separate pool <strong>for</strong><br />

each engine. Additionally, the default maximum <strong>for</strong> the number of engines has been<br />

reduced.<br />

Data sharing shows an overall decrease because the growth in storage described above is<br />

offset by the castout buffers also moving above the bar in <strong>DB2</strong> V8. This can be shown by the<br />

significant decrease in GMB storage in data sharing.<br />

Distributed per<strong>for</strong>mance<br />

Table 4-6 summarizes the storage usage results <strong>for</strong> distributed workloads using CLI, JDBC,<br />

embedded SQL, and SQLJ so they can be easily compared.<br />

Table 4-6 Virtual storage comparison <strong>for</strong> CLI, JDBC, embedded SQL, and SQLJ workloads<br />

CLI JDBC Embedded SQL SQLJ<br />

DBM1 VS in MB<br />

below 2 GB<br />

DBM1 VS in KB<br />

per user thread<br />

DBM1 VS in KB<br />

agent sys<br />

storage per sys<br />

agent<br />

DIST VS in KB<br />

per active<br />

connection<br />

V8 V7 to V8%<br />

increase<br />

150 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

V7 IRWW V8 IRWW % change V7 IRWW V8 IRWW % change<br />

Non-data sharing Data sharing<br />

V8 V7 to V8%<br />

increase<br />

V8 V7 to V8%<br />

increase<br />

V8 V7 to V8%<br />

increase<br />

319 -55% to 26% 402 -48% to 26% 355 -50% to 38% 311 -55% to 28%<br />

338 59% 509 49% 318 52% 323 72%<br />

223 76% 202 24% 239 32% 244 39%<br />

358 162% 403 168% 254 97% 383 201%


Attention: The ranges of percentages reported in the row DBM1 VS (Virtual Storage) in<br />

MB below 2 GB actually reflect the percent increase moving from V7 to V8 with and<br />

without the virtual buffer pools. Naturally, a decrease in the virtual storage is possible since<br />

the virtual buffer pools move above the 2 GB bar. In the case of large buffer pools, they are<br />

likely to be using hiperpools and data space buffer pools, so this would not apply. You also<br />

see a larger decrease if you compress some of your data, since compression dictionaries<br />

also move above the bar.<br />

We can make the following conclusions about the per<strong>for</strong>mance data in Table 4-6:<br />

A general increase in <strong>DB2</strong> V8 DBM1 virtual storage below the 2 GB bar in the distributed<br />

environment is observed:<br />

► The virtual storage usage <strong>for</strong> the DBM1 address space below the 2 GB bar in V8<br />

increases in the range of 24 to 29%. This increase does not take into account the storage<br />

<strong>for</strong> virtual buffer pools. If it did, then the virtual storage usage <strong>for</strong> the DBM1 address space<br />

below the 2 GB bar in V8 decreases in the range of 55 to 48%.<br />

This is primarily due to larger thread-related storage structures required by <strong>DB2</strong> V8 to<br />

support new functionality such as long names, longer SQL statements, Unicode and 64-bit<br />

addressing.<br />

The DBM1 virtual storage increase per distributed user thread is in the range of 49 to 72%.<br />

The predominant contributors are non-system thread storage and user stack storage.<br />

For the SQLJ workload the virtual storage per active connection increased by 201%.<br />

► Total DBM1 VS without BP - up to 38% increase <strong>for</strong> the embedded SQL workload<br />

► Per User Thread - up to 73% increase <strong>for</strong> the SQLJ workload<br />

► Per System Agent - up to 76% increase <strong>for</strong> the CLI workload<br />

As virtual storage increases, real storage usage will generally increase in order to back the<br />

virtual storage requirement.<br />

User thread storage comparison<br />

The increase in storage is primarily thread-related, as the GETMAINed areas and fixed<br />

storage pools did not change with the different workloads in either V7 or V8.<br />

<strong>DB2</strong> V8 uses more storage <strong>for</strong> each thread in the DBM1 address space due to:<br />

► Thread structures increased in size to support larger names in <strong>DB2</strong>.<br />

► The RDS OP pool storage that was used at bind time in V7 is now acquired from the<br />

thread's variable storage pool.<br />

► Some <strong>DB2</strong> structures must increase in size to support 64-bit addresses.<br />

This section compares the user thread storage in DBM1 below the 2 GB bar and references<br />

Figure 4-5.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 151


KB<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

Figure 4-5 DBM1 user thread storage comparison <strong>DB2</strong> V7 vs. V8<br />

OTHER includes RDS OP pool (in V7 only), RID pool, and trace tables.<br />

This graph shows that, in general, the DBM1 storage required <strong>for</strong> each thread increases as<br />

we move from <strong>DB2</strong> V7 to V8. Comparing this graph with Figure 4-4, we can conclude the<br />

increase in thread storage is the most significant driver <strong>for</strong> the overall storage increase in the<br />

DBM1 address space, as we move from <strong>DB2</strong> V7 to V8 with distributed applications.<br />

For dynamic SQL, here we can see that more storage is required by <strong>DB2</strong> V8 to prepare the<br />

dynamic SQL. Once again, this increase in storage is needed to support <strong>DB2</strong> functionality<br />

such as processing SQL in Unicode and support <strong>for</strong> long names. We also observe that the<br />

dynamic statement cache (DSC) memory usage has increased.<br />

Tip: PTF UK00991<strong>for</strong> APAR PQ96772 provides significant virtual storage relief <strong>for</strong> large,<br />

dynamic SQL cache environments by moving the DSC control blocks above the bar.<br />

DIST address space<br />

Now, let us turn our attention briefly to the DIST address space, since the total <strong>DB2</strong> demands<br />

on storage extend beyond the DBM1 address space.<br />

Table 4-6 on page 150 compares the virtual storage consumed by active distributed<br />

connections in the DIST address space <strong>for</strong> <strong>DB2</strong> V7 and V8 <strong>for</strong> all distributed workloads we<br />

studied. The table shows quite a significant increase in virtual storage used by active<br />

distributed connections in the DIST address space, from 45% to 169% <strong>for</strong> SQLJ and JDBC<br />

workloads respectively. This increase may not be an issue with distributed inactive thread<br />

processing (CMTSTAT=INACTIVE).<br />

The majority of this growth is stack storage and the variable subpools. These are very<br />

dynamic pools with the storage owned and consumed by thread-related activities.<br />

152 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

DBM1 below 2 GB VS<br />

User Thread Storage Comparison<br />

V7 CLI<br />

V8 CLI<br />

V7 JDBC<br />

V8 JDBC<br />

V7 EMB<br />

V8 EMB<br />

V7 SQLJ<br />

V8 SQLJ<br />

V7 IRWW<br />

V8 IRWW<br />

V7 IRWW DSHR<br />

V8 IRWW DSHR<br />

Other<br />

Stack<br />

DSC<br />

User


Thread-related storage is much larger in V8 to support all the new function consumed by<br />

threads. The main driver is support <strong>for</strong> much larger identifiers within <strong>DB2</strong>.<br />

IRLM address space<br />

IRLM V2.2 which is shipped with <strong>DB2</strong> V8, is now a 64-bit application in which the locks now<br />

always reside above the 2 GB bar. These changes also have a significant impact on virtual<br />

storage used by <strong>DB2</strong>, if you currently specify PC=NO.<br />

Refer to 4.6, “IRLM V2.2” on page 171, <strong>for</strong> a more detailed discussion of IRLM and virtual<br />

storage.<br />

MSTR address space<br />

The MSTR address space has not caused any problems related to being virtual<br />

storage-constrained. In addition, the MSTR address space is still all coded as 31-bit. We<br />

there<strong>for</strong>e have not done any specific studies on virtual storage usage of the MSTR address<br />

space in V8 compared with V7.<br />

Real storage<br />

An implication of the z/<strong>OS</strong> implementation of the z/Architecture in 64-bit mode is there is no<br />

more Expanded Storage. If a page or ‘frame’ needs to be paged out of real memory by the<br />

system, it is paged out directly to disk. This can have an extraordinary impact on <strong>DB2</strong><br />

per<strong>for</strong>mance, especially if the buffer pools, or part of the buffer pools, are paged out to<br />

auxiliary storage.<br />

<strong>DB2</strong> V8 requires more virtual storage to accommodate:<br />

► Bigger modules, control blocks, and working storage<br />

► Higher default and maximum buffer pool size, RID pool size, sort pool size, EDM pool size<br />

and authorization cache<br />

► More and larger user threads<br />

► More deferred write engines and castout engines (300 -> 600 maximum)<br />

► More parallelism enabled<br />

► Locks moved above the 2 GB bar<br />

This increased demand <strong>for</strong> virtual storage there<strong>for</strong>e increases the demand on the amount of<br />

real (or main) storage that is available on the system (maximum 512 GB on a z9 EC model<br />

S38 or S54) or LPAR (maximum 128 GB).<br />

There are messages regarding what storage is currently available but the storage in<strong>for</strong>mation<br />

contained in these messages can be overly optimistic. The real storage is by z/<strong>OS</strong> image or<br />

LPAR, and you could have several other <strong>DB2</strong> subsystems, each contending <strong>for</strong> the same real<br />

storage. The messages are documented in Table 4-7.<br />

Table 4-7 <strong>DB2</strong> storage messages<br />

Message Message in<strong>for</strong>mation<br />

DSNB536I Indicates that the total buffer pool virtual storage requirement exceeds the size<br />

of real storage capacity of the z/<strong>OS</strong> image.<br />

DSNB610I Indicates that a request to define or increase the size of the buffer pool exceeds<br />

the smaller of twice the amount of real storage of the z/<strong>OS</strong> image or 1 TB.<br />

DSNB508I Issued when the total size used by all buffer pools exceeds 1 TB.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 153


For the same buffer pool size and other configuration settings, in general, a 1 to 20% increase<br />

in demand <strong>for</strong> real storage <strong>for</strong> medium to large <strong>DB2</strong> V8 subsystems is experienced. For<br />

smaller <strong>DB2</strong> subsystems, we experience a higher increase. Measurements have seen as little<br />

as 4 to 5% increase demand <strong>for</strong> real storage, in the workloads used.<br />

Your mileage will definitely vary, depending on the type of <strong>DB2</strong> workload (<strong>for</strong> example, simple<br />

OLTP SQL compared to complex, query-based SQL) and the current demands <strong>DB2</strong> is placing<br />

on your real storage. It is important to ask if <strong>DB2</strong> is a major user of real storage on your<br />

system or a minor user of real storage.<br />

We first compare real storage measurements <strong>for</strong> various distributed workloads. These<br />

scenarios tend to be a “worst case” <strong>for</strong> studying real storage requirements in <strong>DB2</strong> V8,<br />

because the DIST address space storage has also increased in V8, which also drives the<br />

demand <strong>for</strong> real storage in the LPAR. Normally you would see less demand on real storage<br />

when you are only running a local workload since the DIST address space is not used.<br />

Distributed per<strong>for</strong>mance<br />

We can make the following conclusions about the per<strong>for</strong>mance data in Table 4-8.<br />

The real storage used <strong>for</strong> CLI ODBC and embedded SQL workloads is significantly less than<br />

those <strong>for</strong> JDBC and SQLJ. The real storage increase on an LPAR basis is as high as 20% <strong>for</strong><br />

the JDBC workload, compared with 11% <strong>for</strong> the CLI workload.<br />

Table 4-8 Real storage comparison <strong>for</strong> CLI, JDBC, embedded SQL, and SQLJ workloads<br />

Real storage in<br />

MB <strong>for</strong> LPAR<br />

Figure 4-6 illustrates the difference in real storage between <strong>DB2</strong> V7 and V8 <strong>for</strong> the same<br />

series of per<strong>for</strong>mance tests already discussed in this section. We measure the real storage<br />

consumed <strong>for</strong> the different workloads comparing <strong>DB2</strong> V7 usage to that of V8 <strong>for</strong> the DBM1<br />

and DIST address spaces. As you can see, the real storage growth in <strong>DB2</strong> V8 is significant<br />

and something you need to prepare <strong>for</strong>, as you migrate to V8.<br />

154 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CLI JDBC Embedded SQL SQLJ<br />

V8 V7 to V8%<br />

increase<br />

V8 V7 to V8%<br />

increase<br />

V8 V7 to V8%<br />

increase<br />

V8 V7 to V8%<br />

increase<br />

1196 11% 1410 20% 1175 11% 1238 18%<br />

DBM1 547 24% 688 29% 566 29% 523 25%<br />

DIST 70 64% 137 169% 74 73% 63 45%<br />

IRLM 5 139% 5 139%<br />

MSTR 19 19% 18 19%<br />

OTHER 555 -3% 563 -2% 535 -8% 652 12%<br />

Note: The row name OTHER records the real storage consumed by the whole LPAR minus<br />

those address spaces separately listed in the table.<br />

The real storage values <strong>for</strong> IRLM and MSTR were not separately captured <strong>for</strong> the static<br />

cases; as a result, these times are reflected in the table under OTHER. The real storage<br />

consumed by the IRLM and MSTR address spaces does not have significant changes from<br />

the values already noted <strong>for</strong> the CLI and JDBC tests.


MB<br />

1600<br />

1400<br />

1200<br />

1000<br />

800<br />

600<br />

400<br />

200<br />

0<br />

V7 CLI<br />

V7 and V8 Real Storage Comparison<br />

V8 CLI<br />

V7 JDBC<br />

V8 JDBC<br />

V7 EMB<br />

Figure 4-6 Real storage comparison <strong>DB2</strong> V7 vs. V8<br />

V8 EMB<br />

V7 SQLJ<br />

V8 SQLJ<br />

Other<br />

DIST<br />

DBM1<br />

The “OTHER” bar in the graph represents the sum of the real storage consumed by MSTR,<br />

IRLM and other system address spaces. As you can see, this is fairly stable <strong>for</strong> all the tests.<br />

We see an increase in both the DBM1 address space and the DIST address space real<br />

storage usage, as we execute the same workload levels (500 DBAT threads) <strong>for</strong> each<br />

distributed workload.<br />

There is a real storage increase of 20% in the JDBC application within the LPAR. For JDBC,<br />

the DBM1 real storage increases 29%, the DIST real storage increases 169%. Overall, the<br />

DIST address space uses far less storage than the DBM1 address space, even in V8. So, the<br />

huge increase in DIST address space storage should not be considered a big problem,<br />

unless you have a large distributed workload and are already real memory-constrained.<br />

Although this is not shown on the graph, the MSTR address space also sees an increase of<br />

19% over V7. However, as the MSTR address space only has a small storage footprint, we do<br />

not consider this a problem.<br />

Similarly, the IRLM real storage increased 139%. This is also not shown on the graph. For the<br />

test workloads we used, the IRLM is not a huge consumer of storage, even in V8, since the<br />

workloads we use do not generate a large amount of locks. Your workloads probably generate<br />

many more locks and drive IRLM real storage requirements a little more, since many<br />

customers generally run a large and very diverse mix of workloads concurrently, which in turn<br />

tends to generate more locking activity. The IRLM requires more real storage in V8, primarily<br />

due to the increase in size of IRLM control blocks. We there<strong>for</strong>e recommend you also<br />

consider the IRLM storage requirements in your real storage estimates.<br />

Real storage values <strong>for</strong> MSTR and IRLM do not change much and are included under<br />

OTHER.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 155


4.2.3 Conclusion<br />

Nondistributed per<strong>for</strong>mance<br />

We examined the per<strong>for</strong>mance characteristics <strong>for</strong> a local workload in both data sharing and<br />

non-data sharing environments. The measurement test used the IRWW OLTP workload using<br />

78 concurrent threads with 480 MB of virtual buffer pools in <strong>DB2</strong> V7 vs. V8.<br />

There was an 8% increase in real storage usage in <strong>DB2</strong> V8 at the LPAR overall level as<br />

compared to <strong>DB2</strong> V7.<br />

A batch workload with a small number of threads each doing a single-thread table space scan<br />

with a 1200 MB buffer pool configuration showed only a 3% increase in real storage usage in<br />

<strong>DB2</strong> V8 at the overall LPAR level as compared to <strong>DB2</strong> V7.<br />

<strong>DB2</strong> V8 has significant improvements in virtual storage constraint relief as many of the large<br />

<strong>DB2</strong> structures (<strong>for</strong> example, buffer pools, EDM DBDs, and compression dictionaries) in the<br />

DBM1 address space have moved above the 2 GB bar. The most important factor here is the<br />

percentage of storage used <strong>for</strong> threads and local DSC compared to other users of DBM1<br />

below 2 GB in V7. This can vary widely among installations.<br />

For the same <strong>DB2</strong> configuration (<strong>for</strong> example, buffer pool sizes), we experienced a 1% to 20%<br />

increase in real storage requirements <strong>for</strong> medium and large <strong>DB2</strong> subsystems. Larger<br />

increases are possible <strong>for</strong> smaller <strong>DB2</strong> subsystems. This is a result of higher defaults,<br />

minimum and maximum buffer pool sizes, RID pool size, Sort pool size, EDM pool size and<br />

bigger threads. Bigger modules, control blocks and working storage also contribute to the<br />

increase in demand <strong>for</strong> real storage.<br />

How many additional threads, if any, can be supported depends on the Thread Footprint®<br />

which varies by workload depending on the duration of the thread, SQL workload, RELEASE<br />

parameter setting on plan and package bind, effectiveness of thread storage contraction<br />

(CONTSTOR=YES), and storage <strong>for</strong> pools, control blocks, and work areas moved above the<br />

2 GB bar.<br />

4.2.4 Recommendations<br />

<strong>DB2</strong> V8 64-bit support does not totally eliminate virtual storage constraint below the 2 GB bar<br />

in the DBM1 address space. However, V8 provides valuable additional relief, but the relief<br />

varies by installation.<br />

<strong>DB2</strong> V8 is able to exploit all available processors’ storage on the latest processor models<br />

(currently 256 GB, current <strong>DB2</strong> limit of 1 TB), through:<br />

► Supporting extremely large buffer pools to eliminate I/O<br />

► Exploiting increased ESA Compression<br />

► Using larger thread Sort pool<br />

► Allowing more compressed table spaces and partitions<br />

You must have sufficient real storage to fully back increased storage use usage.<br />

You must still continue to plan <strong>for</strong>, monitor and tune virtual storage usage below the 2 GB bar.<br />

The <strong>DB2</strong> Lab's recommendation is that users should implement a methodology which<br />

incorporates the development and measurement of a production workload to achieve<br />

accurate projections <strong>for</strong> virtual storage recommendations. The resulting measurements need<br />

to be evaluated using <strong>for</strong>mulas <strong>for</strong> calculating the thread storage footprint (virtual storage per<br />

thread) and the estimation of the maximum possible threads.<br />

156 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


If you have not measured the amount of storage per thread, here are some rough estimates:<br />

► Low-end: 200 to 400 KB - Static<br />

► Mid-range: 500 KB to 2 M - Static/Dynamic<br />

► High-end: 3 MB to 10 MB or higher - Dynamic, heavy sort, parallelism applied, long<br />

running persistent thread (WFI, CICS Protected Entry Threads with many packages with<br />

RELEASE(DEALLOCATE) or (RELEASE(COMMIT) with CONTSTOR=NO).<br />

These ranges are based on historical observations of typical SQL statements utilized in<br />

customer production environments, the low-end of the range representing static SQL vs. the<br />

high-end representing dynamic SQL-based workloads. The estimation should be verified and<br />

modified appropriately through the actual measurement using the above <strong>for</strong>mulas.<br />

4.3 Monitoring DBM1 storage<br />

Despite the fact that <strong>DB2</strong> V8 provides many enhancements to relieve virtual storage<br />

constraints in <strong>DB2</strong>, it is still important you proactively monitor virtual storage usage within<br />

<strong>DB2</strong>.<br />

It is also important <strong>for</strong> you to monitor storage usage above the bar. Within the z/<strong>OS</strong><br />

implementation of the z/Architecture, there is no expanded storage. Paging goes directly to<br />

disk, and then you will obviously suffer the per<strong>for</strong>mance impact of writing to and reading from<br />

disk. <strong>DB2</strong> should rarely page to disk. So, it is more important than ever now to monitor the<br />

number of real frames in use and ensure auxiliary storage is never used.<br />

<strong>DB2</strong> provides two new messages to help you not overallocate your buffer pools relative to the<br />

amount of real storage available. This is important as buffer pools can now scale to extremely<br />

large sizes, constrained only by the physical memory limits of the machine (64-bit allows <strong>for</strong><br />

16 exabytes of addressability).<br />

► DSNB536I: This warning message indicates the total buffer pool virtual storage<br />

requirement of this <strong>DB2</strong> subsystem exceeds the size of real storage of the z/<strong>OS</strong> image. To<br />

relieve this situation you can either allocate more real storage to the z/<strong>OS</strong> image or, if<br />

there is not enough real storage to hold the buffers, then the number of buffers needs to be<br />

reduced.<br />

► DSNB610I: This warning message indicates that a request to increase the size of the<br />

buffer pool will exceed twice the real storage available to the z/<strong>OS</strong> image, or the normal<br />

allocation of a buffer pool not previously used will cause an aggregate size which exceeds<br />

the real storage. Either request is then limited to 8 MB (2000 pages <strong>for</strong> 4 KB, 1000 pages<br />

<strong>for</strong> 8 KB, 500 pages <strong>for</strong> 16 KB, and 250 pages <strong>for</strong> 32 KB).<br />

<strong>DB2</strong> still monitors Short on Storage (S<strong>OS</strong>) conditions below the bar in the DBM1 address<br />

space by monitoring a storage cushion within the DBM1 address space. When the head room<br />

is less than this storage cushion value, <strong>DB2</strong> attempts to contract and reclaim free memory<br />

segments which have been fragmented. This work can impact <strong>DB2</strong> per<strong>for</strong>mance if <strong>DB2</strong> is<br />

continually in this state.<br />

<strong>DB2</strong> V8 introduces a number of new counters to IFCID 225 to support <strong>DB2</strong> V8. In addition the<br />

IFCID 225 is now available via IFI READS to V8 and V7 (APAR PQ85764), this makes its<br />

contents immediately available to online monitors instead of the last interval values.<br />

The statistics gathered represent a point-in-time view of storage used in the DBM1 address<br />

space at the time the record is cut. They do not record in<strong>for</strong>mation about storage utilization in<br />

any other address space. IFCID 225 records are cut at statistics intervals whenever the <strong>DB2</strong><br />

Statistics class 6 trace is active.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 157


Important: With PTFs UK04394 (<strong>DB2</strong> V8) and UK04393 (<strong>DB2</strong> V7) <strong>for</strong> APAR PQ99658 the<br />

availability of virtual storage diagnostic record IFCID 225 is added to Statistics Class 1, the<br />

system parameter STATIME default time is reduced from 30 minutes to 5, and an internal<br />

cache of IFCID 225 records is being kept to track storage changes over time.<br />

Example 4-1 shows an extract from a <strong>DB2</strong> PE V8.1 Statistics Long Trace, showing the DBM1<br />

STORAGE STATISTICS sections <strong>for</strong> a <strong>DB2</strong> V7 subsystem. The report was produced with the<br />

fix <strong>for</strong> APAR PQ91101 applied to <strong>DB2</strong> V7 and the fix <strong>for</strong> APAR PQ94872 applied to <strong>DB2</strong> PE.<br />

See also 10.2, “<strong>DB2</strong> Per<strong>for</strong>mance Expert” on page 364, and Appendix B, “The DBM1 storage<br />

map” on page 393.<br />

Example 4-1 DBM1 Storage Statistics <strong>for</strong> a <strong>DB2</strong> V7 subsystem<br />

DBM1 AND MVS STORAGE BELOW 2 GB QUANTITY DBM1 AND MVS STORAGE BELOW 2 GB CONTINUED QUANTITY<br />

-------------------------------------------- ------------------ -------------------------------------------- ------------------<br />

TOTAL DBM1 STORAGE BELOW 2 GB (MB) 779.63 24 BIT LOW PRIVATE (MB) 0.21<br />

TOTAL GETMAINED STORAGE (MB) 599.18 24 BIT HIGH PRIVATE (MB) 0.43<br />

VIRTUAL BUFFER POOLS (MB) 437.50 31 BIT EXTENDED LOW PRIVATE (MB) 24.64<br />

VIRTUAL POOL CONTROL BLOCKS (MB) 13.67 31 BIT EXTENDED HIGH PRIVATE (MB) 794.60<br />

EDM POOL (MB) 146.48 EXTENDED REGION SIZE (MAX) (MB) 1628.00<br />

COMPRESSION DICTIONARY (MB) 0.00 EXTENDED CSA SIZE (MB) 256.83<br />

CASTOUT BUFFERS (MB) 0.00<br />

DATA SPACE LOOKASIDE BUFFER (MB) 0.00 AVERAGE THREAD FOOTPRINT (MB) 0.30<br />

HIPERPOOL CONTROL BLOCKS (MB) 0.00 MAX NUMBER OF P<strong>OS</strong>SIBLE THREADS 2593.01<br />

DATA SPACE BP CONTROL BLOCKS (MB) 0.00<br />

TOTAL VARIABLE STORAGE (MB) 153.39<br />

TOTAL AGENT LOCAL STORAGE (MB) 109.16<br />

TOTAL AGENT SYSTEM STORAGE (MB) 3.54<br />

NUMBER OF PREFETCH ENGINES 5<br />

NUMBER OF DEFERRED WRITE ENGINES 26<br />

NUMBER OF CASTOUT ENGINES 0<br />

NUMBER OF GBP WRITE ENGINES 0<br />

NUMBER OF P-LOCK/NOTIFY EXIT ENGINES 0<br />

TOTAL AGENT NON-SYSTEM STORAGE (MB) 105.63<br />

TOTAL NUMBER OF ACTIVE USER THREADS 500<br />

RDS OP POOL (MB) 1.15<br />

RID POOL (MB) 0.57<br />

PIPE MANAGER SUB POOL (MB) 0.00<br />

LOCAL DYNAMIC STMT CACHE CNTL BLKS (MB) 0.99<br />

THREAD COPIES OF CACHED SQL STMTS (MB) 22.77<br />

IN USE STORAGE (MB) N/A<br />

STATEMENTS COUNT N/A<br />

HWM FOR ALLOCATED STATEMENTS (MB) N/A<br />

STATEMENT COUNT AT HWM N/A<br />

DATE AT HWM N/A<br />

TIME AT HWM N/A<br />

BUFFER & DATA MANAGER TRACE TBL (MB) 16.95<br />

TOTAL FIXED STORAGE (MB) 0.30<br />

TOTAL GETMAINED STACK STORAGE (MB) 26.77<br />

STORAGE CUSHION (MB) 132.58<br />

DBM1 STORAGE ABOVE 2 GB QUANTITY REAL AND AUXILIARY STORAGE QUANTITY<br />

-------------------------------------------- ------------------ -------------------------------------------- ------------------<br />

FIXED STORAGE (MB) N/A REAL STORAGE IN USE (MB) 516.13<br />

GETMAINED STORAGE (MB) N/A AUXILIARY STORAGE IN USE (MB) 0.00<br />

COMPRESSION DICTIONARY (MB) N/A<br />

CACHED DYNAMIC SQL STATEMENTS (MAX) (MB) N/A<br />

DBD CACHE (MAX) (MB) N/A<br />

VARIABLE STORAGE (MB) N/A<br />

VIRTUAL BUFFER POOLS (MB) N/A<br />

VIRTUAL POOL CONTROL BLOCKS (MB) N/A<br />

CASTOUT BUFFERS (MB) N/A<br />

STAR JOIN MEMORY POOL (MB) N/A<br />

The <strong>for</strong>mat of the DBM1 Storage Statistics sections of the <strong>DB2</strong> PE Statistics Detail Report is<br />

enhanced over previous versions. See <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 <strong>Version</strong> 7 Selected<br />

Per<strong>for</strong>mance <strong>Topics</strong>, SG24-6894, <strong>for</strong> an example of the previous report. The new report is<br />

hierarchical, more complete and logically organized.<br />

158 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Be aware that IFCID 225 represents a “snapshot” of DBM1 storage usage at a particular point<br />

in time. On an active subsystem, it is not uncommon <strong>for</strong> <strong>DB2</strong> to be in the process of allocating<br />

storage while freeing up other storage. So, the numbers presented in IFCID 225 may keep<br />

changing and do not always add up. However, they become consistent after a while and can<br />

be used as a good guide to what is happening in the DBM1 address space. In addition, keep<br />

in mind that these numbers show the <strong>DB2</strong> side. MVS has a different picture which tends to be<br />

more pessimistic. <strong>DB2</strong> generally acquires storage from MVS in chunks but may not<br />

immediately use the storage <strong>for</strong> any particular purpose within <strong>DB2</strong>. MVS sees the whole<br />

chunk as being allocated and used.<br />

We have seen that <strong>DB2</strong> maintains four main types of storage:<br />

► Stack Storage (SKB): Used <strong>for</strong> very active thread-related storage.<br />

► Getmained Block (GMB) Storage: Used <strong>for</strong> specific purposes such as buffer pools and<br />

compression dictionaries.<br />

► Fixed pools : Storage is sub-allocated into the same length blocks and optimized <strong>for</strong><br />

per<strong>for</strong>mance.<br />

► Variable pools: General use pools of storage, sub-allocated into variable length blocks.<br />

In this example, the TOTAL DBM1 STORAGE BELOW 2 GB is 779.63 MB.<br />

This total can be split up into the following components:<br />

► TOTAL GETMAINED STORAGE = 599.18 MB<br />

► TOTAL VARIABLE STORAGE = 153.39 MB<br />

► TOTAL FIXED STORAGE = 0.30 MB<br />

► TOTAL GETMAINED STACK STORAGE = 26.77 MB<br />

GETMAINED Storage<br />

The TOTAL GETMAINED STORAGE is storage acquired by <strong>DB2</strong> as GETMAINed Blocks<br />

(GMB). In V7, this is generally the largest consumer of storage in the DBM1 address space. It<br />

includes space <strong>for</strong> virtual buffer pools, virtual buffer pool control blocks, the EDM pool,<br />

compression dictionaries, castout buffers, the data space lookaside buffers, hiper pool control<br />

blocks and data space buffer pool control blocks. We can see these indented in the report.<br />

Note however that these numbers may not add up to TOTAL GETMAINED STORAGE<br />

because <strong>DB2</strong> does not collect statistics on all GETMAINed storage.<br />

Buffer pools are usually the major consumers of DBM1 storage.<br />

► The storage required <strong>for</strong> the virtual buffer pools is shown by the following indicator:<br />

– VIRTUAL BUFFER POOLS = 437.50 MB<br />

► Independent of the page size, a control block of 128 bytes (V7) or 144 bytes (V8) is<br />

allocated <strong>for</strong> each page in the virtual buffer pool. The storage required is shown by the<br />

following indicator:<br />

– VIRTUAL BUFFER POOL CONTROL BLOCKS = 13.67 MB<br />

► Hiperpools are not allocated in the DBM1 address space but storage is allocated inside<br />

the DBM1 address space <strong>for</strong> the 56-byte hiperpool control block associated with each<br />

hiperpool buffer. The storage required is shown by the following indicator:<br />

– HIPERPOOL CONTROL BLOCKS = 0 MB (hiperpools are not used here)<br />

► If you allocate the buffers to data spaces (V7), additional storage is required in the DBM1<br />

address space. A control block of 128 bytes is allocated <strong>for</strong> each data space buffer<br />

defined. The lookaside buffers also utilize a sizable amount of DBM1 virtual storage. The<br />

storage required is shown by the following indicators:<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 159


– DATASPACE BP CONTROL BLOCKS = 0 MB (data spaces are not used here)<br />

– DATASPACE LOOKASIDE BUFFER = 0 MB<br />

In our example, buffer pools and control structures use a total of 451.17 MB, which represents<br />

almost 58% of the total DBM1 storage.<br />

Besides the virtual storage required <strong>for</strong> the buffer pools, other components can be large<br />

consumers of virtual storage in the DBM1 address space depending on the workload and<br />

system parameter settings:<br />

► The EDM pool containing active and skeleton plans and packages, dynamic statements,<br />

and Database Descriptors (DBDs). The maximum size is specified by the system<br />

parameter EDMPOOL in DSNZPARM. The storage used is shown by the following<br />

indicator:<br />

– EDM POOL = 146.48 MB<br />

► Compression dictionaries can also consume significant amounts of storage in the DBM1<br />

address space, especially when a compression dictionary is required <strong>for</strong> every partition of<br />

a partitioned table space. The compression dictionary <strong>for</strong> each table space/partition that is<br />

opened. The size of a compression dictionary is 64 KB. The storage required is shown by<br />

the following indicator:<br />

– COMPRESSION DICTIONARY = 0 MB (compression is not used here)<br />

► <strong>DB2</strong> allocates Castout buffers only in a data sharing environment. Castout buffers are<br />

used by <strong>DB2</strong> to read changed pages from the GBP into the DBM1 address space, as a<br />

part of writing them out to disk. Since 128 KB are allocated per castout engine, and you<br />

can have up to 600 castout engines, the total can be up to 77 MB of storage.<br />

– CASTOUT BUFFERS = 0.00 MB (data sharing is not used)<br />

Variable pools<br />

The TOTAL VARIABLE STORAGE contains storage used by threads or agents as working<br />

storage, RID pool, RDS OP pool, Pipe manager subpool (working storage pools used by<br />

parallel tasks), local dynamic statement cache control blocks, thread copies of cached SQL<br />

statements (each thread’s Local Dynamic Statement Cache) and storage <strong>for</strong> various trace<br />

tables. Agent storage is further itemized into storage <strong>for</strong> “system agents” (such as prefetch<br />

engines, deferred write engines, castout engines, GBP write engines, P Lock exit engines)<br />

and “non-system agents”, which includes the number of all active allied threads and active<br />

DBAT threads.<br />

► TOTAL AGENT LOCAL STORAGE = 109.16 MB combines both TOTAL AGENT SYSTEM<br />

STORAGE and TOTAL AGENT NON-SYSTEM STORAGE.<br />

► TOTAL AGENT SYSTEM STORAGE = 3.54 MB. This is the total storage consumed in the<br />

variable pools by the various system agents (<strong>for</strong> example, prefetch engines, deferred write<br />

engines, and castout engines).<br />

► TOTAL AGENT NON-SYSTEM STORAGE = 105.63 MB. This is the total storage<br />

consumed in the variable pools by all the active threads. The normal range <strong>for</strong> <strong>DB2</strong> V8 is<br />

200 KB to 10 MB per thread. Simple threads like CICS transactions can be as low as 200<br />

KB while SAP threads can be as much as 10 MB per thread.<br />

► RID POOL = 0.57 MB. This is the total storage consumed in the variable pools <strong>for</strong> the RID<br />

pool. The RID pool is used <strong>for</strong> list prefetch, multiple index access processing, and hybrid<br />

joins. The maximum size is specified by the DSNZPARM parameter MAXRBLK.<br />

► The Local Dynamic Statement Cache size is indirectly determined by the DSNZPARM<br />

parameter MAXKEEPD when KEEPDYNAMIC(YES) is used. The storage used in the<br />

virtual pools is shown by the following indicators:<br />

160 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


– LOCAL DYNAMIC STMT CACHE CTL BLKS = 0.99 MB<br />

– THREAD COPIES OF CACHED SQL STMTS = 22.77 MB<br />

<strong>DB2</strong> V7 does not further break down the storage used <strong>for</strong> THREAD COPIES OF CACHED<br />

SQL STMTS. So, the values are recorded as N/A.<br />

► RDS OP POOL = 1.15 MB. For <strong>DB2</strong> V7 there is a single RDS OP pool <strong>for</strong> all threads<br />

which is used <strong>for</strong> sort, prepares and other similar functions.<br />

► BUFFER & DATA MANAGER TRACE = 16.95 MB<br />

Stack Storage and Fixed Pools<br />

The TOTAL FIXED STORAGE is typically used <strong>for</strong> <strong>DB2</strong> code and does not tend to vary a<br />

great deal, while the TOTAL GETMAINED STACK STORAGE is typically used <strong>for</strong> program<br />

stack usage, <strong>for</strong> example, save areas. It does vary as your workload varies.<br />

DBM1 and MVS Storage below 2 GB<br />

Figure 4-7 presents an overview of the MVS storage map. You may like to refer to this<br />

illustration as we continue to explain more items in the DBM1 Storage Statistics extract in<br />

Example 4-1.<br />

Figure 4-7 MVS storage overview<br />

MVS Storage Overview<br />

MVS 64-bit (16 Exabyte) Virtual Address Space<br />

64-Bit private storage<br />

Extended Region<br />

Nucleus, ECSA, ESQA, etc.<br />

Nucleus, CSA, SQA, etc.<br />

‘Below the line’<br />

64 Bit End of Virtual<br />

31 Bit ‘Bar’<br />

31 bit High Private<br />

31 bit low private<br />

24 Bit ‘line’<br />

24 bit high private<br />

24 bit low private<br />

The 31-bit EXTENDED LOW PRIVATE is the amount of used storage just above the 16 MB<br />

line. It is generally used by unauthorized programs. <strong>DB2</strong> code is loaded here, as well as data<br />

set control blocks. This storage grows from the bottom up in the extended region. The 31-bit<br />

EXTENDED HIGH PRIVATE is the amount of storage above the 16 MB line generally used by<br />

authorized programs. This storage grows top down in the extended region. All GETMAINed<br />

<strong>DB2</strong> storage is obtained in this way. MVS has a rule that high private cannot grow into low<br />

private. The REGION parameter in the JCL controls how high the low private storage can<br />

grow (0 MB indicate indefinitely). For example, the REGION parameter can be used to save a<br />

few MB of extended private storage by <strong>for</strong>cing some low private growth into 24-bit low private.<br />

Extended low private is often controlled with the system-wide MVS IEFUSI exit which can<br />

treat differently different address spaces.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 161


The EXTENDED REGION SIZE (MAX) is the size of the region available to <strong>DB2</strong> after MVS<br />

has allocated all common ECSA, ELPA, and ENUC type storage. It is commonly thought that<br />

<strong>DB2</strong> has 2 GB available, but this is generally more in the range of 1000 MB - 1600 MB. Most<br />

of the storage <strong>DB2</strong> allocates below the bar is here, in MVS subpool 229 or 230 key 7.<br />

The general recommendation <strong>for</strong> monitoring and tuning <strong>DB2</strong> storage is to have approximately<br />

200 MB free <strong>for</strong> fluctuations in workload. This recommendation is also true <strong>for</strong> <strong>DB2</strong> V8. 200<br />

MB is a good conservative number, but you may think of reducing this if your <strong>DB2</strong> subsystem<br />

is small.<br />

The EXTENDED CSA SIZE is the common storage area across all address spaces <strong>for</strong> a<br />

given LPAR. A large ECSA allocation would be .5 to .8 GB, while a typical allocation would be<br />

.3 to .5 GB.<br />

MVS is very likely to report a different number in EXTENDED REGION SIZE (MAX) by as<br />

much as 100 MB higher (the difference is in MVS overhead that <strong>DB2</strong> cannot track.)<br />

When <strong>DB2</strong> thinks it is running low on extended virtual storage, <strong>DB2</strong> begins a process called<br />

“system contraction”, which attempts to freemain any available segments of storage in fixed<br />

and variable pools back to MVS. (This process can be CPU-intensive and cause latch<br />

contention). If the storage <strong>DB2</strong> has reserved based on the number of threads that are allowed<br />

in the system, plus the storage <strong>DB2</strong> has reserved <strong>for</strong> open and close of data sets based on<br />

DSMAX, plus the storage <strong>DB2</strong> has reserved <strong>for</strong> must complete operations (such as ABORT<br />

and COMMIT), is less than <strong>DB2</strong>’s opinion of what storage is available, then contraction<br />

occurs.<br />

There<strong>for</strong>e, it is important to correctly estimate CTHREAD, MAXDBAT and DSMAX, and not<br />

be overly specific in estimating them.<br />

Storage estimates <strong>for</strong> threads<br />

The following <strong>for</strong>mulas apply to storage between the 16 MB line and the 2 GB bar.<br />

The current <strong>for</strong>mula <strong>for</strong> the Thread Footprint (TF) is as follows:<br />

( TOTAL VARIABLE STORAGE - TOTAL AGENT SYSTEM STORAGE / TOTAL NUMBER OF ACTIVE USER<br />

THREADS<br />

(153.39 - 3.54) / 500 = 0.2997<br />

This value is also reported in the report as AVERAGE THREAD FOOTPRINT as 0.30 MB.<br />

The fixed amounts of storage within the DBM1 address space do not vary a great deal as<br />

workload increases. They can be considered as a fixed overhead, <strong>for</strong> example, buffer pools,<br />

EDM pool, buffer pool control blocks and compression dictionaries. The total fixed storage<br />

overhead (F) can be estimated as:<br />

or<br />

TOTAL GETMAINED STORAGE + TOTAL GETMAINED STACK STORAGE + TOTAL FIXED STORAGE + 31 BIT<br />

EXTENDED LOW PRIVATE<br />

599.18 + 26.77 + 0.30 + 24.64 = 650.89 MB<br />

The value V <strong>for</strong> upper limit variable areas is defined as:<br />

V = R - C - F<br />

where:<br />

► R is the theoretical maximum region size<br />

162 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


= MVS EXTENDED REGION SIZE (MAX) - MVS 31 BIT EXTENDED LOW PRIVATE<br />

or<br />

1628.00 - 24.64 = 1603.36 MB<br />

► C is the basic cushion constant of 200 MB.<br />

► F is the value <strong>for</strong> fixed areas<br />

or<br />

= TOTAL GETMAINED STORAGE + TOTAL GETMAINED STACK STORAGE + TOTAL FIXED STORAGE<br />

599.18 + 26.77 + 0.30 = 626.25 MB<br />

The maximum theoretical number of threads can there<strong>for</strong>e be estimated as:<br />

V/TF<br />

For our example, the theoretical maximum number of threads can be estimated as:<br />

(1603.36 - 200 - 626,25) / 0.3 = 777.11 / 0.30 = 2590.37.<br />

This is also reported in the report as MAX NUMBER OF P<strong>OS</strong>SIBLE THREADS as 2593.01.<br />

The difference between 2590 and 2593 can be explained because the above calculation is<br />

based on the rounded MB values of the report, while Per<strong>for</strong>mance Expert uses the exact byte<br />

values of IFCID 225.<br />

Be warned that this is a maximum theoretical limit and should only be used as a guide or<br />

rough estimate. It does not provide <strong>for</strong> things such as growth in buffer pools and more<br />

compression dictionaries that may be required to support the extra workload.<br />

The stack storage size is directly proportional to the number of threads, not FIXED. Even<br />

Getmained ones are really not fixed. Threads would typically be much bigger in an<br />

environment which has many more threads. If a measurement run has 100 threads and the<br />

maximum is calculated much higher <strong>for</strong> the projection, such as 1000, the result in the<br />

maximum number of threads allowed tends to be much higher than really possible.<br />

So, what has changed in <strong>DB2</strong> V8?<br />

Example 4-2 shows the same extract from a <strong>DB2</strong> PE V8.1 Statistics Long Trace, but this time<br />

it shows the DBM1 STORAGE STATISTICS section <strong>for</strong> a <strong>DB2</strong> V8 subsystem. Once again, the<br />

report was produced with the fix <strong>for</strong> APAR PQ91101 applied to <strong>DB2</strong> and the fix <strong>for</strong> APAR<br />

PQ94872 applied to <strong>DB2</strong> PE.<br />

Example 4-2 DBM1 Storage Statistics <strong>for</strong> a <strong>DB2</strong> <strong>Version</strong> 8 subsystem<br />

DBM1 AND MVS STORAGE BELOW 2 GB QUANTITY DBM1 AND MVS STORAGE BELOW 2 GB CONTINUED QUANTITY<br />

-------------------------------------------- ------------------ -------------------------------------------- ------------------<br />

TOTAL DBM1 STORAGE BELOW 2 GB (MB) 539.30 24 BIT LOW PRIVATE (MB) 0.21<br />

TOTAL GETMAINED STORAGE (MB) 236.09 24 BIT HIGH PRIVATE (MB) 0.43<br />

VIRTUAL BUFFER POOLS (MB) N/A 31 BIT EXTENDED LOW PRIVATE (MB) 30.45<br />

VIRTUAL POOL CONTROL BLOCKS (MB) N/A 31 BIT EXTENDED HIGH PRIVATE (MB) 553.99<br />

EDM POOL (MB) 234.38 EXTENDED REGION SIZE (MAX) (MB) 1628.00<br />

COMPRESSION DICTIONARY (MB) N/A EXTENDED CSA SIZE (MB) 256.83<br />

CASTOUT BUFFERS (MB) N/A<br />

DATA SPACE LOOKASIDE BUFFER (MB) N/A AVERAGE THREAD FOOTPRINT (MB) 0.46<br />

HIPERPOOL CONTROL BLOCKS (MB) N/A MAX NUMBER OF P<strong>OS</strong>SIBLE THREADS 2377.81<br />

DATA SPACE BP CONTROL BLOCKS (MB) N/A<br />

TOTAL VARIABLE STORAGE (MB) 231.47<br />

TOTAL AGENT LOCAL STORAGE (MB) 195.72<br />

TOTAL AGENT SYSTEM STORAGE (MB) 2.32<br />

NUMBER OF PREFETCH ENGINES 6<br />

NUMBER OF DEFERRED WRITE ENGINES 10<br />

NUMBER OF CASTOUT ENGINES 0<br />

NUMBER OF GBP WRITE ENGINES 0<br />

NUMBER OF P-LOCK/NOTIFY EXIT ENGINES 0<br />

TOTAL AGENT NON-SYSTEM STORAGE (MB) 193.40<br />

TOTAL NUMBER OF ACTIVE USER THREADS 500<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 163


RDS OP POOL (MB) N/A<br />

RID POOL (MB) 0.35<br />

PIPE MANAGER SUB POOL (MB) 0.00<br />

LOCAL DYNAMIC STMT CACHE CNTL BLKS (MB) 3.93<br />

THREAD COPIES OF CACHED SQL STMTS (MB) 29.10<br />

IN USE STORAGE (MB) 16.13<br />

STATEMENTS COUNT 2096<br />

HWM FOR ALLOCATED STATEMENTS (MB) 16.13<br />

STATEMENT COUNT AT HWM 2096<br />

DATE AT HWM 10/23/04<br />

TIME AT HWM 00:59:04.55<br />

BUFFER & DATA MANAGER TRACE TBL (MB) N/A<br />

TOTAL FIXED STORAGE (MB) 0.46<br />

TOTAL GETMAINED STACK STORAGE (MB) 71.28<br />

STORAGE CUSHION (MB) 123.79<br />

DBM1 STORAGE ABOVE 2 GB QUANTITY REAL AND AUXILIARY STORAGE QUANTITY<br />

-------------------------------------------- ------------------ -------------------------------------------- ------------------<br />

FIXED STORAGE (MB) 0.02 REAL STORAGE IN USE (MB) 694.48<br />

GETMAINED STORAGE (MB) 2221.78 AUXILIARY STORAGE IN USE (MB) 0.00<br />

COMPRESSION DICTIONARY (MB) 0.00<br />

CACHED DYNAMIC SQL STATEMENTS (MAX) (MB) 1024.00<br />

DBD CACHE (MAX) (MB) 1024.00<br />

VARIABLE STORAGE (MB) 173.78<br />

VIRTUAL BUFFER POOLS (MB) 468.75<br />

VIRTUAL POOL CONTROL BLOCKS (MB) 0.14<br />

CASTOUT BUFFERS (MB) 0.00<br />

STAR JOIN MEMORY POOL (MB) 0.00<br />

The TOTAL GETMAINED STORAGE has decreased from 599.18 MB in V7 to 236.09 MB in<br />

V8. This is a direct result of buffer pools, buffer pool control blocks, data space lookaside<br />

buffers, castout buffers and compression dictionaries all moving above the bar. We can see<br />

them now recorded in a new area of the report, titled DBM1 STORAGE ABOVE 2 GB. You will<br />

also notice these fields are now marked as N/A under the TOTAL GETMAINED STORAGE<br />

section of the report.<br />

For V8, RID Pool is only referred to RID map, since RID lists have been moved above the bar.<br />

Note that the RDS OP pool is recorded as N/A <strong>for</strong> V8. In <strong>DB2</strong> V7, there was a single RDS OP<br />

pool reported, which all threads use. However in <strong>DB2</strong> V8, the RDS OP pool storage <strong>for</strong> each<br />

thread is allocated from the thread's variable length storage pool. We can see the TOTAL<br />

GETMAINED STACK STORAGE jump from 26 MB to 71 MB. This increase is primarily due to<br />

larger thread-related structures in V8, since they must be larger to accommodate long names.<br />

So, in V8 we see a considerable decrease in TOTAL GETMAINED STORAGE and a<br />

considerable increase in TOTAL GETMAINED STACK STORAGE.<br />

<strong>DB2</strong> V8 also breaks down the THREAD COPIES OF CACHED SQL STMTS storage into<br />

more meaningful statistics. Cached SQL statements <strong>for</strong> dynamic SQL can cause quite a lot of<br />

virtual storage to be consumed.<br />

► THREAD COPIES OF CACHED SQL STMTS reports the virtual storage consumed by<br />

copies of currently executable SQL statements and the executable statements that are<br />

kept beyond commit when KEEPDYNAMIC YES is used.<br />

► IN USE STORAGE reports the amount of virtual storage that is actually allocated to locally<br />

cached dynamic SQL statements, discounting storage not used in the storage allocation<br />

segment.<br />

► STATEMENTS COUNT is the number of locally cached dynamic SQL statements that are<br />

actually using the storage.<br />

The following <strong>for</strong>mula can give you some insight into the degree of fragmentation of storage<br />

which is used to locally cache dynamic SQL statements.<br />

(THREAD COPIES OF CACHED SQL STMTS - IN USE STORAGE) / STATEMENTS COUNT<br />

164 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


In addition, <strong>DB2</strong> shows a high water mark <strong>for</strong> storage consumed by locally cached dynamic<br />

SQL statements. The high water marks are measured since the last time the IFCID 225<br />

record was externalized.<br />

Now, with <strong>DB2</strong> V8, if you look only at virtual storage, you get a partial view. <strong>DB2</strong> V8 now can<br />

allocate very large amounts of virtual storage above the bar which may not be backed by real<br />

memory. This can be very bad <strong>for</strong> per<strong>for</strong>mance. The DBM1 STORAGE ABOVE 2 GB counters<br />

do not provide the whole picture.<br />

So the IFCID 225 record and DBM1 Storage Statistics section of the <strong>DB2</strong> PE Statistics<br />

reports also report on DBM1 Storage usage above the 2 GB bar, as well as provide an<br />

indication of real storage frames used by the DBM1 address space. These statistics are<br />

displayed <strong>for</strong> both <strong>DB2</strong> V7 and <strong>DB2</strong> V8.<br />

REAL STORAGE IN USE reports on the amount of real storage in megabytes, used by the<br />

DBM1 address space. Ideally, this should be significantly less than the amount of virtual<br />

storage consumed. (TOTAL DBM1 STORAGE BELOW 2 GB + all the counters in TOTAL<br />

DBM1 STORAGE ABOVE 2 GB.)<br />

AUXILIARY STORAGE IN USE is the amount of storage in megabytes the DBM1 address<br />

space has allocated in auxiliary storage (disks). This should be zero or very close to it.<br />

The following points are indicators <strong>DB2</strong> may be suffering from storage-related problems, such<br />

as a <strong>DB2</strong> code error (storage leak) or a really stressed system due to a lack of real storage:<br />

► 100% real frames consumed. Note that although a physical machine may have 30 GB of<br />

real storage, a given LPAR may only have a fraction of this real storage dedicated.<br />

► An excessive number of auxiliary paging slots in use.<br />

► A general per<strong>for</strong>mance degradation.<br />

Dumps are also another useful tool to monitor storage usage within the DBM1 address space.<br />

However, they only capture a point-in-time picture of storage usage and do not capture peaks.<br />

An IPCS <strong>for</strong>matted dump using the parameter<br />

VERBEXIT DSNWDMP ‘ALL SM=3’<br />

produces the useful summary of DBM1 storage usage shown in Example 4-3.<br />

Example 4-3 DBM1 storage usage summary<br />

===Stack(SKB) total: 55196K 53M<br />

===Fixed subpool total: 384K 0M<br />

GMB total: 151755K 148M<br />

ADMF AGL system total: 3076K 3M<br />

ADMF AGL non system total: 93360K 91M<br />

ADMF AGL 31 total: 72064K 70M<br />

ADMF AGL VL total: 24372K 23M<br />

ADMF local total: 96436K 94M<br />

SQL cache total: 16080K 15M<br />

Variable subpool total: 119736K 116M<br />

Var+Fix+GMB+Stack total: 327071K 319M<br />

===Above the bar<br />

Fixed subpool total: 2604K 2M<br />

ADMF AGL 64 total: 76072K 74M<br />

ADMF AGL 64 system total: 0K 0M<br />

Variable subpool total: 154616K 150M<br />

VSAS blocks: 2201M<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 165


As you can now appreciate, it is important you monitor your system paging rates. Even a<br />

small rate of paging to DASD is usually a warning sign of real storage issues. You can use the<br />

online RMF Monitor III Option 3.7 Storage Frames (STORF) report to gauge paging rated by<br />

address space. This online report monitors the number of REAL+AUX frames used by the<br />

<strong>DB2</strong> DBM1 address space in real time. Figure 4-8 shows a sample RMF Monitor III STORF<br />

report, showing the relative paging rates to the right of the report. Per<strong>for</strong>mance problems<br />

arise from overcommitment of real storage and auxiliary paging slots. The general<br />

recommendation is close to zero (or


PM<strong>DB2</strong> is the <strong>DB2</strong> per<strong>for</strong>mance consulting offering from <strong>IBM</strong> Global Services, taking <strong>DB2</strong><br />

instrumentation (such as Accounting Trace and the <strong>DB2</strong> Catalog) and supplementing it with<br />

per<strong>for</strong>mance data from z/<strong>OS</strong> sources, such as RMF.<br />

Figure 4-9 shows how the IFCID 225 picture varies by time of day. The chart is based on <strong>DB2</strong><br />

Statistics Trace Class 6 (IFCID 225) data. This customer has undertaken most of the sensible<br />

tuning actions to reduce virtual storage, such as moving all the buffer pools and the Prepared<br />

Statement Cache to data space. What remains is mostly thread-related, with some areas<br />

relevant to data sharing and Dataspace Lookaside buffers.<br />

Megabytes<br />

1200<br />

1000<br />

800<br />

600<br />

400<br />

200<br />

0<br />

Virtual Pools<br />

EDM Pool Free<br />

EDM Pool Used<br />

Figure 4-9 DBM1 storage by time<br />

A V7 Customer<br />

DBM1 Very Detailed Virtual Storage Usage<br />

Figure 4-10 shows how the thread-related storage in DBM1 varies by time of day.<br />

YRDDPPPPUUU<br />

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23<br />

GBP Castout<br />

Comp Dicts<br />

Lookaside Bufs<br />

Agt Local Non-Sys<br />

Ag Local Sys<br />

Pipe Mgr<br />

RDS Ops<br />

RID Pool<br />

PSC CB<br />

PSC Statmts<br />

Trace Tables<br />

Other Var.<br />

Fixed<br />

Stack<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 167


Megabytes<br />

A V7 Customer<br />

DBM1 Thread Memory - Headline Numbers<br />

550<br />

500<br />

450<br />

400<br />

350<br />

300<br />

250<br />

0 2 4 6 8<br />

1 3 5 7<br />

Figure 4-10 Thread-related storage by time<br />

This chart shows that the number of threads varies largely between day and night, with more<br />

and lighter threads during the day. Storage per thread stays more or less constant at 1 MB<br />

each during normal working hours.<br />

Figure 4-11 shows in detail how the memory per thread varies by time of day. Overnight there<br />

are fewer threads but they each have a larger footprint. In general each daytime thread (when<br />

the demand <strong>for</strong> virtual storage is at its highest) has a footprint of about 1 MB.<br />

It is useful to calculate the storage per thread so that thread limits such as CTHREAD can be<br />

properly set. This picture can be further refined using IFCID 217 thread-level data.<br />

168 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

10 12 14 16 18 20 22<br />

9 11 13 15 17 19 21 23<br />

Hour<br />

Thread Storage Threads<br />

700<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

Threads


Megabytes<br />

15<br />

10<br />

5<br />

0<br />

A V7 Customer<br />

DBM1 Thread Memory - Per-Thread Profile<br />

Figure 4-11 Storage per thread by time<br />

4.5 Buffer pool long term page fixing<br />

0<br />

1<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

8<br />

<strong>DB2</strong> V8 introduces a new ALTER BUFFERPOOL parameter called PGFIX. This parameter<br />

allows you to fix the buffer pages once in memory and keep them fixed in real storage. This<br />

avoids the processing time that <strong>DB2</strong> needs to fix and free pages each time there is an I/O.<br />

When virtual storage is used <strong>for</strong> an I/O operation, the channels require that the storage be<br />

“page-fixed” during the time span of the I/O, because the channels must use real storage<br />

addresses <strong>for</strong> I/O and there<strong>for</strong>e the page cannot be allowed to move between the time when<br />

the channel program is built and when the I/O is complete.<br />

The operating system normally “fixes” the storage temporarily during the life of the I/O<br />

operation. This extra CPU cost can be as high as 10%.<br />

9<br />

10 12 14 16 18 20 22<br />

11<br />

Hour<br />

13 15 17 19 21 23<br />

Stor Per Thread Agt Local Per Thread<br />

<strong>DB2</strong> V8 utilizes a z/<strong>OS</strong> service requested by the long-term page fixing option to eliminate this<br />

expense. The PGFIX(YES/NO) option may be specified <strong>for</strong> individual buffer pools, and it can<br />

be altered dynamically. PGFIX(NO) is the default.<br />

To use this option, you can use the PGFIX(YES) option on the ALTER BUFFERPOOL<br />

command. The ALTER takes effect the next time the buffer pool is allocated. <strong>DB2</strong> message<br />

DSNB543I indicates the buffer pool is now in a pending state, as a result of changing the<br />

PGFIX parameter to YES. <strong>DB2</strong> message DSNB406I shows the current PGFIX setting <strong>for</strong> the<br />

buffer pool. Be reminded however, that the page fixing is at the buffer pool level.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 169


4.5.1 Per<strong>for</strong>mance<br />

The most buffer pools <strong>DB2</strong> allows you to page fix are up to 80% of the real storage of the<br />

z/<strong>OS</strong> LPAR. This limitation is in place to protect other workloads on the LPAR from being<br />

“squeezed” by <strong>DB2</strong>.<br />

We tested the impact of long term page fixing all of our buffer pools, both in a data sharing<br />

and non-data sharing environment. We used the same IRWW workload <strong>for</strong> both tests. We<br />

also used an I/O intensive workload, by limiting the storage used by the buffer pools to 400<br />

MB.<br />

Let us first look at non-data sharing. Table 4-9 compares PGFIX(NO) to PGFIX(YES) in a<br />

non-data sharing test.<br />

Table 4-9 Long term page fix - non-data sharing<br />

PGFIX NO YES Delta<br />

(YES/NO)<br />

DBM1<br />

(msec / commit)<br />

Total <strong>DB2</strong> CPU time<br />

(msec / commit)<br />

ITR<br />

(msec / commit)<br />

Page fixing <strong>DB2</strong> buffer pools has a significant positive impact on per<strong>for</strong>mance. We can see<br />

almost a 30% reduction in CPU consumed by the DBM1 address space per transaction. This<br />

is because prefetch requests and deferred write I/O requests stand to benefit the most from<br />

page fixing. <strong>DB2</strong> no longer has to page fix a large number pages be<strong>for</strong>e initiating each<br />

prefetch and write I/O request. <strong>DB2</strong> also does not have to release the pages after the I/O has<br />

completed. <strong>DB2</strong> only incurs the cost of page fixing when the buffer pool page is first<br />

referenced in an I/O request. Subsequent I/Os do not incur this cost again.<br />

We can also see a 8% reduction in total CPU time used by <strong>DB2</strong> and a gain of 6% in<br />

transaction throughput.<br />

Now let us have a look at data sharing. Table 4-10 compares PGFIX(NO) to PGFIX(YES) in a<br />

data sharing environment with two members. Notice that a long term page fix applies to GBP<br />

read and write. It does not apply to castout work area, since cast work area is not a part of<br />

buffer pool and a long term page fix is a buffer pool option.<br />

Table 4-10 Long term page fix - data sharing<br />

170 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

0.455 0.322 -29%<br />

2.436 2.238 -8%<br />

587.22 601.42 +6%<br />

PGFIX NO YES Delta<br />

(YES / NO)<br />

DBM1<br />

(msec / commit)<br />

Total <strong>DB2</strong> CPU time<br />

(msec / commit)<br />

Group ITR<br />

(commit / sec)<br />

0.560 0.563 0.456 0.457 -19%<br />

3.318 3.306 3.109 3.357 -2%<br />

890.70 897.00 +1%


4.5.2 Conclusion<br />

The per<strong>for</strong>mance improvements in a data sharing environment are not as pronounced, with<br />

only a 19% improvement in DBM1 CPU used, compared with 29% in non-data sharing. The<br />

main reason is a higher fixed cost with data sharing.<br />

Remember that our measurements were taken using an I/O intensive workload. You might not<br />

see as dramatic an improvement in CPU savings as we did. However our test cases show a<br />

CPU time reduction of up to 8% <strong>for</strong> I/O intensive transaction workload, and as much as 10%<br />

<strong>for</strong> more I/O intensive batch types of workloads.<br />

Although these are still significant CPU savings to be obtained in a data sharing environment,<br />

the CPU savings are generally not as great as in a non-data sharing environment. This is<br />

primarily due to a higher fixed cost overhead with data sharing.<br />

4.5.3 Recommendations<br />

4.6 IRLM V2.2<br />

Long term page fixing <strong>DB2</strong> buffer pools is effectively a trade-off between real storage and<br />

per<strong>for</strong>mance. It is available in V8 CM and beyond.<br />

Long term page fixing of <strong>DB2</strong> buffer pools typically results in a CPU savings in the range of<br />

0% to as great as 10%. The per<strong>for</strong>mance benefits are inversely proportional to the buffer pool<br />

hit ratio. The higher the hit ratio, the lower the potential per<strong>for</strong>mance benefit. We there<strong>for</strong>e<br />

recommend you first page fix your smaller buffer pools with a low hit ratio and frequent I/O,<br />

(<strong>for</strong> example sequential workloads). You then should consider page fixing your other buffer<br />

pools, buffer pool by buffer pool, to minimize potential impact on other concurrently running<br />

workloads. However, you need to be a little more cautious when considering larger buffer<br />

pools. Page fixing buffer pools may drive system paging rates higher, thereby impacting<br />

overall system per<strong>for</strong>mance.<br />

We cannot overstress the importance of having sufficient real storage to back up your buffer<br />

pool 100%. Having 99.9% is not good enough, as the LRU buffer steal algorithm introduces<br />

paging if there is insufficient real storage to back up your buffer pool completely. There<strong>for</strong>e,<br />

make sure your buffer pool is fully backed by real storage be<strong>for</strong>e you start using PGFIX(YES).<br />

<strong>DB2</strong> V8 is shipped with IRLM V2.2, which is now a 64-bit application. With IRLM V2.2, <strong>DB2</strong><br />

locks always reside above the 2 GB bar.<br />

IRLM V2.2 ships with both a 31-bit version of the modules, as well as a 64-bit capable<br />

version. If the operating system is able to handle 64-bit, the 64-bit version is loaded. However,<br />

the interface to IRLM V2.2 is still 31-bit. The 64-bit version requires the z/Architecture as well<br />

as z/<strong>OS</strong> 1.3. <strong>DB2</strong> V8 requires IRLM V2.2 in 64-bit mode.<br />

IRLM V2.2 is also shipped with IMS V9. However, note that at the time of writing this book,<br />

IRLM V2.2 does not support earlier versions of <strong>DB2</strong> or IMS.<br />

IRLM V2.2 supports a far greater number of locks than V2.1. IRLM V2.1 which is shipped with<br />

<strong>DB2</strong> V7, is a 31-bit application and is there<strong>for</strong>e restricted to the 2 GB address space limit. The<br />

maximum number of concurrently held locks in IRLM V2.1 is approximately 8 million locks, (2<br />

GB/approximately 260 bytes per lock). IRLM V2.2 which is shipped with <strong>DB2</strong> V8, is a 64-bit<br />

application and there<strong>for</strong>e not restricted to the 2 GB address space limit. As the average lock<br />

size in <strong>DB2</strong> V8 is increased to approximately 540 bytes, only 3.7 million locks can be<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 171


4.6.1 Per<strong>for</strong>mance<br />

maintained in a 2 GB IRLM address space. However V2.2 is not restricted to this 2 GB limit.<br />

The new maximum number of locks is theoretically 100 million, around 16 times more than<br />

V2.1, assuming that ECSA does not become a bottleneck sooner.<br />

Locks no longer reside in ECSA. There<strong>for</strong>e, the PC=NO parameter in the IRLM procedure is<br />

no longer honored. PC=YES is always used. This also means that the MAXCSA parameter<br />

no longer applies, as it was related to ECSA storage usage. You can still specify both PC=NO<br />

and MAXCSA= <strong>for</strong> compatibility reasons, but they are ignored by IRLM. Note that the IRLM<br />

parameters are positional, so you cannot remove them altogether.<br />

The fact that IRLM locks no longer reside in ECSA (when you were using PC=NO in V7) also<br />

means that a considerable amount of ECSA storage, which used to contain the IRLM locks, is<br />

now freed up in V8, and can be used by other subsystems (such as WebSphere) and other<br />

applications.<br />

IRLM V2.2 has two additional parameters that can be specified in the IRLM startup<br />

procedure. These parameters are:<br />

► MLMT - Max storage <strong>for</strong> locks:<br />

This specifies, in MB or GB, the maximum amount of private storage available above the 2<br />

GB bar that the IRLM <strong>for</strong> this <strong>DB2</strong> uses <strong>for</strong> its lock control block structures. The IRLM<br />

address space procedure uses this parameter (which you specify on the IRLM startup<br />

proc EXEC statement) to set the z/<strong>OS</strong> MEMLIMIT value <strong>for</strong> the address space. Ensure<br />

that you set this value high enough so that IRLM does not reach the limit. Note that the<br />

value you choose should take into account the amount of space <strong>for</strong> possible retained locks<br />

as well. IRLM only gets storage as it needs it, so you can choose a large value without any<br />

immediate effects. IRLM monitors the amount of private storage used <strong>for</strong> locks. If the<br />

specified limit is reached, new lock requests are rejected unless they are “must complete”.<br />

APAR PQ87611 allows you to dynamically change the amount of storage used <strong>for</strong> locks<br />

above the bar by using the z/<strong>OS</strong> command:<br />

MODIFY irlmproc,SET,PVT=nnnn<br />

where nnnn can be specified in nnnnM (MB) or nnnnG (GB). A SET,PVT= command<br />

causes the MEMLIMIT to be updated; never lower than the default 2 G, and never lower<br />

than the amount of storage in use, plus the 10% of reserved space.<br />

► PGPROT - Page protect:<br />

Acceptable values are NO and YES (default). The page protect IRLM startup procedure<br />

parameter specifies whether or not IRLM loads its modules that reside in common storage<br />

into page-protected storage. YES indicates that modules located in common storage are<br />

to be loaded into page-protected storage to prevent programs from overlaying the<br />

instructions. We recommend YES because it requires no additional overhead after the<br />

modules are loaded, and the protection can prevent code-overlay failures. NO indicates<br />

that common storage modules are to be loaded into CSA or ECSA without first<br />

page-protecting that memory.<br />

Some large <strong>DB2</strong> environments, <strong>for</strong> example, large SAP R/3® environments, should consider<br />

a MEMLIMIT of 4 GB <strong>for</strong> their IRLM if the real storage is available.<br />

Table 4-11 shows the CPU time consumed by IRLM while running the IRWW workload in a<br />

two member data sharing environment. Each value in the IRLM CPU row of the table<br />

represents a <strong>DB2</strong> member. All tests were run using PC=YES, including the V7 test. Note that<br />

IRLM request CPU time is not included in IRLM CPU. Instead it is included in accounting<br />

class 2.<br />

172 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Table 4-11 IRLM CPU - V2.1 vs. V2.2<br />

<strong>DB2</strong> V7 V8 V8 Delta <strong>for</strong> P1 %<br />

(V8-V7) / V7<br />

IRLM (PC=YES) 2.1 2.2 2.2<br />

Lock Protocol n/a 1 2<br />

Group ITR<br />

(commits/sec)<br />

IRLM CPU<br />

msec/commit<br />

We can make some judgements here to assess the impact on CPU the IRLM V2.2 has over<br />

the IRLM V2.1. Keep in mind that IRLM V2.2 is now a 64-bit application and the locks are<br />

managed above the 2 GB bar. These figures show only a modest 1.8% increase in CPU with<br />

this workload. The IRLM is generally not a significant user of CPU compared with other <strong>DB2</strong><br />

address spaces such as the DBM1 address space. So, this slight increase is not really<br />

considered significant.<br />

Significant savings in the IRLM CPU can be seen in the third test, when Locking Protocol<br />

Level 2 was used, compared with the first test under <strong>DB2</strong> V8. This CPU savings can directly<br />

be attributed to the Locking Protocol Level 2, which significantly reduces XES contention<br />

resolution. Refer to Chapter 8, “Data sharing enhancements” on page 319 <strong>for</strong> a more detailed<br />

discussion of the new locking protocol implemented in <strong>DB2</strong> V8.<br />

PC=NO vs. PC=YES<br />

In the past, the IRLM PC parameter, an option on the IRLM startup procedure JCL,<br />

determined where the IRLM maintains its locks. PC=NO instructs the IRLM to maintain its<br />

lock structures in ECSA, which is governed by the MAXCSA parameter. PC=YES instructs<br />

the IRLM to maintain its lock structures in the IRLM private region. PC=YES causes<br />

cross-memory linkage PC constructs to be used between <strong>DB2</strong> and the IRLM, rather than the<br />

cheaper branch constructs.<br />

In the past, PC=NO was the general recommendation <strong>for</strong> per<strong>for</strong>mance, and PC=NO is the<br />

default in <strong>DB2</strong> V7. However, Cross Memory calls have become less expensive and recent<br />

enhancements in lock avoidance techniques have greatly reduced the advantage of using<br />

PC=NO.<br />

Prior to <strong>DB2</strong> V8, PC=YES has been the recommendation <strong>for</strong> high availability. PC=YES helps<br />

you avoid “out of storage” problems related to exhausting ECSA. It also allows you to<br />

decrease the ECSA size, and thus increase the private region size. It also allows you to raise<br />

lock escalation limits and max locks per user limit in DSNZPARM, reducing the frequency of<br />

lock escalations.<br />

For some workloads, going from PC=NO to PC=YES may increase the CPU cost of each<br />

IRLM request by as much as 10%. This is because the number of instructions required to<br />

process a lock increase by about 5%, and cross memory instructions are generally more<br />

expensive to process than normal instructions. However if 2% of the overall CPU time is<br />

consumed by the IRLM, the overall impact of having PC=YES is 0.2%, (10% * 2%), which is<br />

probably not noticeable. So, even in <strong>DB2</strong> V7, the availability benefits of moving from PC=NO<br />

to PC=YES outweigh the very slight per<strong>for</strong>mance benefits of PC=NO in most cases.<br />

In any event, the PC and MAXCSA parameters are no longer used in the IRLM V2.2.<br />

However, you must still specify them in the IRLM JCL <strong>for</strong> compatibility reasons.<br />

Delta <strong>for</strong> P2 %<br />

(V8-V7) / V7<br />

823.56 804.69 933.41 -2.29% +13.34%<br />

0.330 0.371 0.335 0.379 0.014 0.014 +1.85% -96.01%<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 173


4.6.2 Conclusion<br />

We can conclude that there is some increase in IRLM CPU caused by moving from V2.1 to<br />

V2.2, generally compensated by the Locking Protocol Level 2 enhancements in a data<br />

sharing environment. In a non-data sharing environment, the increase in CPU usage by the<br />

IRLM address space is included in the accounting.<br />

By maintaining its lock structures in private storage above the 2 GB bar, the IRLM is able to<br />

manage many more locks than be<strong>for</strong>e. This enables <strong>DB2</strong> to manage locks at a smaller<br />

granularity, resulting in less lock contention.<br />

4.6.3 Recommendations<br />

4.7 Unicode<br />

Since IRLM V2.2 can manage many more locks than IRLM V2.1, you may consider<br />

increasing NUMLKTS (maximum number of locks per table space be<strong>for</strong>e lock escalation<br />

occurs) or NUMLKUS (number of lock per user be<strong>for</strong>e a resource unavailable occurs).<br />

Because the lock structures no longer reside in ECSA, considerable ECSA storage is now<br />

freed up in V8 and can be used by other subsystems (such as WebSphere) and other<br />

applications. This is good news <strong>for</strong> MVS Systems Programmers.<br />

Since the space required to maintain each individual lock has increased, some large <strong>DB2</strong><br />

installations, such as large SAP R/3 environments, should consider a MEMLIMIT of 4 GB <strong>for</strong><br />

their IRLM. However, the same rules apply <strong>for</strong> the storage areas that move above the 2 GB<br />

bar in DBM1. Make sure there is enough real storage to back this up.<br />

V8 vastly improves <strong>DB2</strong>’s support <strong>for</strong> Unicode and lifts many of the limitations that existed in<br />

V7. For example, when <strong>DB2</strong> has been migrated to V8 new-function mode, the <strong>DB2</strong> catalog is<br />

converted to Unicode. In addition all the SQL statements must be parsed as Unicode, even in<br />

CM, while <strong>DB2</strong> V8 NFM allows you to combine different encoding schemes, CCSIDs, in the<br />

same SQL statement.<br />

As a result, <strong>DB2</strong> now must per<strong>for</strong>m much more code page conversion than ever be<strong>for</strong>e, which<br />

potentially impacts per<strong>for</strong>mance. In this section we discuss the major improvements that have<br />

occurred in converting to and from Unicode. These improvements come from three major<br />

sources; improvements in the zSeries processor hardware, improvements in the z/<strong>OS</strong><br />

Conversion Services, and optimization inside <strong>DB2</strong> V8.<br />

For details, see the new manual <strong>DB2</strong> <strong>UDB</strong> Internationalization Guide available from:<br />

http://www.ibm.com/software/data/db2/zos/v8books.html<br />

Another source of in<strong>for</strong>mation is the article titled “Unicode Per<strong>for</strong>mance in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>”, by<br />

Jeffrey Berger and Kyoko Amano, published in The IDUG Solutions Journal Volume 11<br />

Number 2.<br />

<strong>DB2</strong> V8 supports three types of encoding schemes: EBCDIC, which is used by mainframe<br />

environments, ASCII, which is used by Unix and Windows environments, and more recently,<br />

Unicode.<br />

We identify the character set <strong>for</strong> a language by a numeric CCSID. A CCSID encoding scheme<br />

consists of a single byte character set (SBCS), and optionally a double byte character set<br />

(DBCS) along with a mixed character set. Over time each geography developed their own<br />

EBCDIC or ASCII encoding schemes. The variety of CCSIDs made it very difficult <strong>for</strong><br />

174 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


multinational companies to combine data from different sources. Unicode was developed to<br />

solve the problem. By storing data in a single Unicode CCSID, text data from different<br />

languages in different countries can be easily stored and managed.<br />

<strong>DB2</strong> V5 introduced the ability to create ASCII databases, table spaces and tables via the<br />

CCSID ASCII clause. This gave you the choice to store your data in either EBCDIC or ASCII,<br />

and <strong>DB2</strong> would convert data between these encoding schemes where appropriate. <strong>DB2</strong> V7<br />

built upon that support, introducing support <strong>for</strong> Unicode objects. However, where EBCDIC<br />

and ASCII conversions are done within <strong>DB2</strong>, <strong>DB2</strong> V7 always relied on <strong>OS</strong>/390 Conversion<br />

Services to handle Unicode conversion. The per<strong>for</strong>mance of Unicode conversion in <strong>DB2</strong> V7,<br />

with older levels of the operating system and zSeries hardware, was less than optimal. <strong>DB2</strong><br />

V8 enhances support <strong>for</strong> Unicode, and at the same time takes advantage of the faster<br />

conversion provided by the current versions of z/<strong>OS</strong> services and zSeries processors.<br />

When storing data into and retrieving data, <strong>DB2</strong> converts the data from one CCSID to another<br />

CCSID where necessary. Obviously, it is preferable that no conversion be carried out,<br />

because conversion impacts per<strong>for</strong>mance. However, <strong>IBM</strong> has done considerable work to<br />

improve conversion per<strong>for</strong>mance on zSeries. In this section, we discuss the recent<br />

enhancements <strong>IBM</strong> have made to conversion and how they impact per<strong>for</strong>mance.<br />

When does CCSID conversion occur?<br />

CCSID conversion occurs whenever there is a mismatch between the CCSID of a source and<br />

target string, such as between a host variable and its associated column. This conversion<br />

support in <strong>DB2</strong> has existed since <strong>DB2</strong> began to support client/server connections in V2.3<br />

between different EBCDIC CCSIDs. <strong>DB2</strong> V5 began to support ASCII tables and ASCII host<br />

variables, so CCSID conversion was expanded to include conversion between EBCDIC and<br />

ASCII.<br />

To per<strong>for</strong>m these conversions (not involving Unicode), <strong>DB2</strong> uses a translate table which is<br />

stored in SYS<strong>IBM</strong>.SYSSTRINGS. We refer to this type of CCSID conversion as<br />

SYSSTRINGS conversions.<br />

The specific EBCDIC and ASCII CCSIDs used to store data by a <strong>DB2</strong> system must be<br />

specified in the DSNHDECP data only module, and they should not be changed. Starting in<br />

V8, they cannot be changed. Within a single <strong>DB2</strong> system, all EBCDIC tables have the same<br />

EBCDIC CCSIDs and all ASCII tables have the same ASCII CCSIDs. In addition, numeric<br />

columns and date/time columns are stored as binary fields, but they may involve CCSID<br />

conversion when loading or unloading such fields using the EXTERNAL attribute. However,<br />

the utilities always apply the EXTERNAL attribute to date/time fields.<br />

<strong>DB2</strong> V7 introduced the ability <strong>for</strong> user tables to be defined as Unicode by specifying “CCSID<br />

UNICODE” on the database, table space or table definition. Within a Unicode table, CHAR<br />

and VARCHAR columns are stored in UTF-8 <strong>for</strong>mat. GRAPHIC and VARGRAHIC columns<br />

are stored in a Unicode table as UTF-16. Any CCSID conversion involving Unicode is called<br />

Unicode conversion and is necessary whenever there is a mismatch between the CCSID of a<br />

source and target string. <strong>DB2</strong> V7 uses the z/<strong>OS</strong> Conversion Services exclusively <strong>for</strong> all<br />

Unicode conversions, which can affect the CPU time substantially.<br />

In V7 the <strong>DB2</strong> Catalog remains in EBCDIC and all SQL statement parsing is still done in<br />

EBCDIC. There<strong>for</strong>e, <strong>for</strong> applications such as the Universal Java Driver that provide an SQL<br />

statement in Unicode, <strong>DB2</strong> must convert the statement to EBCDIC. Similarly, any incoming<br />

metadata, such as package names and authorization ids, may also require conversion by<br />

<strong>DB2</strong>.<br />

One of the limitations of V7 is that you cannot join two tables that use different CCSIDs.<br />

Another limitation is per<strong>for</strong>mance. V7 completely relies on the z/<strong>OS</strong> Unicode conversion<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 175


service <strong>for</strong> Unicode conversions, and prior to z/<strong>OS</strong> 1.4 the conversion service was very slow,<br />

especially on pre-z900 processors.<br />

<strong>DB2</strong> V8 brings many more enhancements in <strong>DB2</strong>’s support <strong>for</strong> Unicode as well as removing<br />

many of the limitations that were in V7. When you first start V8, you are running in CM in<br />

which the <strong>DB2</strong> catalog is still in EBCDIC and you are prevented from exploiting new function.<br />

However, all SQL parsing in V8 is done in Unicode, (that is, UTF-8), even in compatibility<br />

mode. SQL statements that are input in EBCDIC, ASCII or UTF-16 must be converted to<br />

UTF-8. In compatibility mode, all the <strong>DB2</strong> object names the SQL statements reference must<br />

again be converted to EBCDIC in order to compare them to <strong>DB2</strong> catalog data. In addition, all<br />

Utility control statements must be converted to Unicode be<strong>for</strong>e they are parsed.<br />

When you migrate the catalog to new-function mode (NFM), the <strong>DB2</strong> catalog is converted to<br />

Unicode, and fallback to V7 is no longer possible. New <strong>DB2</strong> V8 subsystems always run in<br />

NFM. SQL statement conversion is unaffected by the switch to NFM, but all the <strong>DB2</strong> object<br />

names the SQL statements reference no longer need to be converted since the <strong>DB2</strong> object<br />

names are already in the CCSID of the <strong>DB2</strong> catalog. <strong>DB2</strong> V8 also introduces the capability to<br />

join two tables of different CCSIDs. Needless to say, Unicode conversion is necessary to do<br />

this and the extra CPU time is likely to be substantial.<br />

Now, let us turn to understanding how or when CCSID conversion impacts per<strong>for</strong>mance.<br />

Recall that ‘class 1 CPU time’ and ‘class 2 CPU time’ are CPU metrics reported in the <strong>DB2</strong><br />

accounting statistics. Class 1 CPU time represents the CPU time consumed between the<br />

creation of a <strong>DB2</strong> thread and the termination of the thread. Class 2 CPU time is a subset of<br />

the class 1 CPU time and it represents the CPU time from when the application passed the<br />

SQL statements to the local <strong>DB2</strong> system until return. Sometimes, class 2 time is referred to<br />

simply as ‘in <strong>DB2</strong> time’. In general, conversions per<strong>for</strong>med by remote clients affect neither<br />

class 1 nor class 2 CPU time, but conversions per<strong>for</strong>med by local Java clients only affect<br />

class 1 CPU time. The DBM1 address space handles all CCSID conversions on behalf of old<br />

mainframe legacy applications, including <strong>DB2</strong> utilities. The DIST address space handles all<br />

metadata conversions <strong>for</strong> remote applications, if any conversion is needed by <strong>DB2</strong>.<br />

Let us have a look in more detail. Figure 4-12 shows the flow of data <strong>for</strong> a typical legacy<br />

application accessing a Unicode table, where the application is bound using the default<br />

application encoding scheme, which is EBCDIC.<br />

Local Application <strong>DB2</strong> DBM1<br />

INSERT<br />

HV1 37<br />

HV2 37<br />

SELECT<br />

HV1 37<br />

HV2 37<br />

Figure 4-12 CCSID conversion - Local application<br />

176 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Class 2 CPU Time<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG


Since the database is defined as Unicode, any data being sent or received by the application<br />

must be converted by the DBM1 address space, such as in this example in which the<br />

EBCDIC code page is 37. Had the database remained as EBCDIC 37, no CCSID conversion<br />

would be necessary. The table contains one CHAR column called COLC (CCSID 1208) and<br />

one GRAPHIC column called COLG (CCSID 1200). When the application inserts host<br />

variables HV1 and HV2 into the table, the strings are converted by the DBM1 address space<br />

to Unicode. The CPU time <strong>for</strong> these conversions is added to the class 2 CPU time.<br />

Figure 4-13 shows a <strong>DB2</strong> Connect example using the same Unicode table.<br />

C-program<br />

INSERT<br />

HV1 943<br />

HV2 943<br />

SELECT<br />

HV1 943<br />

HV2 943<br />

<strong>DB2</strong> Connect V8<br />

Conversion<br />

Routines<br />

DisableUnicode=1<br />

AIX z/<strong>OS</strong><br />

DRDA<br />

Common<br />

Layer<br />

Figure 4-13 CCSID conversion - Remote application - 1<br />

The application is running remotely on an AIX client and uses the Japanese ASCII CCSID<br />

943. The application uses <strong>DB2</strong> Connect V8 to communicate to the z/<strong>OS</strong> server.<br />

The DRDA protocol and <strong>DB2</strong> maintain a convention strategy in which the "receiver makes<br />

right". Hence, DRDA lets <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> do the conversions when sending data to the server,<br />

and <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> lets the client do the conversions <strong>for</strong> data being retrieved by the client.<br />

Note however that the conversion is actually per<strong>for</strong>med by the DBM1 address space, not the<br />

DIST address space. The DBM1 address space actually does the inbound CCSID conversion<br />

<strong>for</strong> character strings, while the DIST address space per<strong>for</strong>ms the conversion <strong>for</strong> numeric data.<br />

<strong>IBM</strong> first introduced a JDBC Driver in V5 and V6, which is now known as the Legacy JDBC<br />

Driver. On workstations, the Legacy JDBC Driver interfaced with <strong>DB2</strong> Connect. When<br />

sending data to a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V6 server, the Legacy JDBC Driver converted the data from<br />

UTF-16 to EBCDIC, because V6 was unable to handle incoming data in Unicode. (All <strong>IBM</strong><br />

implementations of Java use CCSID 1200 corresponding to UTF-16.)<br />

However, <strong>DB2</strong> V7 supports Unicode databases. If <strong>DB2</strong> Connect were to convert UTF-16 data<br />

to EBCDIC and then the server converted it to back to Unicode, there would be a potential <strong>for</strong><br />

data loss since not all Unicode characters exist in the intermediate EBCDIC character set. To<br />

DDF<br />

<strong>DB2</strong> Connect V8<br />

DBM1<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 177


overcome this, when <strong>DB2</strong> Connect is interfacing with <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V7, <strong>DB2</strong> Connect sends<br />

the data in Unicode (by default). If you still require the data to be sent in ASCII instead of<br />

Unicode, then you may set the DISABLEUNICODE=1 parameter. DISABLEUNICODE is<br />

specified in the db2cli.ini file. Older z/<strong>OS</strong> systems were slow to convert Unicode so it was<br />

desirable to specify DISABLEUNICODE=1. Otherwise, installations migrating from <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> V6 to V7 would experience an increase in class 2 CPU time. Only <strong>for</strong> Java Applications<br />

was it preferable not to specify DISABLEUNICODE=1.<br />

This per<strong>for</strong>mance problem goes away with z/<strong>OS</strong> 1.4, because now Unicode conversion is<br />

faster than ASCII conversion. Furthermore, if the database is actually stored in Unicode,<br />

setting DISABLEUNICODE adds Unicode conversions to the class 2 CPU time.<br />

In the above example, the <strong>DB2</strong> Connect properties file indicates DISABLEUNICODE=1,<br />

which prevents <strong>DB2</strong> Connect from sending data as Unicode. The data sent on INSERTS is in<br />

ASCII. The DBM1 address space converts the ASCII data to Unicode.<br />

For the SELECT statement, <strong>DB2</strong> Connect on the client converts the data from Unicode back<br />

to ASCII. Only those conversions done by the DIST address space are counted as class 2<br />

CPU time.<br />

Class 2 CPU time is unaffected by the conversions done by the client, but if the client is<br />

running locally on z/<strong>OS</strong>, the CPU time <strong>for</strong> conversions done by the client may be part of class<br />

1 CPU time. Conversions done by a non-z/<strong>OS</strong> client do not use zSeries mainframe resources.<br />

Figure 4-14 shows the effect of not disabling Unicode in <strong>DB2</strong> Connect, which is the default.<br />

C-program<br />

INSERT<br />

HV1 943<br />

HV2 943<br />

SELECT<br />

HV1 943<br />

HV2 943<br />

<strong>DB2</strong> Connect V8<br />

Conversion<br />

Routines<br />

Figure 4-14 CCSID conversion - Remote application - 2<br />

In this case, <strong>DB2</strong> Connect sends all data as 1208, no matter what the type of column is. The<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> conversions <strong>for</strong> CHAR columns disappear. However, there is a double<br />

conversion <strong>for</strong> GRAPHIC columns, but only the second conversion is done by <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>.<br />

178 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

DisableUnicode=0<br />

AIX z/<strong>OS</strong><br />

DRDA<br />

Common<br />

Layer<br />

DDF<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

DBM1<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG


Still, this second conversion is a conversion from 1208 to 1200 which is somewhat less<br />

expensive than an ASCII conversion (provided that z/<strong>OS</strong> 1.4 is installed).<br />

In summary, <strong>for</strong> CHAR columns, not setting DISABLEUNICODE shifts the Unicode<br />

conversion during the Insert from the z/<strong>OS</strong> server to the workstation client, helping to reduce<br />

class 2 CPU time. For GRAPHIC columns, DISABLEUNICODE has a more subtle effect,<br />

because in one case the class 2 CPU time contains a conversion from UTF-8 to UTF-16, and<br />

in the other case the class 2 CPU time contains a conversion from ASCII to UTF-16 (a Java<br />

application would send all data as UTF-8.)<br />

The same DISABLEUNICODE parameter affects both host variables and SQL statements.<br />

Since <strong>DB2</strong> V8 does SQL parsing in Unicode, it becomes more important to avoid setting<br />

DISABLEUNICODE. This is especially true if any of the code points used in the SQL<br />

statement is greater than 127. If all code points are less than 128, CCSID 1208 is equivalent<br />

to ASCII, and no conversion of the SQL statement actually occurs. See “<strong>DB2</strong> V8 major and<br />

minor conversion” on page 185 <strong>for</strong> more details.<br />

Now let us have a look at Unicode conversion <strong>for</strong> Java clients.<br />

Along with <strong>DB2</strong> V8, <strong>IBM</strong> introduced the Universal Driver <strong>for</strong> JDBC and SQLJ to replace the<br />

old Legacy JDBC Driver. The Universal Driver does not use <strong>DB2</strong> Connect. The Universal<br />

Driver supports both a Type 2 and Type 4 Driver. While the Type 2 Driver is optimally used by<br />

local Java applications running on z/<strong>OS</strong>, the Type 4 Driver can be used by workstation clients<br />

as well as z/<strong>OS</strong> clients. The Type 4 Driver uses DRDA protocols.<br />

Since the Universal Driver does not use <strong>DB2</strong> Connect, the DISABLEUNICODE parameter is<br />

not applicable. Instead the Universal Type 4 Driver supports a new “UseServerEncoding” data<br />

source property. Unlike the Legacy Driver, the Universal Driver always sends the SQL<br />

statement in UTF-8 no matter how the property is set. The Universal Java Driver is shipped<br />

with <strong>DB2</strong> V8 and V7 with PQ8841. Although it can connect to <strong>DB2</strong> V7, it is optimized to work<br />

with <strong>DB2</strong> V8. Since the Universal Driver always sends the SQL statement in UTF-8, a V7<br />

server has to convert the SQL statement to EBCDIC, and the result is higher class 2 CPU<br />

time.<br />

Because there is no disadvantage to using UseServerEncoding=1, our discussion assumes<br />

that UseServerEncoding=1 is always used.<br />

Figure 4-15 shows the Universal Java Type 2 Driver locally connecting to <strong>DB2</strong> V8, first using<br />

an EBCDIC database and then using a Unicode database.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 179


INSERT<br />

HV1 1200<br />

HV2 1200<br />

SELECT<br />

HV1 1200<br />

HV2 1200<br />

Java program<br />

INSERT<br />

HV1 1200<br />

HV2 1200<br />

SELECT<br />

HV1 1200<br />

HV2 1200<br />

JVM<br />

JVM<br />

Java Universal T2 Driver<br />

z/<strong>OS</strong><br />

z/<strong>OS</strong><br />

RRSAF<br />

RRSAF<br />

Figure 4-15 CCSID conversion - Local z/<strong>OS</strong> Universal Java Type 2 Driver<br />

Here we see that <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> never has to do any CCSID conversion because the Universal<br />

Java Driver always converts the data to the correct CCSID. Hence, Unicode conversion does<br />

not affect class 2 CPU time, but since the JVM (Java Virtual Machine) is running on z/<strong>OS</strong>,<br />

conversions per<strong>for</strong>med under the JVM affect the class 1 CPU time. Note also that when a<br />

string is being inserted into or fetched from a Graphic Unicode column, there are no<br />

conversions under the JVM.<br />

As an aside, the Unicode conversions per<strong>for</strong>med by the JVM in z/<strong>OS</strong> do not use the z/<strong>OS</strong><br />

Conversion Services because it is difficult <strong>for</strong> the JVM to use z/<strong>OS</strong> system services. Prior to<br />

JDK Release 1.4.1 the conversions within Java did not use any of the special zSeries<br />

translation instructions, and the conversions were inefficient <strong>for</strong> long strings. Starting with<br />

JDK 1.4.1, some of these conversions are beginning to use the zSeries translate instructions,<br />

namely the TROO, TROT and TRTO instructions, which are useful <strong>for</strong> converting among byte<br />

codes and UTF-16 and SBCS EBCDIC characters. So, we can see improved per<strong>for</strong>mance <strong>for</strong><br />

the Universal Type 2 Driver, with particularly significant improvements with large SBCS<br />

strings on the z990 processor. Such an improvement does not occur when a string contains<br />

DBCS characters.<br />

180 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

Java program Java Universal T2 Driver<br />

DBM1<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

DBM1<br />

1390 COLC<br />

16684 COLG<br />

1390 COLC<br />

16684 COLG<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG


Figure 4-16 shows the Universal Java Type 4 Driver remotely connecting to <strong>DB2</strong> V8 from AIX.<br />

It also assumes that Deferred Prepare is used. By default, the Type 4 Driver defers the<br />

Prepare in order to minimize network overhead.<br />

Java<br />

Application<br />

1st INSERT<br />

HV1 1200<br />

HV2 1200<br />

AIX z/<strong>OS</strong><br />

JVM<br />

Subsequent INSERT<br />

HV1 1200<br />

HV2 1200<br />

SELECT<br />

HV1 1200<br />

HV2 1200<br />

Java<br />

Application<br />

1st INSERT<br />

HV1 1200<br />

HV2 1200<br />

JVM<br />

Subsequent INSERT<br />

HV1 1200<br />

HV2 1200<br />

SELECT<br />

HV1 1200<br />

HV2 1200<br />

1208 COLC<br />

1208 COLG<br />

1390 COLC<br />

16684 COLG<br />

1208<br />

1208<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

DDF DBM1<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

DDF DBM1<br />

1390 COLC<br />

16684 COLG<br />

1390 COLC<br />

16684 COLG<br />

1390 COLC<br />

16684 COLG<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG<br />

1208 COLC<br />

1200 COLG<br />

Figure 4-16 CCSID conversion - Remote Prepare using Java Universal Type 4 Driver<br />

The Type 4 Driver offers a new interface called ParameterMetaData to retrieve the table<br />

characteristics, but of course it requires network communication. After ParameterMetaData is<br />

invoked, the Universal Driver uses CCSIDs in the same way the Type 2 Driver does. If<br />

ParameterMetaData is not used, and Deferred Prepare is used, the first Insert sends the data<br />

in UTF-8; if the table is stored in EBCDIC, <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> needs to convert the data to<br />

EBCDIC. Subsequent inserts do not require any conversions by <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>. Again, as with<br />

the Type 2 Driver, subsequent INSERTs and SELECTs do not require any conversions <strong>for</strong><br />

Graphic columns.<br />

Note that <strong>for</strong> static SQL processing where the SQL statements are prebound by SQLJ,<br />

Deferred Prepares are not applicable because the CCSIDs are already known by SQLJ at<br />

execution time.<br />

SQL statements and <strong>DB2</strong> object names such as Authorization Ids and package names may<br />

also require CCSID conversion. Figure 4-17 shows an AIX application using <strong>DB2</strong> Connect<br />

and DRDA to remotely prepare an SQL statement remotely, connecting to <strong>DB2</strong> V7 and <strong>DB2</strong><br />

V8.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 181


AIX<br />

C-program Conversion<br />

Routines<br />

Prepare 943<br />

Prepare 943<br />

<strong>DB2</strong> <strong>UDB</strong> client code V8<br />

DRDA<br />

Common<br />

Layer<br />

Figure 4-17 CCSID conversion - Remote Prepare of SQL statement<br />

The application on AIX typically inputs the SQL statement in ASCII, whether the target <strong>DB2</strong><br />

server is V7 or V8. So, <strong>DB2</strong> V7 converts the statement from ASCII to EBCDIC, and <strong>DB2</strong> V8<br />

converts the SQL statement from ASCII to UTF-8.<br />

Finally, Figure 4-18 shows a local prepare of an SQL statement using the Universal Java Type<br />

2 Driver to connect to <strong>DB2</strong> V7 and <strong>DB2</strong> V8.<br />

Java<br />

Application<br />

Prepare 1200<br />

Prepare 1200<br />

USS<br />

Universal<br />

Java T2 Driver<br />

1208<br />

1208<br />

Figure 4-18 CCSID conversion - Local Prepare using Universal Java Type 2 Driver<br />

The Legacy JDBC Driver converts the SQL statement from UTF-16 to UTF-8, which requires<br />

no conversion on <strong>DB2</strong> V8.<br />

182 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 on z/<strong>OS</strong><br />

DDF DBM1<br />

<strong>DB2</strong> V8 on z/<strong>OS</strong><br />

DDF DBM1<br />

z/<strong>OS</strong><br />

RRS <strong>DB2</strong> V7<br />

DBM1<br />

<strong>DB2</strong> V8<br />

DBM1<br />

1390<br />

1208<br />

1390<br />

1208<br />

<strong>DB2</strong> V7<br />

Catalog<br />

<strong>DB2</strong> V8<br />

Catalog<br />

<strong>DB2</strong> V7<br />

Catalog<br />

<strong>DB2</strong> V8<br />

Catalog


Choosing between UTF-8 and UTF-16<br />

When choosing to store data in a Unicode database, you have a choice of using either UTF-8<br />

(CHAR) or UTF-16 (GRAPHIC). This choice includes both per<strong>for</strong>mance and non-per<strong>for</strong>mance<br />

considerations. For example, since the collating sequences of UTF-8 and UTF-16 are<br />

different, you can choose column types based on the desired collating sequence rather than<br />

per<strong>for</strong>mance.<br />

However, the major per<strong>for</strong>mance consideration when comparing UTF-8 to UTF-16 is the<br />

amount of space used. The reason space is important is not just the cost of the space itself,<br />

but also the impact that the space has on I/O bound utilities and queries, including the time to<br />

recover, which affects data availability. Buffer pool hit ratios are also affected by space.<br />

A UTF-8 character is variable length and can be 1 to 4 bytes in length, of which the first 128<br />

code points match 7-bit ASCII. A UTF-8 character is used by <strong>DB2</strong> to store CHAR or<br />

VARCHAR columns. This is opposed to a character in UTF-16, which is 2 or 4 bytes. <strong>DB2</strong><br />

uses UTF-16 to store GRAPHIC or VARGRAPHIC columns. The first 128 code points match<br />

UTF-8 and ASCII, while the rest have a different collating sequence.<br />

Consider the type of data you will be storing in <strong>DB2</strong> and choose UTF-8 (CHAR) or UTF-16<br />

(GRAPHIC), depending on the characteristics of the data. UTF-8 is efficient <strong>for</strong> text that is<br />

predominantly English alphanumeric while UTF-16 is more efficient <strong>for</strong> Asian characters.<br />

To reduce the space required by Unicode tables, you can use <strong>DB2</strong> compression. With no <strong>DB2</strong><br />

compression and <strong>for</strong> alphanumeric characters, UTF-8 has the same space characteristics as<br />

EBCDIC, however UTF-16 doubles the storage requirements. Compressed alphanumeric<br />

UTF-16 strings use more storage than compressed alphanumeric UTF-8 strings, but the ratio<br />

is generally much less than 2 to 1. Tests have shown this ratio can be less than 1.5 to 1.<br />

Whether compression is used or not, the overall effect of Unicode on space usage depends<br />

on the amount of text data versus non-text data.<br />

CPU time can also be another consideration. Compression itself costs a lot of CPU time,<br />

although its I/O benefits can outweigh the CPU costs. In some applications Unicode<br />

conversion can be avoided, but if conversion must be done, it is best done by a remote client<br />

in order to distribute the CPU overhead. If conversion must be done on the zSeries machine,<br />

then you should consider what the dominant application CCSID will be. Generally, the choice<br />

which tends to minimize space usage also tends to minimize CPU usage.<br />

Choosing between fixed and variable length strings may also be another consideration.<br />

Remember, the length of a UTF-8 string is unpredictable, unless the application limits the<br />

characters to the common set and fixed length strings.<br />

Consider, <strong>for</strong> example, a column that was defined as CHAR(1) in EBCDIC. If you try to insert<br />

a multibyte UTF-8 character into CHAR(1), you get a -302 SQL error, because the data does<br />

not fit into one byte. If you change the column definition to GRAPHIC(1), you need two bytes.<br />

If you change the column definition to VARCHAR, you need 3 bytes in order to account <strong>for</strong> the<br />

two-byte length field. Knowing that a field is restricted to alphanumeric characteristics allows<br />

you to continue using CHAR(1).<br />

It is especially good to avoid using variable length fields in indexes, especially nonpadded<br />

indexes, since key comparisons of variable length fields are more expensive. On the other<br />

hand, you should try to avoid padding costs with fixed length fields if Unicode conversion is<br />

being done.<br />

Remember, there is nothing stopping you from storing both UTF-8 and UTF-16 encoded data<br />

in the same table.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 183


4.7.1 Per<strong>for</strong>mance<br />

The improvements in Unicode conversion come from three sources. Each of these sources<br />

affects different facets of conversion per<strong>for</strong>mance, such as the type of characters, and the<br />

length of the character strings. The three sources are:<br />

► <strong>DB2</strong> V8 major and minor conversion: Improves the per<strong>for</strong>mance of all types of<br />

conversions, but the improvements are most dramatic with English alphanumeric<br />

characters because <strong>DB2</strong> does not need to invoke the Unicode conversion service.<br />

► z/<strong>OS</strong> Conversion Services: z/<strong>OS</strong> Release 1.4 implemented an enhancement to z/<strong>OS</strong><br />

Conversion Services with PTF UA05789: This enhancement, referred to as HC3, helps the<br />

per<strong>for</strong>mance of both <strong>DB2</strong> V7 and V8.<br />

► zSeries processor hardware: The z900 model introduced some new Unicode hardware<br />

instructions that are simulated by the z/<strong>OS</strong> Conversion Services on older processors. In<br />

addition, the speed of a z990 engine is approximately 50% faster than the z900 Turbo, but<br />

when it comes to the Unicode conversion of large strings, the z990 hardware is twice as<br />

fast (in this book, we refer to the z900 Turbo model).<br />

Figure 4-19 summarizes the step by step improvements in conversion per<strong>for</strong>mance each of<br />

these sources have made. For these measurements, a single table scan of 1 million rows was<br />

used, using a single cursor with no predicates. The table was defined using 20 VARCHAR<br />

columns per row with 10 characters per column.<br />

Figure 4-19 Conversion per<strong>for</strong>mance overview<br />

Note that the table is not drawn exactly to scale, but it does show the progressive gains in<br />

per<strong>for</strong>mance that have been achieved.<br />

The first bar represents <strong>DB2</strong> V7 running on z/<strong>OS</strong> 1.3 with EBCDIC host variables and<br />

database. CCSID conversion is done here by <strong>DB2</strong> using SYS<strong>IBM</strong>.SYSSTRINGS. Next, we<br />

see a huge jump in CPU time as we ask <strong>DB2</strong> V7 to use Unicode. <strong>DB2</strong> V7 now must invoke<br />

z/<strong>OS</strong> Conversion Services <strong>for</strong> any conversion to and from Unicode. By simply moving to z/<strong>OS</strong><br />

1.4, we see quite a improvement in CPU. This is primarily due to advancements in the z/<strong>OS</strong><br />

Conversion Services that dramatically improved the per<strong>for</strong>mance of (but not exclusively)<br />

conversions between UTF-8 and EBCDIC (or ASCII). The next step in per<strong>for</strong>mance is<br />

184 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Conversion per<strong>for</strong>mance overview<br />

<strong>DB2</strong>V7, z900, z/<strong>OS</strong> 1.3, EBCDIC hostvars and database<br />

+UTF-8<br />

database<br />

+ z/<strong>OS</strong> 1.4<br />

+ z990<br />

+ <strong>DB2</strong>V8 (assuming non-alphanumeric)<br />

+ minor conversion (assuming alphanumeric)<br />

+ convert the hostvars to UTF-8 (eliminate conversion)<br />

CPU time


achieved by simply moving to <strong>DB2</strong> V8. <strong>DB2</strong> V8 is able to exploit the 64-bit interface into the<br />

z/<strong>OS</strong> Conversion Services, which is much more efficient than the 31-bit interface used by<br />

<strong>DB2</strong> V7. Next, we see a greater improvement by moving to the z990 hardware, which brings a<br />

number of specific hardware instructions to support Unicode conversion. Next, we introduce<br />

optimization in <strong>DB2</strong> V8 called “minor conversion”. FInally, we introduce further optimization in<br />

<strong>DB2</strong> V8 which in certain cases allows the system to avoid conversion.<br />

Now, we explore each of these enhancements in more detail.<br />

<strong>DB2</strong> V8 major and minor conversion<br />

Conversion of SQL statements and <strong>DB2</strong> object names generally involves English<br />

alphanumeric characters. For many years the <strong>DB2</strong> Catalog has been EBCIDC. To improve<br />

the per<strong>for</strong>mance of <strong>DB2</strong>, V8 developed a faster way to convert such characters without calling<br />

the z/<strong>OS</strong> Conversion Services. This faster way is called minor conversion. There<strong>for</strong>e, the term<br />

major conversion refers to those conversions per<strong>for</strong>med by the z/<strong>OS</strong> Conversion Services.<br />

<strong>DB2</strong> maintains a translate table associated with the EBCDIC SBCS/mixed CCSIDs that are<br />

specified during <strong>DB2</strong> installation. The same translate table is also used <strong>for</strong> access to the <strong>DB2</strong><br />

catalog and user data. Minor conversion is supported <strong>for</strong> all European EBCDIC character<br />

sets, and some Asian EBCDIC character sets. Minor conversion does not apply to UTF-16<br />

(GRAPHIC) or ASCII; it may only apply to conversions between EBCDIC and UTF-8.<br />

How does minor conversion work?<br />

The zSeries instruction set has always included a TR instruction that translates one byte <strong>for</strong><br />

one byte, based on a 256-byte translation table. A TRT instruction has also existed which<br />

could be used to test a string <strong>for</strong> certain one byte characters. As long as a single byte English<br />

alphanumeric character can be represented in UTF-8 by a single byte, a TR instruction can<br />

be used to convert the byte to UTF-8. <strong>DB2</strong> V8 has built-in translate tables <strong>for</strong> most common<br />

single byte CCSIDs and if the TRT instruction is "successful", <strong>DB2</strong> can translate the string<br />

using a TR instruction. The presence of shift-in/shift-out characters in a mixed string always<br />

causes the TRT instruction to fail. If the TRT fails, then <strong>DB2</strong> must invoke the z/<strong>OS</strong> Conversion<br />

Services.<br />

The per<strong>for</strong>mance of minor conversion is much better than the per<strong>for</strong>mance of major<br />

conversion because minor conversion avoids calling the z/<strong>OS</strong> Conversion Services. Hence,<br />

minor conversion is one of the significant advantages of <strong>DB2</strong> V8 compared to <strong>DB2</strong> V7, and<br />

represents an advantage of UTF-8 over UTF-16. Even when <strong>DB2</strong> V8 needs to use major<br />

conversion, V8 is still much faster than V7, which we will see later.<br />

Note that <strong>DB2</strong> V8 still uses the catalog table SYS<strong>IBM</strong>.SYSSTRINGS <strong>for</strong> conversions that do<br />

not involve Unicode.<br />

<strong>DB2</strong> V8 introduces a further optimization <strong>for</strong> ASCII conversion to UTF-8. <strong>DB2</strong> uses the TRT<br />

instruction to ensure all characters are less than 128, and because the first 128 code points<br />

are the same between ASCII and UTF-8, no conversion is necessary. <strong>DB2</strong> can skip<br />

conversion altogether.<br />

Studies using strings containing only English characters show that minor conversion in V8<br />

can be more than four times faster than major conversion in V8. Compared to conversion in<br />

V7, minor conversion can be more than six times faster. Keep in mind that minor conversion is<br />

only successful <strong>for</strong> single byte characters.<br />

z/<strong>OS</strong> Conversion Services<br />

The z/<strong>OS</strong> Conversion Services contain both a 31-bit and a 64-bit service. <strong>DB2</strong> V7 uses the<br />

31-bit service, while <strong>DB2</strong> V8 most often uses the 64-bit service.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 185


In October 2003, a new enhancement was shipped to z/<strong>OS</strong> in PTF UA05789, known as HC3,<br />

that included very significant per<strong>for</strong>mance enhancements, especially (but not exclusively) <strong>for</strong><br />

conversions between UTF-8 and EBCDIC (or ASCII). The UTF-8 enhancement applies to<br />

both the 31-bit service and the 64-bit service. In order to take advantage of this per<strong>for</strong>mance<br />

enhancement, you must rebuild your conversion tables after this PTF has been applied. With<br />

this enhancement, Conversion Services under z/<strong>OS</strong> 1.4 can be as much as 3.75 times faster<br />

than under z/<strong>OS</strong> 1.3.<br />

In addition to the UTF-8 enhancement, the 64-bit service implemented some improved<br />

module linkage that gives <strong>DB2</strong> V8 an advantage over <strong>DB2</strong> V7. Studies have shown that <strong>DB2</strong><br />

V8 improves the per<strong>for</strong>mance of major conversion over <strong>DB2</strong> V7 and that this improvement is<br />

most evident with small strings. With a 10-byte string, V8 is 1.5 times faster. With a 200-byte<br />

string, V8 is only about 15% faster.<br />

zSeries processor hardware<br />

The z/<strong>OS</strong> Conversion Services take advantage of a number of new hardware instructions that<br />

are faster with the z990 and z890 processors. These instructions are:<br />

► CUTFU - Convert from UTF-8 to UTF-16<br />

► CUUTF - Convert from UTF-16 to UTF-8<br />

► TROO - Translate from One byte to another One byte (used to convert single byte codes)<br />

► TRTO - Translate from Two bytes to One byte (used to convert from UTF-16 to EBCDIC)<br />

► TROT - Translate from One byte to Two bytes (used to convert from EBCDIC to UTF-16)<br />

► TRTT - Translate Two bytes to Two bytes (used to convert between UTF-16 and double<br />

byte EBCDIC)<br />

z/<strong>OS</strong> understands the term Unicode to be UTF-16, while <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> uses Unicode UTF-8<br />

<strong>for</strong> the catalog and all CHAR columns within Unicode tables. So, all z/<strong>OS</strong> Conversion<br />

Services translations between SBCS EBCDIC and UTF-8 require two steps. Step 1 uses the<br />

TROT instruction to convert from EBCDIC to UTF-16, and step 2 uses the CUUTF instruction<br />

to convert from UTF-16 to UTF-8. Conversion in the opposite direction first uses CUTFU and<br />

then TRTO. In other words, UTF-16 is always used to transit between EBCDIC and UTF-8.<br />

Combining these two steps into one step was the key to HC3's improved per<strong>for</strong>mance, which<br />

was discussed earlier, but UTF-16 is still used as a transit point.<br />

Conversions involving DBCS make use of the TRTT instruction, and mixed strings involve<br />

some combination of all of these instructions. If the caller need only convert between UTF-8<br />

and UTF-16, only the CUUTF or CUTFU instruction is used, so the per<strong>for</strong>mance is faster than<br />

conversions between UTF-8 and EBCDIC or ASCII.<br />

Like many other instructions, the CPU time of these instructions increases in proportion to the<br />

string length. In a workload involving Unicode conversion, the CPU time effects of these<br />

instructions can be high, especially with large strings. The z990 and z890 processors have<br />

provided significant enhancements to the TROO, TROT, TRTO and TRTT instructions,<br />

making them as much as five times faster than the z900 and z800 processors. The larger the<br />

string is, the larger the per<strong>for</strong>mance benefit of the z990 and z890 processors.<br />

Studies have shown that the z990 reduces the conversion CPU time using V7 <strong>for</strong> 10 byte<br />

strings by 1.5 times. This is a typical z990 improvement that we have measured <strong>for</strong> most<br />

applications. This increases to a two times improvement <strong>for</strong> 200 byte strings, which is even<br />

better. Per<strong>for</strong>mance of other string lengths may be inter- or extrapolated from 10-byte and<br />

200-byte strings. We see similar improvements in <strong>DB2</strong> V8.<br />

186 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.7.2 Conclusion<br />

The enhancements we have seen in <strong>DB2</strong> V8, z/<strong>OS</strong> Conversion Services and the z990<br />

hardware dramatically improve Unicode conversion per<strong>for</strong>mance.<br />

Prior to the z/<strong>OS</strong> Conversion Services improvement (HC3), Unicode conversion to EBCDIC<br />

was always slower than ASCII conversion to EBCDIC, but this is not true with HC3. In V7<br />

Unicode conversion is about 20% faster than ASCII conversion. In addition, V8 major Unicode<br />

conversion is about 12% faster than ASCII conversion, but minor conversion is much faster<br />

still.<br />

The cost of conversion can affect the total CPU time of your application. As an example,<br />

consider a table space scan of 1 million rows with no predicates or indexes. On the z900 with<br />

V8, the table space scan used 18.6 CPU seconds when there was no conversion, and 63.3<br />

CPU seconds <strong>for</strong> major conversion. In other words, 67% of the time was spent doing<br />

conversion. For this study, each major conversion used 2.3 microseconds and was 25 times<br />

faster.<br />

4.7.3 Recommendations<br />

Although <strong>DB2</strong> V8 can run on z/<strong>OS</strong> 1.3, we recommend you migrate to at least z/<strong>OS</strong> 1.4, to<br />

take advantage of the enhancements that have been made to the z/<strong>OS</strong> Conversion Services.<br />

Notice that z/<strong>OS</strong> 1.3 was out of service as of March 31, 2005. In addition, migrating to current<br />

hardware brings per<strong>for</strong>mance improvements to the z/<strong>OS</strong> Conversion Services.<br />

When choosing to store data in a Unicode database, you have a choice of using either UTF-8<br />

(CHAR) or UTF-16 (GRAPHIC). This choice includes both per<strong>for</strong>mance and nonper<strong>for</strong>mance<br />

considerations. However, the major per<strong>for</strong>mance consideration when comparing UTF-8 to<br />

UTF-16 is the amount of space used. CPU time can also be another consideration. Obviously<br />

compression itself costs a lot of CPU time, although its I/O benefits may outweigh the CPU<br />

costs. Choosing between fixed and variable length strings can also be a consideration. The<br />

decision between UTF-8 and UTF-16 there<strong>for</strong>e has the potential to have a real impact on<br />

application per<strong>for</strong>mance.<br />

We recommend you closely consider the type of data you will be storing in <strong>DB2</strong> and choose<br />

UTF-8 (CHAR) or UTF-16 (GRAPHIC) depending on the characteristics of the data. UTF-8 is<br />

efficient <strong>for</strong> text that is predominantly English alphanumeric while UTF-16 is more efficient <strong>for</strong><br />

Asian characters.<br />

In addition, there are big advantages to limiting the data to single byte characters, so that<br />

minor conversion can succeed. However, we do not think you run the risk of compromising<br />

your application design in order to take advantage of <strong>DB2</strong> minor conversion techniques. In<br />

any event, using multi-byte characters does not impact per<strong>for</strong>mance if Unicode conversion is<br />

unnecessary.<br />

Some customers who use <strong>DB2</strong> Connect to connect to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> have been using<br />

DISABLEUNICODE=1 to tell <strong>DB2</strong> Connect to send the data to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> in ASCII rather<br />

than Unicode. In the past, converting from ASCII to EBCDIC was much less expensive than<br />

converting from Unicode to EBCDIC. However now in z/<strong>OS</strong> 1.4, Unicode conversion is faster<br />

than ASCII conversion. Furthermore if the database is stored in Unicode, setting<br />

DISABLEUNICODE adds Unicode conversion times to the class 2 CPU times. We there<strong>for</strong>e<br />

recommend you not to set the DISABLEUNICODE parameter when you are using <strong>DB2</strong><br />

Connect to connect to <strong>DB2</strong> V8.<br />

Since the Universal Driver does not need <strong>DB2</strong> Connect, the DISABLEUNICODE parameter is<br />

not generally applicable. Instead, the Universal Type 4 Driver supports a new<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 187


UseServerEncoding data source property. Since there is no disadvantage to using<br />

UseServerEncoding=1, we recommend you should always have this property set, especially if<br />

your <strong>DB2</strong> system is using MIXED=NO.<br />

4.8 Data encryption<br />

<strong>DB2</strong> V8 ships a number of built-in functions which allow you to encrypt and decrypt data. <strong>IBM</strong><br />

also offer an encryption tool called the <strong>IBM</strong> Data Encryption Tool <strong>for</strong> IMS and <strong>DB2</strong><br />

Databases, program number 5799-GWD, also mentioned in 10.8, “Data Encryption <strong>for</strong> IMS<br />

and <strong>DB2</strong> Databases” on page 369. The per<strong>for</strong>mance implications <strong>for</strong> encryption are roughly<br />

similar to data compression when only considering CPU overhead. In this section, we<br />

introduce both <strong>DB2</strong> encryption and the <strong>IBM</strong> Data Encryption Tool and discuss recent<br />

hardware enhancements that improve encryption per<strong>for</strong>mance.<br />

Today, many organizations are paying much more attention to the security of their data, to<br />

comply with various security regulations or as a result of emerging new technologies, <strong>for</strong><br />

example, the emergence of the internet, Storage Area Networks (SAN) and more intelligent<br />

storage controllers. (Do you trust your storage vendor not to look at your data?)<br />

However, data encryption has a number of challenges; including making changes to your<br />

application to encrypt and decrypt the data, encryption key management and the<br />

per<strong>for</strong>mance overhead of encryption.<br />

Machines prior to the z990 have a Cryptographic Coprocessor Feature to improve the<br />

per<strong>for</strong>mance of encryption and decryption. However, only CPU 0 and 1 could per<strong>for</strong>m<br />

encryption. To encrypt and decrypt data, tasks running on other processors need to be<br />

redispatched to run on CPU 0 or 1. Per<strong>for</strong>mance is there<strong>for</strong>e a problem if there is contention<br />

among tasks (<strong>for</strong> example, parallel query). In addition, dedicated LPARs might not be able to<br />

use the encryption hardware feature.<br />

The z990 introduced a new hardware instruction, CP Assist <strong>for</strong> Cryptographic Function<br />

(CPACF), which can run on all CPUs and is a feature available only on the z990 hardware and<br />

later, not the older z900. The z990 also introduces a PCIXCC card which is needed <strong>for</strong> the<br />

<strong>IBM</strong> Data Encryption Tool, but not <strong>for</strong> the <strong>DB2</strong> encryption function. Now, we briefly introduce<br />

these two encryption functions.<br />

<strong>DB2</strong> column level encryption<br />

<strong>DB2</strong> V8 ships a number of built-in functions which allow you to encrypt data at the cell level.<br />

These functions are ENCRYPT_TDES (or ENCRYPT), DECRYPT_BIN, DECRYPT_CHAR,<br />

and GETHINT. The SET ENCRYPTION PASSWORD statement allows you to specify a<br />

password as a key to encryption. Because you can specify a different password <strong>for</strong> every row<br />

that you insert, you can really encrypt data at the cell level in your tables. However, you are<br />

responsible <strong>for</strong> managing all these keys. So, make sure you have a mechanism in place to<br />

manage the passwords that are used to encrypt the data. Without the password, there is<br />

absolutely no way to decrypt the data. These encryption functions use the Triple Data<br />

Encryption Standard (Triple DES) to per<strong>for</strong>m the encryption.<br />

The <strong>DB2</strong> built-in encryption functions require:<br />

► <strong>DB2</strong> V8<br />

► Integrated Cryptographic Service Facility (ICSF)<br />

► On z990, CPACF is required (PCIXCC card is not, unless DRDA encryption is necessary)<br />

► Pre-z990, cryptographic coprocessor is required.<br />

188 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Each CP on the z990 has an assist processor on the chip in support of cryptography. This<br />

feature provides <strong>for</strong> hardware encryption and decryption support. Peripheral Component<br />

Interconnect Extended Cryptographic Coprocessor (PCIXCC) provides a cryptographic<br />

environment with added function. The PCIXCC consolidates the functions previously offered<br />

on the z900 by the Cryptographic Coprocessor feature (CCF) and the PCI Cryptographic<br />

Coprocessor (PCICC) feature. For a more detailed discussion of CPACF and PCIXCC, refer<br />

to the book <strong>IBM</strong> eServer zSeries 990 (z990) Cryptography Implementation, SG24-7070.<br />

Applications implementing <strong>DB2</strong> encryption must apply the <strong>DB2</strong> encrypt and decrypt built-in<br />

functions <strong>for</strong> each column to be encrypted or decrypted. All encrypted columns must be<br />

declared “<strong>for</strong> bit data”. So, unchanged read-applications see data in encrypted <strong>for</strong>m.<br />

Applications may apply a different key <strong>for</strong> each column, but may also supply the key in a<br />

special register. It is strongly recommended <strong>for</strong> per<strong>for</strong>mance to specify the key in the special<br />

register.<br />

LOAD and UNLOAD utilities do not support <strong>DB2</strong> encryption, but SQL-based programs such<br />

as DSNTIAUL do support encryption. Encryption of numeric fields is not supported. The<br />

length of encrypted columns must allow <strong>for</strong> an additional 24 bytes, rounded up to a double<br />

word boundary. So, space usage may be a concern if you plan to use <strong>DB2</strong> to encrypt small<br />

columns.<br />

Indexes are also encrypted. Predicates that depend on the collating sequence of encrypted<br />

columns, (<strong>for</strong> example range predicates), may produce wrong results (unless modified to use<br />

built-in functions correctly). For example:<br />

SELECT COUNT(*) WHERE COL = :HV;<br />

produces wrong results.<br />

SELECT COUNT(*) WHERE COL = ENCRYPT_TDES(:HV);<br />

produces correct results and almost no impact to per<strong>for</strong>mance.<br />

SELECT COUNT(*) WHERE COL < ENCRYPT_TDES(:HV);<br />

produces wrong results.<br />

SELECT COUNT(*) WHERE DECRYPT_CHAR(COL) < :HV;<br />

produces correct results with large impact on per<strong>for</strong>mance.<br />

<strong>IBM</strong> Data Encryption Tool <strong>for</strong> IMS and <strong>DB2</strong> Databases<br />

<strong>IBM</strong> also offers an encryption tool called <strong>IBM</strong> Data Encryption Tool <strong>for</strong> IMS and <strong>DB2</strong><br />

Databases. This tool per<strong>for</strong>ms row level encryption using EDITPROCs. Unlike the <strong>DB2</strong><br />

encryption functions shipped with <strong>DB2</strong>, the Data Encryption Tool uses different keys to<br />

encrypt different tables. The encryption keys can be either clear, like the <strong>DB2</strong> encryption<br />

functions, or secure and they are managed through ICSF (Integrated Cryptographic Service<br />

Facility). Clear keys are generally better per<strong>for</strong>ming. The tool also supports single, double, or<br />

triple DES. Once again, refer to the book, <strong>IBM</strong> eServer zSeries 990 (z990) Cryptography<br />

Implementation, SG24-7070, <strong>for</strong> a more detailed explanation of clear keys and secure keys.<br />

You can find more in<strong>for</strong>mation about the <strong>IBM</strong> Data Encryption Tool <strong>for</strong> IMS and <strong>DB2</strong><br />

Databases by visiting the Web site at:<br />

http://www.ibm.com/software/data/db2imstools/db2tools/ibmencrypt.html<br />

The <strong>IBM</strong> Data Encryption Tool <strong>for</strong> IMS and <strong>DB2</strong> Databases supports all versions of <strong>DB2</strong> but<br />

only encrypts the whole row. No application changes are required, however the DDL must be<br />

modified to include the EDITPROC. The applications do not need to be aware of encryption<br />

keys.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 189


4.8.1 Per<strong>for</strong>mance<br />

4.8.2 Conclusion<br />

The following software is required to support clear keys<br />

► APAR PQ93943 and PQ94822 <strong>for</strong> the tool<br />

► ICSF SPE APAR OA08172 (availability TBD)<br />

► FMID HCR770A or HCR770B<br />

► <strong>OS</strong>/390 V2R10 or later<br />

The following hardware is also required to support “clear” keys<br />

► On z990, both CPACF and a PCIXCC card<br />

► Pre z990, cryptographic coprocessor<br />

While, secure keys require the following hardware:<br />

► On z990, a PCIXCC card<br />

► Pre z990, the cryptographic coprocessor<br />

The PCIXCC card is required to install ICSF, which in turn, manages the encryption keys.<br />

Studies on z990 have shown <strong>DB2</strong> encryption costs approximately 2.3 microseconds per<br />

column, plus 0.0086 microseconds per byte. While the Encryption Tool (clear key) costs<br />

roughly 1 microsecond per row, plus 0.006 microseconds per byte.<br />

So, to fetch 100k rows, encrypting two 32 byte columns using <strong>DB2</strong> encryption:<br />

<strong>DB2</strong> cost of encryption = 2x(2.3 + 32x0.0086)x100,000 = 520,000 microseconds<br />

To fetch 100k rows with row size of 204 bytes using the Encryption Tool, the additional CPU<br />

time is:<br />

Encryption Tool cost = (1+204x0.006)x100,000 = 220,000 microseconds<br />

For an equivalent number of bytes, we found it is faster to use <strong>DB2</strong> encryption to encrypt and<br />

decrypt the data, in situations where the number of columns to be encrypted is three or less.<br />

Otherwise, may be a better choice. The breakeven point varies depending on how many other<br />

columns are in the table and how big each column is, but generally the <strong>IBM</strong> Data Encryption<br />

Tool is a better choice than <strong>DB2</strong> column level encryption from the per<strong>for</strong>mance level point of<br />

view.<br />

The cost of encryption is reduced on the z990 hardware, compared with the older z900<br />

hardware. CPU time <strong>for</strong> the Encryption Tool is 10 times faster on a z990 versus the z900, and<br />

the elapsed time <strong>for</strong> multithreaded applications using encryption is much faster on z990<br />

versus z900 depending on the number of concurrent tasks. Similar observations are<br />

applicable to the z890 processor, which has the same level of relative per<strong>for</strong>mance as the<br />

z990.<br />

The CPU per<strong>for</strong>mance implications <strong>for</strong> encryption are similar to data compression. However<br />

the impact on encryption on CPU is likely to be slightly higher than compression.<br />

OLTP per<strong>for</strong>mance is less affected than query per<strong>for</strong>mance. The best query per<strong>for</strong>mance is<br />

achieved by designing good indexes to avoid “touching” many rows.<br />

190 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.8.3 Recommendations<br />

For both <strong>DB2</strong> encryption and the <strong>IBM</strong> Data Encryption Tool, we recommend you move to the<br />

current z990 or z890 hardware, where the hardware-assisted encryption instructions are<br />

available on all processors.<br />

The <strong>IBM</strong> Encryption Tool (row level) per<strong>for</strong>ms generally better than the <strong>DB2</strong> encryption and<br />

decryption (column level). The break<br />

even point varies depending on how many other columns are in the table and their size.<br />

However, per<strong>for</strong>mance is not the only reason to choose one encryption strategy over the<br />

other, as they also vary in function.<br />

Encryption is done be<strong>for</strong>e compression, so compression and encryption cannot be effectively<br />

combined. Encrypted data does not tend to compress very well because repeating<br />

unencrypted characters are no longer repeating after they are encrypted.<br />

Important: Be aware that if you plan to use DRDA encryption, you need the PCIXCC<br />

function on your z990, because the hardware requires it.<br />

4.9 Row level security<br />

<strong>DB2</strong> recognized the need <strong>for</strong> more granular security of <strong>DB2</strong> data and introduced support <strong>for</strong><br />

Row Level Security in V8. Multilevel security support in z/<strong>OS</strong> 1.5 and RACF Security Server<br />

1.5, in conjunction with <strong>DB2</strong> V8, simplify row level security implementation and management<br />

significantly.<br />

In this section we first introduce Row Level Security, then describe the per<strong>for</strong>mance impact of<br />

Row Level security on <strong>DB2</strong> workloads.<br />

Security is becoming increasingly important in the past few years. Row level access control is<br />

increasingly critical. Many customers need to extend the granularity from table level to row<br />

level, so that an individual user is restricted to a specific set of rows. Good examples are Web<br />

hosting companies that need to store data from multiple customers into a single subsystem,<br />

database or table.<br />

In the past, views have been used to hide data. They can subselect data to provide only<br />

certain columns or fields. By creating a view and granting privileges on it, you can give<br />

someone access to only a specific combination of data. However, the application tends to<br />

become much more complex when views are used in this way. Separating the data into<br />

different databases or base tables has also been used to provide more granular security.<br />

<strong>DB2</strong> recognizes this need and introduces support <strong>for</strong> Row Level Security in V8. Multilevel<br />

security (MLS) support in z/<strong>OS</strong> 1.5 and RACF Security Server 1.5, in conjunction with <strong>DB2</strong><br />

V8, simplify row level security implementation and management significantly.<br />

Multilevel security is a security policy that allows the classification of data and users based on<br />

a system of hierarchical security levels, combined with a system of non-hierarchical security<br />

categories. A multilevel-secure security policy prevents unauthorized individuals from<br />

accessing in<strong>for</strong>mation at a higher classification than their authorization (read-up), and<br />

prevents individuals from declassifying in<strong>for</strong>mation (write-down).<br />

You can use MLS <strong>for</strong> multiple purposes in <strong>DB2</strong>:<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 191


Multilevel security with row-level granularity<br />

In this combination, <strong>DB2</strong> grants are used <strong>for</strong> authorization at the <strong>DB2</strong> object level (database,<br />

table, and so <strong>for</strong>th). Multilevel security is implemented only at the row level within <strong>DB2</strong>.<br />

External security is used only by multilevel security itself issuing the RACROUTE. This is the<br />

configuration on which we focus <strong>for</strong> the remainder of this section.<br />

Multilevel security at the object level with external access control<br />

In this combination, external access control, such as the RACF access control module, is<br />

used <strong>for</strong> authorization at the <strong>DB2</strong> object level. In addition, you can now define a proper<br />

hierarchy of security labels <strong>for</strong> <strong>DB2</strong> objects. For example, a database can be defined with a<br />

higher security label than its table spaces. The RACF access control module has been<br />

enhanced to use security labels to per<strong>for</strong>m access checking on <strong>DB2</strong> objects as part of<br />

multilevel security.<br />

Multilevel security with row level granularity with external access control<br />

This option combines both options mentioned above. It uses multilevel security to control the<br />

access to the <strong>DB2</strong> objects, as well as multilevel security (SECLABELs) to control access at<br />

the row level within <strong>DB2</strong>.<br />

In the following sections we describe some of the concepts of multilevel security. Multilevel<br />

security is complex and describing the details of it is beyond the scope of this publication. For<br />

more in<strong>for</strong>mation, refer to the z/<strong>OS</strong> Security Server publications. An introduction can be found<br />

in z/<strong>OS</strong> Planning <strong>for</strong> Multilevel Security and Common Criteria, SA22-7509.<br />

Security label: SECLABEL<br />

A security label (SECLABEL) is defined <strong>for</strong> each object which defines the sensitivity of that<br />

object. This security label indicates the hierarchical level or classification of the in<strong>for</strong>mation<br />

(such as top secret, confidential or general-use), as well as indicates to which<br />

non-hierarchical category the in<strong>for</strong>mation belongs within that level (such as group ABC or<br />

group XYZ).<br />

In RACF you must define two profiles in the RACF SECDATA resource class; one to define<br />

the security levels (SECLEVEL profiles) and the other to define the security categories<br />

(CATEGORY profile) <strong>for</strong> the system.<br />

Security level: SECLEVEL<br />

The hierarchical security level (SECLEVEL) defines the degree of sensitivity of the data. In<br />

the following example, security level, “L0” is defined to be a security level 10. The security<br />

administrator can define up to 254 security levels.<br />

RDEFINE SECDATA SECLEVEL UACC(READ)<br />

RALTER SECDATA SECLEVEL ADDMEM(L0/10 L1/30 L2/50 L3/70 L4/90)<br />

Security category: CATEGORY<br />

The non-hierarchical CATEGORY profile further qualifies the access capability. The security<br />

administrator can define zero or more categories that correspond to some grouping<br />

arrangement in the installation. The CATEGORY profile contains a member <strong>for</strong> each<br />

non-hierarchical category in the system. For example, C1 through C5 are security categories.<br />

RDEFINE SECDATA CATEGORY UACC(READ)<br />

RALTER SECDATA CATEGORY ADDMEM(C1 C2 C3 C4 C5)<br />

Defining Security labels<br />

After defining the SECLEVEL and CATEGORY profiles, the security administrator defines a<br />

profile in the SECLABEL resource class <strong>for</strong> each security label. The SECLABEL is a name of<br />

192 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


up to eight uppercase alphanumeric or national characters and each SECLABEL profile<br />

specifies the particular combination of:<br />

► A SECLEVEL member<br />

► Zero or more members of the CATEGORY profile that apply to the security label<br />

For example:<br />

RDEFINE SECLABEL L1C12 SECLEVEL(L1) ADDCATEGORY(C1 C2) UACC(NONE)<br />

In addition, RACF has a number of built-in security labels.<br />

► SYSHIGH: Is equivalent to the highest security level defined and covers all categories<br />

defined.<br />

► SYSLOW: Is equivalent to the lowest security level defined and has no categories signed.<br />

It is dominated by all other security labels.<br />

► SYSNONE: Is treated as equivalent to any security label to which it is compared.<br />

SYSNONE, like SYSLOW, should be used <strong>for</strong> data that has no classified data content.<br />

► SYSMULTI: Is treated as equivalent to any defined security label. It is intended to be used<br />

by users <strong>for</strong> access to data that has multilevel data classified.<br />

Assigning security labels<br />

A subject (or user ID) can have more than one security label, but can only use one security<br />

label at a given time. To authorize a subject to use a security label, the security administrator<br />

permits that subject’s user ID to the profile in the RACF SECLABEL resource class <strong>for</strong> the<br />

security label. Do not <strong>for</strong>get to RACLIST REFRESH the SECLABEL class.<br />

PERMIT L1C12 CLASS(SECLABEL) ACCESS(READ) ID(USER01)<br />

The security label that a subject uses at a given time can be assigned in a number of ways.<br />

For example, a TSO/E user can specify a security label on the logon panel, and a batch user<br />

can specify a security label on the JOB statement. The default SECLABEL is defined in the<br />

user’s RACF profile.<br />

A resource can have only one security label. For most types of resources, the security<br />

administrator assigns a security label to each resource in the system that is to be protected by<br />

ensuring that the resource is protected by a profile, and by specifying the security label in the<br />

profile.<br />

For <strong>DB2</strong> row level security, <strong>DB2</strong> maintains the security label in a new column attribute within<br />

the table itself. To implement multilevel security, the DBA adds a column with the security<br />

label data type to an existing table. This is done by defining a column with the AS SECURITY<br />

LABEL attribute. Each row value has a specific SECLABEL. This new column is populated<br />

with security label in<strong>for</strong>mation when data is inserted into the table. Every row can have a<br />

different security label although this is not likely in practice. More likely, the number of distinct<br />

security labels is much smaller than the number of rows in a table.<br />

How Row Level Security works<br />

Briefly, access to tables is controlled by security labels which are assigned to users as well as<br />

to the data. If the security labels of a user and the data are an equivalent level, that user can<br />

access the data.<br />

Dominance<br />

One security label dominates another security label when both of the following conditions are<br />

true:<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 193


► The security level that defines the first security label is greater than or equal to the security<br />

level that defines the second security label.<br />

► The set of security categories that defines the first security label includes the set of<br />

security categories that defines the second security label.<br />

You can also look at dominance in a simplistic way as one security label being “greater than”<br />

another.<br />

Reverse dominance<br />

With reverse dominance access checking, the access rules are the reverse of the access<br />

rules <strong>for</strong> dominance access checking. This type of checking is not used by <strong>DB2</strong>.<br />

In loose terms, it can be looked as “less than or equal to” checking.<br />

Equivalence<br />

Equivalence of security labels means that either the security labels have the same name, or<br />

they have different names but are defined with the same security level and identical security<br />

categories.<br />

You can look at this type of checking as “equal to” checking. (One way to check is if both<br />

dominance and reverse dominance are true.)<br />

Disjoint<br />

Two security labels are considered disjoint when they have at least one category that the<br />

other does not have. Neither of the security labels dominates the other.<br />

Read-up<br />

Multilevel security controls prevent unauthorized individuals from accessing in<strong>for</strong>mation at a<br />

higher classification than their authorization. It does not allow users to “read-up” or read<br />

above their authorization level. Read-up is en<strong>for</strong>ced through dominance checking.<br />

Write-down<br />

Multilevel security also prevents individuals from declassifying in<strong>for</strong>mation. This is also known<br />

as write-down, that is, writing in<strong>for</strong>mation back at a lower level (down-level) than its current<br />

classification. Write-down is prevented by doing equivalence checking.<br />

However, there may be cases where you want to allow write-down by selected individuals.<br />

The security administrator controls whether write-down is allowed at the system level by<br />

activating and deactivating the RACF MLS(FAILURES) option (using the SETROPTS<br />

command), or <strong>for</strong> controlled situations of write-down in which z/<strong>OS</strong> allows the security<br />

administrator to assign a “write-down by user” privilege to individual users that allows those<br />

users to select the ability to write down. To do so, a user has to have at least read authority on<br />

the IRR.WRITEDOWN.BYUSER profile in the RACF FACILITY class.<br />

Accessing data<br />

When a query fetches data from a table, <strong>DB2</strong> checks the security label of the user submitting<br />

the query to the security label of the row. If there is a match (equivalent or dominating), the<br />

row is returned to the user. To per<strong>for</strong>m this check, <strong>DB2</strong> invokes RACROUTE <strong>for</strong> the<br />

determination. <strong>DB2</strong> also caches the decision made by RACF so that subsequent rows with<br />

the same data security label could be determined locally.<br />

For more detail on Multilevel Security, see z/<strong>OS</strong> Planning <strong>for</strong> Multilevel Security and Common<br />

Criteria, SA22-7509, and the recent book, z/<strong>OS</strong> Multilevel Security and <strong>DB2</strong> Row-level<br />

Security Revealed, SG24-6480.<br />

194 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.9.1 Per<strong>for</strong>mance<br />

We can implement RACF external security with MLS at the <strong>DB2</strong> object level to control access<br />

to databases, table spaces, tables, views, indexes, storage groups, buffer pools, plans,<br />

packages, stored procedures, and more. This is done by implementing the <strong>DB2</strong> and RACF<br />

security exit DSNX@XAC. See the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Administration Guide,<br />

SC18-7413-01, and the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 RACF Access Control Module Guide,<br />

SC18-7433, <strong>for</strong> discussions regarding how to implement RACF External Security <strong>for</strong> <strong>DB2</strong>.<br />

At the time of writing this book, there have been no per<strong>for</strong>mance studies conducted<br />

comparing RACF External Security <strong>for</strong> <strong>DB2</strong> objects, (either with or without using MLS), with<br />

<strong>DB2</strong> native security. However, we consider the impact of <strong>DB2</strong> External Security over <strong>DB2</strong><br />

native security (GRANT and REVOKE) insignificant.<br />

We can also implement RACF MLS security with row level granularity, as is described here.<br />

These per<strong>for</strong>mance studies explore the per<strong>for</strong>mance impact of <strong>DB2</strong> Row Level Security<br />

where there was no RACF external security at all, only <strong>DB2</strong> native security. No application<br />

changes were made and there was no “application” row level security implemented (<strong>for</strong><br />

example via views). Obviously, if you wish to change your application to remove any<br />

application-implemented row level security techniques and implement <strong>DB2</strong> Row Level<br />

Security, your application probably becomes less complex and there<strong>for</strong>e less CPU intensive.<br />

Any CPU overhead caused by <strong>DB2</strong> Row Level Security should be offset by these savings.<br />

A user or thread has only one SECLABEL “active” at any one time. When rows are accessed,<br />

<strong>DB2</strong> checks the thread’s, or user’s SECLABEL value with each new SECLABEL value from<br />

the rows being accessed. To avoid going to RACF <strong>for</strong> each and every row accessed, <strong>DB2</strong><br />

caches all the SECLABEL values that have been checked, both successfully or<br />

unsuccessfully. The cache is maintained per thread and is flushed on commit and rollback.<br />

So, if immediate changes are required in the security policy, then long-running applications<br />

which have not committed or rolled back may need to be canceled.<br />

In a general sense, you can think of <strong>DB2</strong> evaluating SECLABEL values in the same way as<br />

<strong>DB2</strong> evaluating Stage 1 predicates, only in that <strong>DB2</strong> attempts to per<strong>for</strong>m SECLABEL<br />

checking as a Stage 1 activity. During access path selection, the <strong>DB2</strong> optimizer does not<br />

consider the task of evaluating the SECLABELs the same way as it would any Stage 1<br />

predicates. This is similar to resolving referential constraints. However, the need to evaluate<br />

SECLABEL values can impact SQL access paths. For example, Index Only access may now<br />

be regressed to an Index plus data access (to retrieve each row’s SECLABEL value), if the<br />

index being selected does not also contain the SECLABEL column. Row Level Security can<br />

there<strong>for</strong>e have a significant impact on your application per<strong>for</strong>mance by changing access<br />

paths.<br />

The overhead of Row Level Security in <strong>DB2</strong> is recorded as Accounting class 2 CPU time and<br />

varies depending on the complexity of your SQL, how many rows your query needs to “touch”<br />

during Stage 1 processing, and how many different SECLABEL values you have in your table.<br />

The more complex the query, the less impact Row Level Security has on CPU. This is<br />

because the overhead of Row Level Security is diluted with more CPU intensive queries.<br />

There<strong>for</strong>e, your mileage will vary!<br />

SELECT<br />

The user's SECLABEL is compared to the data SECLABEL of each row to be selected, also<br />

<strong>for</strong> the rows that do not qualify. If the SECLABEL of the user dominates the SECLABEL of the<br />

row, <strong>DB2</strong> returns the row. If the SECLABEL of the user does not dominate the SECLABEL of<br />

the row, <strong>DB2</strong> does not return the data from that row, and <strong>DB2</strong> does not generate an error.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 195


<strong>DB2</strong> must call RACF <strong>for</strong> this dominance checking if the rows SECLABEL has not already<br />

been encountered and there<strong>for</strong>e cached.<br />

If RACF is called, studies have shown up to a 10% impact on CPU with SELECT statements<br />

using Row Level Security. If the SECLABEL is found in the cache, this impact reduces to 2%.<br />

For a FETCH rather than a SELECT, this can be as high as 5%. This is because the CPU time<br />

which can be attributed to the overhead or Row Level Security consumes a larger percentage<br />

of the total CPU time.<br />

INSERT<br />

If the user has write-down privilege or write-down control is not enabled, the user can set the<br />

SECLABEL <strong>for</strong> the row to a valid security label that is not disjoint in relation to the user's<br />

security. If the user does not specify a value <strong>for</strong> the SECLABEL, the SECLABEL of the row<br />

becomes the same as the SECLABEL of the user. Alternatively, If the user does not have<br />

write-down privilege and write-down control is enabled, the SECLABEL of the row becomes<br />

the same as the SECLABEL of the user.<br />

The cost of each INSERT statement can increase by up to 2%. This is also dependent on the<br />

complexity of the INSERT statement, the number of columns to be INSERTed and the<br />

number of indexes that must be updated. The extra overhead results in <strong>DB2</strong> extracting the<br />

user’s SECLABEL value and building the new row with this extra column.<br />

UPDATE<br />

If the SECLABEL of the user and the SECLABEL of the row are equivalent, the row is<br />

updated and the value of the SECLABEL is determined by whether the user has write-down<br />

privilege. If the user has write-down privilege or write-down control is not enabled, the user<br />

can set the SECLABEL of the row to a valid security label that is not disjoint in relation to the<br />

user's security. If the user does not have write-down privilege and write-down control is<br />

enabled, the SECLABEL of the row is set to the value of the SECLABEL of the user.<br />

Alternatively, if the SECLABEL of the user dominates the SECLABEL of the row, the result of<br />

the UPDATE statement is determined by whether the user has write-down privilege. If the<br />

user has write-down privilege or write-down control is not enabled, the row is updated and the<br />

user can set the SECLABEL of the row to a valid security label that is not disjoint in relation to<br />

the user's security. If the user does not have write-down privilege and write-down control is<br />

enabled, the row is not updated.<br />

Finally, if the SECLABEL of the row dominates the SECLABEL of the user, the row is not<br />

updated.<br />

As is the case with SELECT, RACF is not consulted unless the user’s SECLABEL is not<br />

already cached. There<strong>for</strong>e we see the same degree of overhead in using Row Level Security<br />

as in the case of SELECT. We see up to a 10% per<strong>for</strong>mance impact if the user’s SECLABEL<br />

is not cached and up to 2% if it is cached.<br />

DELETE<br />

If the SECLABEL of the user and the SECLABEL of the row are equivalent, the row is<br />

deleted.<br />

If the SECLABEL of the user dominates the SECLABEL of the row, the user’s write-down<br />

privilege determines the result of the DELETE statement: If the user has write-down privilege<br />

or write-down control is not enabled, the row is deleted. Alternatively, if the user does not have<br />

write-down privilege and write-down control is enabled, the row is not deleted.<br />

Finally, if the SECLABEL of the row dominates the SECLABEL of the user, the row is not<br />

deleted.<br />

196 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The per<strong>for</strong>mance impact of Row Level Security on DELETE is there<strong>for</strong>e very similar to the<br />

per<strong>for</strong>mance impact on UPDATE.<br />

Utilities<br />

You need a valid SECLABEL and additional authorizations to run certain LOAD, UNLOAD,<br />

and REORG TABLESPACE jobs on tables that have multilevel security enabled. All other<br />

utilities check only <strong>for</strong> authorization to operate on the table space; they do not check <strong>for</strong><br />

row-level authorization and are there<strong>for</strong>e not impacted. Offline utilities such as DSN1COPY<br />

and DSN1PRNT do not impose Row Level Security and are also not impacted.<br />

At the time of writing this book, no actual per<strong>for</strong>mance studies have been undertaken to<br />

quantify the impact of Row Level Security on utilities. However, we can make some comment<br />

as to what per<strong>for</strong>mance impact may occur. As always the per<strong>for</strong>mance overhead on utilities<br />

varies greatly, depending on how many columns are in the table and how complex the<br />

definitions of the columns are. A utility processing more columns and per<strong>for</strong>ming more<br />

complex data conversion sees less impact using Row Level Security because any impact of<br />

SECLABEL processing is diluted. However, the CPU overhead of using Row Level Security<br />

may be significant when you are processing a large number of rows with few columns in each<br />

row. As always, your mileage will vary.<br />

Executing a LOAD RESUME utility against a table space containing tables with Row Level<br />

Security requires that the user is identified to RACF and has a valid SECLABEL. LOAD<br />

RESUME adheres to the same rules as INSERT. Without write-down authorization, the<br />

SECLABEL in the table is set to the SECLABEL associated with the user ID executing the<br />

LOAD RESUME utility. With write-down, any valid security label that is not disjoint in relation<br />

to the user's security can be specified. So, the per<strong>for</strong>mance impact of Row Level Security on<br />

LOAD RESUME is similar, but slightly higher than that of INSERTs.<br />

LOAD REPLACE deletes all rows in a table space. There<strong>for</strong>e, write-down authority is<br />

required. If the user ID associated with the job that is running the LOAD REPLACE utility does<br />

not have write-down privilege, and write-down is in effect, an error message is issued.<br />

Executing the UNLOAD or REORG UNLOAD EXTERNAL utility against tables with Row<br />

Level Security requires that the user associated with the job is identified to RACF, and have a<br />

valid SECLABEL. For each row unloaded from those tables, if the user SECLABEL dominates<br />

the data SECLABEL, then the row is unloaded. If the user’s SECLABEL does not dominate<br />

the data SECLABEL, the row is not unloaded and no error is returned. The per<strong>for</strong>mance<br />

impact is there<strong>for</strong>e similar to that of SELECT.<br />

The UNLOAD utility has a sampling option where you can specify a percentage of rows to be<br />

unloaded. The sampling filter operates only on the rows you are allowed to access, so it is not<br />

possible <strong>for</strong> an unauthorized user to calculate the total size of the table using the UNLOAD<br />

utility. However, the RUNSTATS utility, which also has a sampling function, does not invoke<br />

Row Level Security. RUNSTATS also updates the <strong>DB2</strong> catalog with column distribution<br />

statistics and column values. We there<strong>for</strong>e recommend that if you are planning to implement<br />

MLS Row Level Security to protect your data, you should also review who has access to your<br />

<strong>DB2</strong> catalog tables.<br />

Executing REORG... DISCARD on tables with Row Level Security requires that the user is<br />

identified to RACF and has a valid SECLABEL. REORG with the DISCARD option adheres to<br />

the same rules as the SQL DELETE statement. For each row unloaded from those tables, if<br />

the row qualifies to be discarded, the user SECLABEL is compared to the data SECLABEL.<br />

We would there<strong>for</strong>e evaluate the per<strong>for</strong>mance impact to be slightly higher than that of<br />

DELETEs.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 197


4.9.2 Conclusion<br />

The CPU increase caused by Row Level Security occurs because <strong>DB2</strong> must now access the<br />

SECLABEL column in the table, evaluate the user’s SECLABEL against the SECLABEL of<br />

the data, manage a cache of SECLABEL values, and periodically consult RACF. At a very<br />

rough level, the per<strong>for</strong>mance impact of row level security can be considered in the same<br />

ballpark as <strong>DB2</strong> data compression with less than a 5% impact <strong>for</strong> a typical online transaction<br />

but higher <strong>for</strong> a CPU-bound sequential scan.<br />

However, these CPU costs are very much dependent on the complexity of the SQL, the<br />

number and size of columns manipulated by the SQL and the number of indexes that need to<br />

be updated. Anticipate seeing more overhead with simple queries which must touch a large<br />

number of unique seclabels and users, so that the cache is ineffective, rather than complex<br />

queries. A simple table space scan returning a small number of rows can potentially<br />

experience the highest impact, even with caching.<br />

Users who have already implemented a <strong>for</strong>m of row level security in their application and want<br />

to convert to <strong>DB2</strong>’s implementation of Row Level Security should not see a high CPU<br />

increase. The applications probably are less complex and the SQL less complex and<br />

expensive to run. So, the extra cost in CPU caused by Row Level Security should be<br />

compensated by the savings in CPU resulting from a simpler application.<br />

4.9.3 Recommendations<br />

Row Level Security using MLS only has a small overhead compared to no row level security<br />

at all. In addition, the MLS Row Level Security probably out per<strong>for</strong>ms any application<br />

implementation which provides similar function. MLS Row Level Security also offers a more<br />

complete or secure solution than many application implementations of row level security.<br />

When you add MLS Row Level Security into your existing applications, or design new ones<br />

with it, you should consider the per<strong>for</strong>mance impact to the application and possibly review the<br />

physical design.<br />

The per<strong>for</strong>mance of accessing tables that contain a security label can be impacted if the<br />

SECLABEL column is not included in the indexes. The SECLABEL column is used whenever<br />

a table with Row Level Security enabled is accessed. Access paths may change as <strong>DB2</strong> must<br />

now access the SECLABEL column. An index only scan may now turn into an index plus data<br />

scan. There<strong>for</strong>e, it is a good idea to include the SECLABEL column in your existing indexes if<br />

your index design allows, especially when your queries are using index-only access today.<br />

<strong>DB2</strong> caches security labels to avoid extra calls to RACF. This caching would work best if there<br />

are a relatively small number of security labels to be checked compared with the number of<br />

rows accessed.<br />

Some application processes may also need to change to accommodate write-down<br />

processing and preserve existing SECLABEL values in the table. For example, you may need<br />

to run multiple SQL or batch jobs against a table where you would normally run a single<br />

execution. In this way, you preserve the SECLABEL values already in the table.<br />

For example, if you have an SQL process to increase everyone’s salary by 10%:<br />

UPDATE PAYROLL<br />

SET SALARY = SALARY * 1.1<br />

You need write-down authority to update the whole table. Un<strong>for</strong>tunately <strong>DB2</strong> sets ALL<br />

SECLABEL values to the one value.<br />

198 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


4.10 New CI size<br />

To preserve the SECLABEL values that are in the table, you need to execute the SQL in<br />

separate tasks with the various unique seclabels in the table, and include the predicate:<br />

WHERE SECLABEL_COLUMN = GETVARIABLE(SYSTEM.SECLABEL)<br />

An alternative is to include another SET clause in the SQL UPDATE statement in order to<br />

preserve the SECLABLE values already in the table.<br />

UPDATE PAYROLL<br />

SET SALARY = SALARY * 1.1,<br />

SECLABEL_COLUMN = SECLABEL_COLUMN<br />

This technique would require write-down authority <strong>for</strong> the user running the job. If there are<br />

any rows in the table that dominate (not equivalent) the user's seclabel, then they are not<br />

updated.<br />

In summary, although MLS Row Level Security can simplify the separation in an application, it<br />

is not transparent. You need to review how your application INSERTs and UPDATEs the data,<br />

as these processes probably need to change in order to manage and maintain the<br />

SECLABEL values in the data. There are similar considerations <strong>for</strong> batch processes and<br />

some utilities. Utilities may also take a little longer to execute. Processes <strong>for</strong> managing and<br />

controlling which processes have the write-down authority must also be developed.<br />

With V7, <strong>DB2</strong> only uses the VSAM Control Interval (CI) size of 4 KB. If the page size is 8, 16<br />

or 32 KB, <strong>DB2</strong> treats the page as a chain of 2, 4, or 8 CIs and requires VSAM to only allocate<br />

CIs in 4 KB blocks.<br />

<strong>DB2</strong> V8 introduces support <strong>for</strong> VSAM CI sizes of 8, 16, and 32 KB, activated by the new<br />

DSNZPARM parameter, DSVCI, in panel DSNTIP7. This is valid <strong>for</strong> both user-defined and<br />

<strong>DB2</strong> STOGROUP-defined table spaces. Index spaces only use 4 KB pages.<br />

Once you have activated the new CI sizes (in NFM), all new table spaces are allocated by<br />

<strong>DB2</strong> with a CI corresponding to the page size. The table spaces already existing at the time of<br />

migration to <strong>DB2</strong> V8 are later converted by the first execution of LOAD REPLACE or REORG.<br />

When using <strong>DB2</strong> user-defined objects (USING VCAT), it is your responsibility to define the<br />

underlying VSAM cluster with the correct CISIZE.<br />

<strong>DB2</strong> uses VSAM linear data sets, (LDS), which only uses a CI size which is a multiple of 4<br />

KB, and no CIDF. CIs are written by VSAM in physical blocks which try to use the best fit<br />

within the CI, and keep track occupancy decent.<br />

Now, consider Table 4-12, which describes the existing relationship between <strong>DB2</strong> V7 page<br />

sizes and VSAM CI sizes assuming a 3390 disk.<br />

Table 4-12 <strong>DB2</strong> V7 - Sizes in KB (usable track size 48 KB <strong>for</strong> 3390)<br />

<strong>DB2</strong> page size VSAM CI size VSAM physical<br />

block size<br />

Blocks per track <strong>DB2</strong> pages per<br />

track<br />

4 4 4 12 12<br />

8 4 4 12 6<br />

16 4 4 12 3<br />

32 4 4 12 1.5<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 199


4.10.1 Per<strong>for</strong>mance<br />

VSAM does not know the <strong>DB2</strong> page size, nor the fact that <strong>DB2</strong> chains the VSAM CIs to make<br />

up its “logical” page size. VSAM I/Os cannot span cylinder boundaries or data set extent<br />

boundaries. So, we can see by Table 4-12 that if we have a <strong>DB2</strong> page size of 32 KB, VSAM<br />

can write 22.5 32 KB <strong>DB2</strong> pages per cylinder, (15 X 1.5). A 32 KB <strong>DB2</strong> page can there<strong>for</strong>e<br />

span a cylinder boundary and there<strong>for</strong>e span DASD volumes. This is not a problem since <strong>DB2</strong><br />

chains the physical pages and guarantees the data integrity by ensuring all 8 VSAM pages<br />

are written correctly.<br />

Since a 32 KB <strong>DB2</strong> “logical” page can span DASD volumes, restrictions exist in V7 that<br />

Concurrent Copy cannot support 32 KB pages and striping of objects with a page size > 4 KB<br />

is not supported <strong>for</strong> <strong>DB2</strong> data sets. In V7, striping is only allowed to 4 KB page sets and<br />

Concurrent Copy is not allowed <strong>for</strong> 32 KB table spaces. Concurrent Copy can copy the two<br />

volumes at different points in time; however, a single <strong>DB2</strong> 32 KB “logical” page can span<br />

these two DASD volumes. A <strong>DB2</strong> page should not be allowed to span a CA boundary and in<br />

the case of striping, a CI cannot span a cylinder.<br />

Now, we see what has changed in V8. Consider Table 4-13, which describes the relationship<br />

between <strong>DB2</strong> V8 page sizes and VSAM CI sizes.<br />

Table 4-13 <strong>DB2</strong> V8 - Sizes in KB (usable track size 48 KB <strong>for</strong> 3390)<br />

<strong>DB2</strong> page size VSAM CI size VSAM physical<br />

block size<br />

VSAM now deals with the 4 different CI sizes, and, knowing the track size, now allows CI size<br />

equal to page size. VSAM writes the CI in a physical block of the same size as the page, but<br />

splits the 32 KB CI over two blocks of 16 KB in order not to waste space due track size (48<br />

KB). It fits the 32 KB CIs 1.5 per track. VSAM also takes care of spanning track boundaries<br />

and operates I/O at the CI level. A 16 KB block is wasted every 15 tracks (CA size) because<br />

the CI cannot span a CA boundary. This is a small price to pay, now that VSAM is aware of<br />

the <strong>DB2</strong> page size.<br />

Now VSAM can guarantee a <strong>DB2</strong> page does not span CAs and there<strong>for</strong>e DASD volumes.<br />

The new CI sizes reduce integrity exposures, and relieve restrictions on concurrent copy (of<br />

32 KB objects) and the use of striping (of objects with a page size > 4 KB). It also resolves<br />

small integrity exposure with the Split Mirror solution using FlashCopy on 32 KB pages (SAP)<br />

if at the extent border. A <strong>DB2</strong> page now is always written in a single I/O and is totally<br />

contained in the same extent and the same device (even if striping is used).<br />

What happens to I/O per<strong>for</strong>mance if we increase the VSAM CI size from 4 KB, to 8 KB, to 16<br />

KB? Preliminary measurements show that large CIs are beneficial <strong>for</strong> FICON channels and<br />

storage controllers <strong>for</strong> table space scans. Table 4-14 shows I/O service times on a ESS 800<br />

<strong>for</strong> 4 KB, 8 KB, 16 KB and 32 KB page sizes, respectively.<br />

200 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Blocks per track <strong>DB2</strong> pages per<br />

track<br />

4 4 4 12 12<br />

8 8 8 6 6<br />

16 16 16 3 3<br />

32 32 16 3 1.5


Table 4-14 I/O service time on ESS 800<br />

I/O service time on ESS 800<br />

(ms)<br />

We see fewer “blocks” on a FICON link which results in the improved per<strong>for</strong>mance. We can<br />

also see that changing the VSAM CI size has little impact on I/O per<strong>for</strong>mance.<br />

However, there is an impact on <strong>DB2</strong> buffer pool hit ratios. For example, if you increase your<br />

<strong>DB2</strong> page size from 4 KB to 8 KB and do not increase your buffer pool size, then you are only<br />

able to cache half as many pages in the buffer pool. This certainly impacts the buffer pool hit<br />

ratio. If you do plan to use larger <strong>DB2</strong> page sizes, we recommend you also review your <strong>DB2</strong><br />

buffer pool sizes. However always ensure you have enough real storage available to back any<br />

increase in buffer pools, to avoid any paging to disk.<br />

Now we turn our attention to <strong>DB2</strong>. Figure 4-20 compares a <strong>DB2</strong> table space scan with 4 KB, 8<br />

KB and 16 KB page sizes respectively.<br />

Figure 4-20 Larger CI size impact on <strong>DB2</strong><br />

Page sizes<br />

4 KB 8 KB 16 KB 32 KB<br />

Cache hit 0.4 0.43 0.5 0.7<br />

Cache miss 7.0 7.03 7.1 7.3<br />

MB/sec<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

<strong>DB2</strong> Table Scan Throughput<br />

ESS 800 FICON<br />

Non-EF EF<br />

Dataset type<br />

4K CI<br />

8K CI<br />

16K CI<br />

A <strong>DB2</strong> page size of 32 KB is not shown as VSAM implements this as 2 16 KB CIs. So, the<br />

results are the same as a <strong>DB2</strong> 16 KB page size. EF data sets are VSAM Extended Format<br />

data sets. EF data sets are required to allocate table spaces larger than 4 GB and <strong>for</strong><br />

DFSMS striping.<br />

The per<strong>for</strong>mance improvements are most pronounced when using Extended Format (EF)<br />

VSAM data sets. We see 45% improvement when we increase the VSAM CI size from 4 KB<br />

to 16 KB, and we see huge 70% improvements if these data sets are also EF-Enabled.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 201


4.10.2 Conclusion<br />

4.10.3 Striping<br />

All I/O bound executions benefit with using larger VSAM CI sizes, including COPY and<br />

REORG. This enhancement can also potentially reduce elapsed time <strong>for</strong> table space scans.<br />

There is little to be gained in per<strong>for</strong>mance by going above 16 KB CI size.<br />

Now, <strong>for</strong> a few brief words on VSAM striping. In <strong>DB2</strong> V7, VSAM striping was only<br />

recommended <strong>for</strong> <strong>DB2</strong> log data sets and <strong>DB2</strong> work file data sets. Although you could also use<br />

VSAM striping <strong>for</strong> application data with 4 KB pages, it was not generally recommended or<br />

widely used, because it was not extensively researched or tested. However, some customers<br />

have used VSAM striping rather successfully in V7 on <strong>DB2</strong> indexes, to dramatically increase<br />

the per<strong>for</strong>mance of REBUILD INDEX. Once you have saturated your channels, VSAM striping<br />

does not really help.<br />

I/O striping is beneficial <strong>for</strong> those cases where parallel partition I/O is not possible, <strong>for</strong><br />

example, segmented tablespaces, work files, non-partitioning indexes, and so on.<br />

4.10.4 Recommendations<br />

If you already have large pages, migrate them to large CIs. The default CI size is equal to the<br />

page size. If you have large table space scans, larger CIs can also help.<br />

4.11 <strong>IBM</strong> System z9 and MIDAWs<br />

MIDAW stands <strong>for</strong> Modified Indirect Data Address Word facility, and as the name says, it is a<br />

modification to the standard IDAW channel programming technique that has existed since the<br />

S/360 days. MIDAWs adds a new method of gathering data into and scattering data from<br />

discontiguous storage locations during I/O operations. This improves the per<strong>for</strong>mance of<br />

FICON channels.<br />

MIDAWs require the <strong>IBM</strong> System z9 server and z/<strong>OS</strong> Release 1.7 or APAR OA10984 with<br />

z/<strong>OS</strong> Release 1.6, see Figure 4-21.<br />

202 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


z9-109 I/O Overview<br />

I/O Enhancements<br />

– Up to 28 FICON Express/FICON Express2 features<br />

per I/O cage<br />

• 4 channels/feature FICON/FCP<br />

• 1, 2 Gbps auto-negotiated<br />

– Modified Indirect Data Address Word (MIDAW) facility<br />

– Multiple (2) Subchannel sets (MSS)<br />

• Increase to 63.75K Subchannels <strong>for</strong> Set-0<br />

– Up to 64* x 2.7GB STI’s (21 STIs max <strong>for</strong> 3 I/O cages)<br />

Storage Area Networks (SANs) enhancements<br />

– N_Port ID Virtualization<br />

– Program Directed re-IPL<br />

– FICON Link Incident Reporting<br />

Networking enhancements<br />

– HiperSockets IPv6<br />

– <strong>OS</strong>A-Express2 1000BASE-T Ethernet<br />

– <strong>OS</strong>A-Express2 <strong>OS</strong>N (<strong>OS</strong>A <strong>for</strong> NCP support)<br />

– GARP VLAN management (GRVP) * z9-109 exploits a subset of its designed I/O capability<br />

9109TLLB 1<br />

Figure 4-21 <strong>IBM</strong> System z9<br />

©2005<strong>IBM</strong>C ti<br />

The use of MIDAWs reduces the number of frames and sequences flowing across the link,<br />

making the channel more efficient.<br />

Figure 4-22 summarizes the comparisons with and without MIDAW <strong>for</strong> a partitioned table<br />

space scan. Page fixing is active and the table space is in EF.<br />

The I/O response time is reduced by about 50%, and gets even better increasing the number<br />

of partitions. Channel utilization is largely reduced, and the throughput increases up to 186<br />

MB/sec, close to the FICON link nominal capability of 200 MB/sec in one direction.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 203


5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

9109TLLB 4<br />

Parallel <strong>DB2</strong> Table Scan, EF 4K (single channel)<br />

I/O Response Time (sec)<br />

pend connect<br />

Pre-MIDAWs MIDAWs<br />

1 2 3 1 2 3<br />

Number of <strong>DB2</strong> partitions<br />

Figure 4-22 Table space scan with MIDAWs<br />

The measurements have also shown that EF and non EF data sets have similar throughput<br />

using MIDAW <strong>for</strong> sequential prefetch of 4 KB pages.<br />

Notice that large pages do not require MIDAWs to achieve excellent I/O per<strong>for</strong>mance, they<br />

already benefitted from the per<strong>for</strong>mance improvements of FICON Express2 and the<br />

DS8000. MIDAWs add benefits targeted at the 4 KB pages.<br />

4.12 Instrumentation enhancements<br />

There are several instrumentation changes with <strong>DB2</strong> V8. See Appendix F of the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong><br />

z/<strong>OS</strong> <strong>Version</strong> 8 Release Planning Guide, SC18-7425-01, <strong>for</strong> an overview of the record<br />

changes. Details are in the DSNWMSGS member of the SDSNIVPD library and recent<br />

related maintenance is listed in APAR PQ86477. This is a list of the major changes:<br />

► Package level accounting<br />

► Accounting rollup <strong>for</strong> DDF & RRSAF<br />

► New and improved traces, larger monitor area<br />

► Long-running reader<br />

► Lock escalation<br />

► Full SQL statement<br />

► PREPARE attributes<br />

► High water marks<br />

► Secondary authorization ids<br />

► Storage 64-bit, READS<br />

► Dynamic statement cache<br />

► Temporary space usage<br />

► Auditing <strong>for</strong> multilevel security<br />

► Option <strong>for</strong> EBCDIC or Unicode data<br />

204 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Configuration:<br />

•MIDAW: z/<strong>OS</strong> 1.7<br />

•Pre-MIDAW: z/<strong>OS</strong> 1.4<br />

•<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

•4000 byte row size<br />

•System z9 109<br />

•FICON Express 2<br />

•2 Gbit/sec link<br />

•DS8000 control unit<br />

pre-MIDAWs MIDAWs<br />

Channel<br />

Busy%<br />

Throughput<br />

(MB/sec)<br />

100<br />

80<br />

60<br />

40<br />

20<br />

0<br />

1 2 3<br />

Number of <strong>DB2</strong> partitions<br />

200<br />

150<br />

100<br />

50<br />

0<br />

1 2 3<br />

Number of <strong>DB2</strong> partitions<br />

This document contains per<strong>for</strong>mance in<strong>for</strong>mation. Per<strong>for</strong>mance is based on measurements and projections using standard <strong>IBM</strong> benchmarks in a controlled<br />

environment. The actual throughput or per<strong>for</strong>mance that any user will experience will vary depending upon considerations such as the amount of multiprogramming in<br />

the user’s job stream, the I/O configuration, the storage configuration, and the workload processed. There<strong>for</strong>e, no assurance can be given that an individual user will<br />

achieve throughput or per<strong>for</strong>mance improvements equivalent to the numbers stated here.<br />

©2005<strong>IBM</strong>C ti


4.12.1 Unicode IFCIDs<br />

In this section we describe the significant enhancements to <strong>DB2</strong> instrumentation in V8,<br />

paying special attention to the new IFCIDs that provide detailed in<strong>for</strong>mation to help you<br />

monitor and tune your <strong>DB2</strong> environment.<br />

<strong>DB2</strong> V8 introduces a new DSNZPARM parameter, UIFCIDS, which governs whether output<br />

from IFC records should include Unicode in<strong>for</strong>mation.<br />

<strong>DB2</strong> V8 supports a Unicode catalog and long names, also in Unicode. This means that <strong>DB2</strong><br />

object names, <strong>for</strong> example table names, can be longer than be<strong>for</strong>e and use “special” Unicode<br />

characters. Normally the various <strong>DB2</strong> identifiers that are externalized in IFCID records are<br />

converted to EBCDIC. This is done to make it easier <strong>for</strong> applications that read IFCID records,<br />

like online monitors, to provide “toleration support” <strong>for</strong> <strong>DB2</strong> V8.<br />

Only a subset of the character fields is encoded in Unicode. The remaining fields maintain the<br />

same encoding of previous releases, EBCDIC. The fields that can be written as Unicode are<br />

identified in the IFCID record in the DSNDQWxx mapping macros which are shipped in the<br />

SDSNMACS dataset. Each field is identified by a %U in the comment area to the right of the<br />

field declaration.<br />

All of the in<strong>for</strong>mation that is presented in the IFCID records in Unicode are stored in Unicode<br />

in memory. If you choose to have your IFCID records continue to contain only EBCDIC data,<br />

each of those data elements must be converted to EBCDIC from Unicode. See 4.7, “Unicode”<br />

on page 174 <strong>for</strong> more in<strong>for</strong>mation.<br />

4.12.2 Statistics enhancements<br />

In this section we discuss the IFC enhancements related to storage trace records that can be<br />

obtained through the statistics trace.<br />

Enhanced DBM1 and z/<strong>OS</strong> storage usage reports<br />

Additional fields were added to storage-related IFCIDs 225 and 217 <strong>for</strong> 64-bit addressing.<br />

Sample <strong>DB2</strong> Per<strong>for</strong>mance Expert (PE) statistics trace reports, showing the IFCID 225 record,<br />

are discussed in more detail in 4.2, “Virtual storage constraint relief” on page 139. IFCID 217<br />

has more detailed in<strong>for</strong>mation, but is normally only used under the guidance of the <strong>IBM</strong><br />

Support team, so it is not discussed in more detail in this publication.<br />

In addition, IFCID 225 and 217 have been added to monitor class 1 and are available via IFI<br />

READS requests.<br />

Additional high water mark counters in statistics records<br />

<strong>DB2</strong> V8 adds the following high water mark counters to the statistics record, which should<br />

assist you in more accurately setting the appropriate DSNZPARM parameters:<br />

► Q3STHWIB - High water mark <strong>for</strong> IDBACK, the number of background connections<br />

► Q3STHWIF - High water mark <strong>for</strong> IDFORE, the number of <strong>for</strong>eground connections<br />

► Q3STHWCT - High water mark <strong>for</strong> CTHREAD, the number of active threads<br />

These fields are also reported in <strong>DB2</strong> Per<strong>for</strong>mance Expert (<strong>DB2</strong> PE) statistics reports, in the<br />

Subsystem Services section, as shown in Example 4-4.<br />

Example 4-4 <strong>DB2</strong> PE enhanced subsystem services reporting<br />

SUBSYSTEM SERVICES QUANTITY /SECOND /THREAD /COMMIT<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 205


--------------------------- -------- ------- ------- -------<br />

IDENTIFY 0 0.00 0.00 0.00<br />

CREATE THREAD 2 261.75 1.00 1.00<br />

SIGNON 0 0.00 0.00 0.00<br />

TERMINATE 2 261.75 1.00 1.00<br />

ROLLBACK 0 0.00 0.00 0.00<br />

COMMIT PHASE 1 0 0.00 0.00 0.00<br />

COMMIT PHASE 2 0 0.00 0.00 0.00<br />

READ ONLY COMMIT 0 0.00 0.00 0.00<br />

UNITS OF RECOVERY INDOUBT 0 0.00 0.00 0.00<br />

UNITS OF REC.INDBT RESOLVED 0 0.00 0.00 0.00<br />

SYNCHS(SINGLE PHASE COMMIT) 2 261.75 1.00 1.00<br />

QUEUED AT CREATE THREAD 0 0.00 0.00 0.00<br />

SUBSYSTEM ALLIED MEMORY EOT 0 0.00 0.00 0.00<br />

SUBSYSTEM ALLIED MEMORY EOM 0 0.00 0.00 0.00<br />

SYSTEM EVENT CHECKPOINT 0 0.00 0.00 0.00<br />

HIGH WATER MARK IDBACK 1 130.87 0.50 0.50<br />

HIGH WATER MARK IDFORE 1 130.87 0.50 0.50<br />

HIGH WATER MARK CTHREAD 1 130.87 0.50 0.50<br />

In addition, the high water mark <strong>for</strong> MAXDBAT and CONDBAT are listed in the enhanced <strong>DB2</strong><br />

PE Statistics reports, under the DRDA Remote Locations section.<br />

Package in<strong>for</strong>mation added to deadlock trace records<br />

When a deadlock (IFCID 172) occurs, <strong>DB2</strong> now adds package and DBRM related in<strong>for</strong>mation<br />

about the holder and blocker that allows you to identify the culprit and victims more easily. The<br />

following in<strong>for</strong>mation is added <strong>for</strong> both the blockers and holders of the locks involved in the<br />

deadlock:<br />

► Location name<br />

► Collection name<br />

► Program or package name<br />

► Consistency token<br />

This in<strong>for</strong>mation is also available from <strong>DB2</strong> PE, as shown in Example 4-5.<br />

Example 4-5 Enhances deadlock trace record<br />

LOCATION: PMO<strong>DB2</strong>A <strong>DB2</strong> PERFORMANCE EXPERT (V2) PAGE: 1-3<br />

GROUP: N/A RECORD TRACE - LONG REQUESTED FROM: NOT SPECIFIED<br />

MEMBER: N/A TO: NOT SPECIFIED<br />

SUBSYSTEM: SDA1 ACTUAL FROM: 04/16/04 09:53:59.42<br />

<strong>DB2</strong> VERSION: V8 PAGE DATE: 04/16/04<br />

PRIMAUTH CONNECT INSTANCE END_USER WS_NAME TRANSACT<br />

ORIGAUTH CORRNAME CONNTYPE RECORD TIME DESTNO ACE IFC DESCRIPTION DATA<br />

PLANNAME CORRNMBR TCB CPU TIME ID<br />

-------- -------- ----------- ----------------- ------ --- --- -------------- ------------------------------------------------------<br />

N/P N/P 00BB46094741 N/P N/P N/P<br />

N/P N/P 'BLANK' 09:53:59.43270268 103075 3 172 DEADLOCK DATA NETWORKID: G998C442 LUNAME: HF05 LUWSEQ: 1<br />

N/P N/P N/P<br />

|-------------------------------------------------------------------------------------------------------------------------<br />

| DEADLOCK HEADER<br />

|INTERVAL COUNT: 152949 WAITERS INVOLVED: 2 TIME DETECTED: 04/16/04 09:53:59.424504<br />

|.........................................................................................................................<br />

| UNIT OF WORK<br />

| R E S O U R C E<br />

|LOCK RES TYPE: PAGESET LOCK DBID: DSNDB06 OBID: SYSDBASE<br />

|LOCK HASH VALUE: X'00000906'<br />

| B L O C K E R<br />

206 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


|PRIMAUTH : AND PLAN NAME : DISTSERV CORR ID : javaw.exe CONN ID : SERVER<br />

|NETWORKID : G998C442 LUNAME : HF05 OWNING WORK UNIT: 223 UNIQUENESS VALUE: X'00BB46094741'<br />

|MEMBER : SDA1 DURATION : COMMIT STATE : INTENT EXCLUSIVE ACE : 3<br />

|TRANSACTION : javaw.exe WS_NAME : B55Z5WH0 END_USER: and<br />

|PROGRAM NAME: SYSSH200 LOCATION : 'BLANK' PCKG/COLL ID: NULLID<br />

|CONS TOKEN : X'5359534C564C3031'<br />

|STATUS : HOLD<br />

|QW0172HF: X'12'<br />

| W A I T E R<br />

|PRIMAUTH : CHM PLAN NAME : DSNESPRR CORR ID : CHM CONN ID : TSO<br />

|NETWORKID : DE<strong>IBM</strong>IPS LUNAME : IPSASDA1 OWNING WORK UNIT: 132 UNIQUENESS VALUE: X'BB13C6E7AD25'<br />

|MEMBER : SDA1 DURATION : COMMIT STATE : SHARED INTENT EXCLUSIVACE : 2<br />

|TRANSACTION : 'BLANK' WS_NAME : 'BLANK' END_USER: 'BLANK'<br />

|PROGRAM NAME: DSNESM68 LOCATION : 'BLANK' PCKG/COLL ID: DSNESPRR<br />

|CONS TOKEN : X'149EEA901A79FE48'<br />

|<strong>DB2</strong>S ASIC : 5008 REQ WORK UNIT: 132 EB PTR : X'206F8540' REQ FUNCTION: CHANGE<br />

|WORTH : X'12' QW0172WG: X'32'<br />

|<br />

| R E S O U R C E<br />

|LOCK RES TYPE: DATA BASE LOCK DBID: DSNDB04 OBID: 0<br />

|LOCK HASH VALUE: X'00000080'<br />

| B L O C K E R<br />

|PRIMAUTH : CHM PLAN NAME : DSNESPRR CORR ID : CHM CONN ID : TSO<br />

|NETWORKID : DE<strong>IBM</strong>IPS LUNAME : IPSASDA1 OWNING WORK UNIT: 132 UNIQUENESS VALUE: X'BB13C6E7AD25'<br />

|MEMBER : SDA1 DURATION : COMMIT STATE : EXCLUSIVE ACE : 2<br />

|TRANSACTION : 'BLANK' WS_NAME : 'BLANK' END_USER: 'BLANK'<br />

|PROGRAM NAME: DSNESM68 LOCATION : 'BLANK' PCKG/COLL ID: DSNESPRR<br />

|CONS TOKEN : X'149EEA901A79FE48'<br />

|STATUS : HOLD<br />

|QW0172HF: X'10'<br />

| W A I T E R<br />

|PRIMAUTH : AND PLAN NAME : DISTSERV CORR ID : javaw.exe CONN ID : SERVER<br />

|NETWORKID : G998C442 LUNAME : HF05 OWNING WORK UNIT: 223 UNIQUENESS VALUE: X'00BB46094741'<br />

|MEMBER : SDA1 DURATION : COMMIT STATE : EXCLUSIVE ACE : 3<br />

|TRANSACTION : javaw.exe WS_NAME : B55Z5WH0 END_USER: and<br />

|PROGRAM NAME: SYSSH200 LOCATION : 'BLANK' PCKG/COLL ID: NULLID<br />

|CONS TOKEN : X'5359534C564C3031'<br />

|<strong>DB2</strong>S ASIC : 5008 REQ WORK UNIT: 223 EB PTR : X'2027DFB8' REQ FUNCTION: LOCK<br />

|WORTH : X'11' QW0172WG: X'30'<br />

|-------------------------------------------------------------------------------------------------------------------------<br />

Detecting long-running readers<br />

<strong>DB2</strong> V8 introduces a new DSNZPARM, LRDRTHLD, as a threshold value in number of<br />

minutes an application can hold a read claim against an object be<strong>for</strong>e notification. You can set<br />

this value in order to be able to detect long-running readers. If statistics class 3 is active, an<br />

additional field type in IFCID 313 is recorded.<br />

4.12.3 Lock escalation IFCID 337<br />

Many installations go to great lengths to avoid or minimize lock escalation. However, <strong>DB2</strong> V7<br />

does not produce an IFCID record when lock escalation occurs, thus making it difficult <strong>for</strong><br />

per<strong>for</strong>mance monitors to report on lock escalation. You can trap console message DSNI031I<br />

today. It is produced whenever lock escalation occurs. However, per<strong>for</strong>mance monitors prefer<br />

a single interface <strong>for</strong> all per<strong>for</strong>mance-related in<strong>for</strong>mation through the <strong>DB2</strong> Instrumentation<br />

Facility Component.<br />

<strong>DB2</strong> V8 introduces a new IFCID 337 to report on lock escalations. IFCID 337 is added to the<br />

statistics trace class 3 and per<strong>for</strong>mance trace class 6. If activated, IFCID 337 is written<br />

whenever lock escalation occurs. The record contains a superset of the in<strong>for</strong>mation that is<br />

reported in message DSNI031I. Refer to Appendix C of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8:<br />

Everything You Ever Wanted to Know, ... and More, SG24-6079, <strong>for</strong> a more detailed<br />

discussion of IFCID 337, or member DSNWMGSG in <strong>DB2</strong> V8 SDSNSAMP <strong>for</strong> a description<br />

of its contents.<br />

In addition, message DSNI031I is enhanced to include the collection ID in order to be<br />

consistent with IFCID 337.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 207


This message is completed with the COLLECTION-ID if available, see Example 4-6.<br />

Example 4-6 DSNI031I - Lock escalation<br />

DSNI031I -D8F1 DSNILKES - LOCK ESCALATION HAS<br />

OCCURRED FOR<br />

RESOURCE NAME = DSNDB04.SSECQTY0<br />

LOCK STATE = X<br />

PLAN NAME : PACKAGE NAME = DSNESPCS : DSNESM68<br />

COLLECTION-ID = DSNESPCS<br />

STATEMENT NUMBER = 000063<br />

CORRELATION-ID = PAOLOR6<br />

CONNECTION-ID = TSO<br />

LUW-ID = US<strong>IBM</strong>SC.SCPD8F1.BC1C562B4800<br />

THREAD-INFO = PAOLOR6 : * : *<br />

4.12.4 Accounting enhancements<br />

In addition to reducing the overhead of collecting class 2 and class 3 accounting in<strong>for</strong>mation,<br />

a number of other enhancements have also been made to the accounting trace records.<br />

Accounting roll-up <strong>for</strong> DDF and RRSAF threads<br />

To avoid flooding the system with accounting records, <strong>DB2</strong> V8 allows applications coming into<br />

<strong>DB2</strong> through DDF or RRS to roll up the accounting in<strong>for</strong>mation of individual “transactions” into<br />

a single record that is written out at a user-defined interval.<br />

Package level accounting<br />

<strong>DB2</strong> V8 adds SQL, buffer pool, and locking counters to package level accounting. As be<strong>for</strong>e,<br />

the gathering of package level accounting level in<strong>for</strong>mation is triggered by activating<br />

accounting trace classes 7 and 8. This is especially important <strong>for</strong> applications that come in<br />

through the network via DRDA, since they only execute packages, not plans, and they<br />

produce a large amount of accounting-related in<strong>for</strong>mation.<br />

The new SQL counters collected at the package level are:<br />

► The number of SELECT statements<br />

► The number of INSERT statements<br />

► The number of UPDATE statements<br />

► The number of DELETE statements<br />

► The number of DESCRIBE statements<br />

► The number of PREPARE statements<br />

► The number of OPEN statements<br />

► The number of CL<strong>OS</strong>E statements<br />

► The number of FETCH statements<br />

► The number of LOCK TABLE statements<br />

► The number of SQL CALL statements<br />

The buffer pool counters at the package level are identical to those you have in today’s plan<br />

level accounting record. However, there is only one section <strong>for</strong> all buffer pools used by the<br />

package. For example, if the package did 5 getpages <strong>for</strong> objects in BP1 and 9 getpages <strong>for</strong><br />

objects in BP2, in the package level buffer pool section, you find 14 getpages.<br />

Note, however, that adding up the numbers in the buffer pool sections of all packages touched<br />

by a plan, may not add up to the same number that is shown at the plan level. This can be the<br />

case because <strong>DB2</strong> does some work while the plan is running but be<strong>for</strong>e the package is<br />

208 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


invoked; <strong>for</strong> example, the loading of the package into the EDM pool, or work that is done via<br />

DBRMs in the plan that do not have a package.<br />

The locking in<strong>for</strong>mation at the package level is identical to the in<strong>for</strong>mation you have in today’s<br />

plan level accounting record.<br />

Note: In V8, package-related accounting in<strong>for</strong>mation is always stored in IFCID 239 and no<br />

longer stored as part of IFCID 3 (plan level accounting).<br />

Writing accounting records with KEEPDYNAMIC(YES)<br />

If the <strong>DB2</strong> DSNZPARM parameter CMTSTAT is set to INACTIVE (new default <strong>for</strong> <strong>DB2</strong> V8),<br />

<strong>DB2</strong> writes an accounting record when a transaction commits and the connection qualifies to<br />

become inactive. However, when using the KEEPDYNAMIC(YES) bind option, <strong>DB2</strong> cannot<br />

disconnect the connection from the thread (which happens when the connection becomes<br />

inactive), because the thread contains in<strong>for</strong>mation about locally cached statements.<br />

There<strong>for</strong>e DDF threads always have to remain active when using KEEPDYNAMIC(YES). As a<br />

consequence accounting records are not cut at transaction boundaries. Likewise, DDF does<br />

not reestablish WLM enclaves at transaction boundaries.<br />

Although KEEPDYNAMIC(YES) still prevents DDF threads from becoming inactive in <strong>DB2</strong><br />

V8, using KEEPDYNAMIC(YES) still allows <strong>DB2</strong> to cut accounting records at transaction<br />

boundaries. When a new request arrives from the client system over the connection (that is<br />

still active), a new enclave is created and a new accounting interval is started.<br />

At commit time, when <strong>DB2</strong> evaluates whether a DDF connection is eligible <strong>for</strong> inactivation, if<br />

the only reason why it cannot become inactive is the presence of cached dynamic SQL<br />

statements due to KEEPDYNAMIC(YES), DDF still cuts an accounting record, and also<br />

completes the WLM enclave (as if KEEPDYNAMYIC(YES) were not specified). As in V7, the<br />

presence of held cursors or declared temporary tables keeps the thread active and does not<br />

allow accounting intervals or WLM enclaves to complete.<br />

With this new behavior, you may now consider period-based WLM goals <strong>for</strong> threads that<br />

commit frequently, but cannot become inactive only because they use KEEPDYNAMIC(YES).<br />

Threads that cannot become inactive <strong>for</strong> other reasons do not reset the WLM enclave, and<br />

period-based goals are probably not right <strong>for</strong> them (which was the case in the past).<br />

4.12.5 SQLCODE -905 new IFCID 173<br />

The current method of monitoring dynamic SQL statements that exceeded the resource limit<br />

facility (RLF) ASUTIME time limit is inadequate. It does not provide the DBA with in<strong>for</strong>mation<br />

at the system level.<br />

Description<br />

Currently <strong>DB2</strong> issues an SQLCODE -905 <strong>for</strong> the dynamic SQL statement which exceeds the<br />

ASUTIME time limit set by the DBA. This is inadequate <strong>for</strong> the DBA to identify and act on it if<br />

this is a recurring problem.<br />

A new IFCID 173 trace record is written whenever a SQLCODE -905 is issued. For a<br />

distributed system, IFCID 173 is issued at the site that the -905 error is issued except <strong>for</strong> a<br />

statement that references a remote table with a three part name, then the IFCID 173 can be<br />

issued at both the server and the requester.<br />

This new IFCID 173 trace record is contained in trace type STAT CLASS(4) and PERFM<br />

CLASS(3).<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 209


This enhancement is introduced by PTFs UQ90755 (<strong>DB2</strong> V7) and UQ90756 (<strong>DB2</strong> V8) <strong>for</strong><br />

APAR PQ87848.<br />

IFCID 173 DSECT<br />

Example 4-7 shows the DSECT <strong>for</strong> the new IFCID 173.<br />

Example 4-7 IFCID 173 DSECT<br />

QW0173 DSECT<br />

QW0173ID DS CL8 %U AUTH ID<br />

QW0173PC DS CL18 %U PACKAGE COLLECTION ID<br />

QW0173PK DS CL8 %U PACKAGE NAME<br />

QW0173PL DS CL8 PLAN NAME<br />

QW0173CN DS CL18 %U CURSOR NAME if it exists<br />

QW0173UT DS F (S) Time used so far<br />

QW0173AT DS F (S) User ASUTIME<br />

QW0173SN DS H SECTION NUMBER<br />

DS CL2 Reserved<br />

QW0173ST DS F STATEMENT NUMBER<br />

QW0173CS DS XL4 cached statement ID, or zero<br />

QW0173DI DS CL128 (S) RLF Diagnostic in<strong>for</strong>mation area<br />

*<br />

QW0173ID_Off DS H Offset from QW0173 to<br />

* AUTH ID<br />

* If QW0173ID truncated<br />

QW0173PC_Off DS H Offset from QW0173 to<br />

* PACKAGE COLLECTION ID<br />

* If QW0173PC truncated<br />

QW0173PK_Off DS H Offset from QW0173 to<br />

* PACKAGE NAME<br />

* If QW0173PK truncated<br />

QW0173CN_Off DS H Offset from QW0173 to<br />

* CURSOR NAME if it exist<br />

* If QW0173CN truncated<br />

*<br />

QW0173ID_D Dsect Use if QW0173ID_Off^=0<br />

QW0173ID_Len DS H Length of the following field<br />

QW0173ID_Var DS 0CL128 %U AUTH ID<br />

*<br />

QW0173PC_D Dsect Use if QW0173PC_Off^=0<br />

QW0173PC_Len DS H Length of the following field<br />

QW0173PC_Var DS 0CL128 %U PACKAGE COLLECTION ID<br />

*<br />

QW0173PK_D Dsect Use if QW0173PK_Off^=0<br />

QW0173PK_Len DS H Length of the following field<br />

QW0173PK_Var DS 0CL128 %U PACKAGE NAME<br />

*<br />

QW0173CN_D Dsect Use if QW0173CN_Off^=0<br />

QW0173CN_Len DS H Length of the following field<br />

QW0173CN_Var DS 0CL128 %U CURSOR NAME if it exist<br />

4.12.6 Per<strong>for</strong>mance trace enhancements<br />

In this section we discuss enhancements to IFCIDs that are related to <strong>DB2</strong> per<strong>for</strong>mance trace<br />

classes.<br />

210 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Full SQL statement text trace record<br />

<strong>DB2</strong> V8 provides a new IFCID 350, which is both similar and in addition to IFCID 63, which<br />

traces the entire SQL statement. Previous versions of <strong>DB2</strong> limited the SQL statement text to a<br />

maximum of 5,000 bytes (the maximum length of a trace field).<br />

Since there is a 5,000 byte limit on a single data item being traced, a “repeating group" of<br />

5,000 byte items are placed in each IFCID 350 record up to a maximum of 6. If that is not<br />

enough, multiple IFCID 350 records are produced. IFCID 350 is written under the same<br />

circumstances that trigger the writing of IFCID 63. PREPARE attributes are also traced.<br />

Enhanced trace recording <strong>for</strong> PREPARE attribute<br />

Since <strong>DB2</strong> V7, you can change the attributes of a cursor or SELECT statement on the<br />

PREPARE statement. To do so, you use the ATTRIBITES clause on the PREPARE. For<br />

example, it allows you to change a cursor’s isolation level by providing a new attribute string.<br />

However, in V7 the attribute string is not always present in IFCID records, which makes<br />

problem determination and per<strong>for</strong>mance analysis more complex.<br />

<strong>DB2</strong> V8 adds the attribute string to the following trace records:<br />

► IFCID 63: (which contains the first 5,000 bytes of the SQL statement text) now also<br />

contains the attribute string on a short prepare.<br />

► IFCID 124: (which is used to obtain in<strong>for</strong>mation about the currently executing SQL<br />

statement through a READS request) now also contains the attributes string.<br />

► IFCID 317: (which is used to retrieve the SQL statement string of a statement in the<br />

dynamic statement cache) now also contains the attributes string.<br />

Add cached statement ID to IFCID 124<br />

IFCID 124 provides in<strong>for</strong>mation about the currently executing SQL statement through the<br />

READS interface. <strong>DB2</strong> V8 enhances IFCID 124 to also include the dynamic cached SQL<br />

statement ID. The 4 byte field QW0124ST was added to contain the cached dynamic SQL<br />

statement identifier.<br />

This enhancement works together with another enhancement in <strong>DB2</strong> V8 that allows you to<br />

Explain SQL statements from the dynamic statement cache. You can retrieve the in<strong>for</strong>mation<br />

about the currently executing SQL statement via IFCID 124. That now contains the SQL<br />

statement ID of the statement in the dynamic statement cache, and then explains the SQL<br />

statement from the dynamic statement cache using that statement ID.<br />

For more in<strong>for</strong>mation on how to explain a statement from the dynamic statement cache, see<br />

section 4.20, “EXPLAIN STMTCACHE” in the book <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything<br />

You Ever Wanted to Know, ... and More, SG24-6079.<br />

Agent level workfile tracing<br />

<strong>DB2</strong> V8 introduces a new IFCID 342 to record workfile and TEMP database usage at an<br />

application level. This allows you to take corrective action, such as adding space or cancelling<br />

a runaway query that is using a lot of space in the databases and preventing other queries<br />

from running successfully even they only need very little space.<br />

When active, IFCID 342 is written whenever space is allocated or deallocated in the workfile<br />

or TEMP database. It gives in<strong>for</strong>mation about the total amount of space being used by the<br />

agent currently and the maximum space that the agent may have used at any given point in<br />

time in the workfile or TEMP database. The trace also records the total amount of space<br />

being used <strong>for</strong> indexes on Declared Temporary Tables.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 211


This record is activated by:<br />

-START TRACE(PERFM) CLASS(32) IFCID(342)<br />

Monitors, <strong>for</strong> example, can trigger exceptions on this new IFCID to catch runaway queries<br />

be<strong>for</strong>e they monopolize the system and cause other applications to fail, because the workfile<br />

database and TEMP database are shared amongst all <strong>DB2</strong> users.<br />

Obtaining secondary authorization ID in<strong>for</strong>mation<br />

This enhancement allows applications to obtain the authorization identifiers that are<br />

associated with an application (such as QMF) that is executing. The primary authorization ID,<br />

the CURRENT SQLID, and secondary authorization IDs can be retrieved with a synchronous<br />

read of IFCID 234. This enhancement is also available in <strong>DB2</strong> V6 and V7 via APAR PQ47973,<br />

PTF UQ57178 <strong>for</strong> V7 and PTF UQ57177 <strong>for</strong> V8.<br />

Note however that IFCID 234 is always started implicitly by <strong>DB2</strong> at startup time. It is not<br />

contained in any <strong>DB2</strong> trace class and cannot be specified as an IFCID value on the -START<br />

TRACE command.<br />

Auditing <strong>for</strong> multilevel security<br />

Audit record (IFCID 142) is produced if a table with a security label is created, altered or<br />

dropped.<br />

The user must be identified to Security Server with a valid SECLABEL. If not, an authorization<br />

error and audit record are produced (IFCID 140).<br />

4.12.7 Miscellaneous trace enhancements<br />

In this section we discuss other enhancements to monitoring, such as new <strong>DB2</strong> messages.<br />

Monitor system checkpoints and log offload activity<br />

<strong>DB2</strong> V8 provides new messages, as well as an IFCID 335 record, to help you to identify<br />

problems with log offloading faster. An IFCID 335 record is produced if the statistics class 3<br />

trace is active. See “Monitoring system checkpoints and log offload activity” in <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong><br />

z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever Wanted to Know, ... and More, SG24-6079, <strong>for</strong> more<br />

in<strong>for</strong>mation about the console messages that are produced.<br />

This enhancement helps you identify potential problems with <strong>DB2</strong> logging be<strong>for</strong>e they<br />

become real problems which may cause application outages. For example, when <strong>DB2</strong> stops<br />

taking system checkpoints or gets stuck during its log offload activity, the system grinds to a<br />

halt.<br />

4.13 Miscellaneous items<br />

In this section we introduce miscellaneous enhancements which also impact <strong>DB2</strong> subsystem<br />

availability, per<strong>for</strong>mance and scalability.<br />

4.13.1 <strong>DB2</strong> logging enhancements<br />

As the throughput of a single <strong>DB2</strong> subsystem increases, the amount of data <strong>DB2</strong> must log<br />

also increases. Keeping the <strong>DB2</strong> logging data available and online is very important, as it<br />

dramatically speeds up <strong>DB2</strong> recovery and maximizes data availability.<br />

212 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


<strong>DB2</strong> V8 in new-function mode increases the number of active log data sets from 31 to 93,<br />

allowing <strong>DB2</strong> to keep more log data online and there<strong>for</strong>e available <strong>for</strong> any recovery.<br />

In addition, <strong>DB2</strong> V8 in new-function mode increases the number of archive log data sets <strong>DB2</strong><br />

remembers from 1,000 to 10,000. This increases the amount of log data <strong>DB2</strong> is able to<br />

access and use in recovery, there<strong>for</strong>e satisfying the larger window often required by Service<br />

Level Agreements (SLA).<br />

4.13.2 Up to 65,041 open data sets<br />

<strong>DB2</strong> V8 increases the number of open data sets from 32k to 65,041. This enhancement is<br />

available starting with z/<strong>OS</strong> V1.5 base code.<br />

Open data sets require storage <strong>for</strong> MVS control blocks below the 16 MB line. This has been<br />

the cause of virtual storage constraint problems below the 16 MB line in the past. Dynamic<br />

allocations can request these control blocks to be allocated above the 16 MB line. With z/<strong>OS</strong><br />

V1.5, media manager, the interface that <strong>DB2</strong> uses, can fully exploit this feature. This reduces<br />

the amount of storage that <strong>DB2</strong> requires below the 16 MB line.<br />

This enhancement does not only provide virtual storage relief. It also removes a potential<br />

scalability problem with growing systems and growing machine capacity.<br />

In addition, <strong>DB2</strong> V8 no longer uses system-generated DDNAMEs, as the current limit there is<br />

also 32k. <strong>DB2</strong> generates its own DDNAMEs <strong>for</strong> dynamic allocation. This way <strong>DB2</strong> can have<br />

better open data set per<strong>for</strong>mance as well, and, can avoid the problem of the task that<br />

generates the system DDNAMEs becoming a bottleneck <strong>for</strong> parallel data set open.<br />

When DSMAX is reached, <strong>DB2</strong> currently attempts to close up to 3% of the open data sets.<br />

However, 3% of 65,041 is still a large number, and this burst of data set close activity could be<br />

disruptive. There<strong>for</strong>e <strong>DB2</strong> now closes MIN(3%,300) data sets when DSMAX is reached.<br />

PFT UQ96862 <strong>for</strong> APAR PQ96189 is related to the number of open data sets.<br />

4.13.3 SMF type 89 record collection enhancements<br />

SMF type 89-1 interval records provide <strong>IBM</strong> with the required “Software Usage Report” <strong>for</strong><br />

reporting on zSeries Software License Requirements.<br />

Prior to V8, <strong>DB2</strong> automatically used detailed tracking of measured usage if SMF type 89<br />

records were activated.<br />

<strong>DB2</strong> V8 provides a new DSNZPARM parameter, SMF89, which lets you specify whether <strong>DB2</strong><br />

is to do detailed tracking <strong>for</strong> measured usage pricing. The default value is NO, which means<br />

that <strong>DB2</strong> does not do detailed measured usage tracking. If the SMF type 89 record is<br />

activated, only high-level tracking is recorded in the SMF type 89 record.<br />

If you select YES, <strong>DB2</strong> does detailed measured usage tracking if SMF type 89 records are<br />

activated. When SMF89 is set to YES, <strong>DB2</strong> invokes a z/<strong>OS</strong> service on every entry or exit into<br />

or out of <strong>DB2</strong> to ensure accurate tracking. A new SMF type 89 record is cut on each SQL<br />

statement.<br />

If you select NO, <strong>DB2</strong> CPU is reduced; however, the amount of time spent in <strong>DB2</strong> as<br />

measured by SMF 89 is increased.<br />

A "typical" CPU overhead <strong>for</strong> <strong>DB2</strong> per<strong>for</strong>ming detailed tracking of CPU usage is in the range<br />

of 0 to 5%. Since there is a fixed overhead per SQL statement, the overhead tends to be<br />

higher <strong>for</strong> short-running SQL statements and negligible <strong>for</strong> long-running SQL statements. For<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 213


an online transaction with very simple SQL statements each accessing and retrieving one<br />

row, the overhead can be about 1% if there is no other transaction running. On the other<br />

hand, if there are many concurrent transactions, we have heard of up to 15% overhead. A<br />

20% figure is <strong>for</strong> a projected maximum number <strong>for</strong> 32-way complex with many concurrent<br />

threads.<br />

In <strong>DB2</strong> V8, the overhead is thought to be completely negligible as there is no longer SMF 89<br />

data collection <strong>for</strong> each SQL statement.<br />

We there<strong>for</strong>e recommend you select SMF89 YES only if you use measured usage pricing.<br />

4.13.4 Lock avoidance enhancements<br />

We briefly describe the main lock avoidance enhancements.<br />

Overflow lock avoidance<br />

Sometimes when you update a variable length row, <strong>DB2</strong> is not able to store the row on the<br />

original page. This happens when the size of the row has increased and it no longer fits on its<br />

original page. In order to avoid updating all the indexes that point to that row (each index entry<br />

contains a RID, which contains the original page number), a pointer record is created on the<br />

original page. The pointer record then points to the actual row. If a later update of the row<br />

decreases its size, it can be put back into its original page, again without any updates to the<br />

index.<br />

You can have variable length rows when:<br />

► Using variable length columns like VARCHAR and VARGRAPHIC<br />

► Using <strong>DB2</strong> data compression<br />

► Altering a table to add a column, but you have not per<strong>for</strong>med a REORG to materialize all<br />

the rows to have the new column<br />

► Using the new V8 online schema enhancements to enlarge the a columns data type, but<br />

you have not run REORG to materialize all the rows to the latest <strong>for</strong>mat<br />

The good thing about using the overflow pointer is that we avoid updating the indexes. The<br />

disadvantage is that we potentially double the number of data I/Os and getpage requests, and<br />

increase the number of lock and unlock requests. This can obviously impact per<strong>for</strong>mance.<br />

You can check whether or not overflow records exist by looking at the FARINDREF and<br />

NEARINDREF in<strong>for</strong>mation in SYS<strong>IBM</strong>.SYSTABLEPART. This in<strong>for</strong>mation is updated by<br />

running RUNSTATS and provides in<strong>for</strong>mation about the number of rows that have been<br />

relocated far from (> 16 pages) or near (< 16 pages) their “home” page. We recommend you<br />

run a REORG when (FARINDREF +NEARINDREF) exceed 5 to 10%. To reduce the amount<br />

of overflow rows, and hence the number of double I/Os, getpages, and lock and unlock<br />

requests, you can use a higher PCTFREE value (FREEPAGE does not help in this case).<br />

In V7, there is no lock avoidance on both the pointer record and the overflow record itself.<br />

With <strong>DB2</strong> <strong>Version</strong> 8, only the pointer is locked.<br />

Table 4-15 Lock avoidance of overflow record<br />

Isolation Level Cursor Stability<br />

with CURRENTDATA NO or YES<br />

214 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

V7 V8<br />

Lock and Unlock required <strong>for</strong> the pointer record YES YES<br />

Lock and Unlock required <strong>for</strong> the overflow record YES NO


In addition, with V8, PQ89070 implements lock avoidance <strong>for</strong> a singleton SELECT statement<br />

with ISOLATION(CS) and CURRENTDATA(YES). Semantically, a singleton select with<br />

ISOLATION(CS) can avoid getting an S page or row lock regardless of the setting of the<br />

CURRENTDATA parameter, since the cursor is closed after the SELECT is processed.<br />

Lock avoidance <strong>for</strong> embedded SELECT or SELECT INTO<br />

Semantically, a SELECT INTO with ISOLATION(CS) should avoid getting an S page or row<br />

lock regardless of the setting of the CURRENTDATA(CD) option since the cursor is closed<br />

after the SELECT is processed. Currently, with ISO(CS) and CD(NO) we get LOCK<br />

AVOIDANCE but not with ISO(CS) and CD(YES).<br />

If <strong>DB2</strong> can determine that the data that it is reading has already been committed, it can avoid<br />

taking the lock altogether. For rows that do not satisfy the search condition, this lock<br />

avoidance is possible with CURRENTDATA(YES) or CURRENTDATA(NO). For a row that<br />

satisfies the search condition on such a SELECT, lock avoidance is possible with<br />

CURRENTDATA(YES) or CURRENTDATA(NO). For other rows that satisfy the search<br />

condition, lock avoidance is possible only when you use the option CURRENTDATA(NO).<br />

In a test case, executing a simple select statement in a loop (100k times), we have seen up to<br />

a 25% better elapsed time in V8 when compared to the run without lock avoidance. When<br />

compared to V7, V8 is 7% better with lock avoidance.<br />

Chapter 4. <strong>DB2</strong> subsystem per<strong>for</strong>mance 215


216 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 5. Availability and capacity<br />

enhancements<br />

Continuous availability is a major business requirement. New releases of <strong>DB2</strong> keep<br />

introducing enhancements to meet this need.<br />

5<br />

<strong>DB2</strong> V8 introduces new and enhanced function in this area.<br />

► System level point-in-time recovery: V8 provides enhanced backup and recovery<br />

capabilities at the <strong>DB2</strong> subsystem level or data sharing group level. The new BACKUP<br />

SYSTEM and RESTORE SYSTEM utilities rely on the new Fast Replication services of<br />

DFSMS in z/<strong>OS</strong> V1R5.<br />

► Automated space management: This feature potentially enhances availability <strong>for</strong> many<br />

<strong>DB2</strong> installations. <strong>DB2</strong> will adjust the size of the secondary extent, when extending the<br />

data set, in such a way that the maximum allowable data set size is reached be<strong>for</strong>e the<br />

maximum number of extents, avoiding out of space conditions.<br />

► Online schema: Online schema evolution allows <strong>for</strong> table space, table and index attribute<br />

changes while minimizing impact on availability.<br />

► Volatile table: Statistics <strong>for</strong> tables which can vary greatly in size can deviate completely at<br />

runtime from values used at bind time. Per<strong>for</strong>mance can benefit from favoring index<br />

access <strong>for</strong> these types of tables.<br />

► Index changes: Data-partitioned indexes, partitioning without a partitioning index, padded<br />

and not-padded indexes enhance indexing capabilities.<br />

► More availability enhancements: Other <strong>DB2</strong> V8 availability enhancements and also<br />

recent enhancements introduced via maintenance are discussed in this section.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 217


5.1 System level point-in-time recovery<br />

Prior to <strong>DB2</strong> V8 you could make an external copy of your production system by delimiting the<br />

back up activity with the -SET LOG SUSPEND and -SET LOG RESUME commands. <strong>DB2</strong>’s update<br />

activity and logging, while you were making the external copy of your <strong>DB2</strong> system, was<br />

suspended.<br />

<strong>DB2</strong> V8 introduces the new BACKUP SYSTEM and RESTORE SYSTEM utilities. This<br />

provides an easier and less disruptive way to make fast volume-level backups of an entire<br />

<strong>DB2</strong> subsystem or data sharing group with minimal disruption, and recover a subsystem or<br />

data sharing group to any point-in-time, regardless of whether or not you have uncommitted<br />

units of work. At <strong>DB2</strong> restart, the uncommitted URs are resolved during the <strong>for</strong>ward and<br />

backward recovery phase.<br />

These new utilities rely on the new Fast Replication in DFSMS 1.5. DFSMS provides a<br />

volume-level fast replication function that allows you to create a backup that is managed by<br />

DFSMShsm with minimal application outage. DFSMShsm recovers a Fast Replication backup<br />

version from the volume or copy pool level, but not at the data set level. This function enables<br />

the backup and recovery of a large set of volumes to occur within a small time frame. The<br />

term Fast Replication refers to the FlashCopy function supported by <strong>IBM</strong> TotalStorage®<br />

Enterprise Storage Server® (ESS) disk and the SnapShot function supported by <strong>IBM</strong><br />

RAMAC® Virtual Array (RVA) disk.<br />

► The BACKUP SYSTEM utility provides fast volume-level copies (versions) of <strong>DB2</strong><br />

databases and logs.<br />

► The RESTORE SYSTEM utility recovers a <strong>DB2</strong> system to an arbitrary point-in-time.<br />

RESTORE SYSTEM automatically handles any creates, drops, and LOG NO events that<br />

might have occurred between the backup and the recovery point-in-time.<br />

Prerequisites <strong>for</strong> this feature<br />

In order to use the BACKUP SYSTEM and RESTORE SYSTEM utilities, all data sets that you<br />

want to back up and recover must be SMS-managed data sets. Additionally, you must have<br />

the following requirements:<br />

► z/<strong>OS</strong> V1R5, DFSMShsm, DFSMSdss.<br />

► Disk control units that support ESS FlashCopy API (we recommend FlashCopy V2).<br />

► SMS copy pools that are defined by using the <strong>DB2</strong> naming convention.<br />

► Defined SMS copy pool backup storage groups.<br />

► <strong>DB2</strong> has to be running in new-function mode.<br />

RESTORE SYSTEM LOGONLY option has no dependency on z/<strong>OS</strong> 1.5.<br />

A copy pool is a set of SMS-managed storage groups that can be backed up and restored<br />

with a single command.<br />

A copy pool backup is a new storage group type that is used as a container <strong>for</strong> copy pool<br />

volume copies. Each volume in the copy pool storage group needs to have a corresponding<br />

volume in the copy pool backup storage group. For each copy pool volume as many backup<br />

volumes as backup versions defined <strong>for</strong> the copy pool should be available in the copy pool<br />

backup.<br />

Each <strong>DB2</strong> system has up to two copy pools, one <strong>for</strong> databases and one <strong>for</strong> logs. The name of<br />

each copy pool that is to be used with <strong>DB2</strong> must use the following naming conventions:<br />

DSN$locn-name$cp-type<br />

The variables that are used in this naming convention have the following meanings:<br />

218 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► DSN: Unique <strong>DB2</strong> product identifier.<br />

► $: Delimiter.<br />

► locn-name: <strong>DB2</strong> location name.<br />

► cp-type: copy pool type. Use DB <strong>for</strong> the database copy pool and LG <strong>for</strong> the log copy pool.<br />

You have to set up both copy pools properly in order to successfully implement system level<br />

point-in-time recovery:<br />

The “log” copy pool should be set up to contain the volumes that contain the BSDS data sets,<br />

the active logs, and their associated ICF catalogs.<br />

The “database” copy pool should be set up to contain all the volumes that contain the<br />

databases and the associated ICF catalogs.<br />

Important: Make sure that the ICF catalog <strong>for</strong> the data is on an other volume than the ICF<br />

catalog <strong>for</strong> the logs.<br />

Three new DFSMShsm commands are introduced to support this new function, and other<br />

commands are changed to provide new in<strong>for</strong>mation related to the DFSMShsm Fast<br />

Replication function:<br />

► FRBACKUP: Create a fast replication backup version <strong>for</strong> each volume in a specified copy<br />

pool.<br />

► FRRECOV: Use fast replication to recover a single volume or a pool of volumes from the<br />

managed backup versions<br />

► FRDELETE: Delete one or more unneeded fast replication backup versions.<br />

LIST and QUERY commands are modified to aid monitoring of the fast replication backup<br />

versions.<br />

Prepare <strong>for</strong> fast replication<br />

After establishing the copy pools, the storage administrator issues FRBACKUP PREPARE<br />

against each copy pool. The PREPARE allows you to validate your fast replication<br />

environment <strong>for</strong> DFSMShsm. DFSMShsm preassigns the required number of target volumes<br />

to each source volume in each storage group in the specified copy pool. When you specify<br />

the PREPARE keyword, DFSMShsm verifies that there is a sufficient number of eligible target<br />

volumes in the specified copy pool backup storage group.<br />

For instance, if you specified in the copy pool definition that DFSMShsm should keep two<br />

backup versions, then DFSMShsm preassigns two target volumes to each source volume in<br />

the copy pool.<br />

You should use the PREPARE keyword whenever there is a change in the fast replication<br />

environment. Changing any of the following definitions will change the fast replication<br />

environment:<br />

► The volumes in the copy pool or copy pool backup storage groups are changed or<br />

removed.<br />

► The number of backup versions <strong>for</strong> DFSMShsm to maintain is changed.<br />

► The storage groups defined to the copy pool have changed.<br />

Important: It is recommended to run the PREPARE after each copy pool assignment since<br />

it removes the time <strong>for</strong> target volume selection from the BACKUP execution window.<br />

Otherwise the prepare phase will be executed implicitly when the backup starts and will<br />

elongate its execution.<br />

Chapter 5. Availability and capacity enhancements 219


BACKUP SYSTEM<br />

During backup <strong>DB2</strong> records the “recovery base log point” (RBLP) in the header page of<br />

DBD01. The RBLP is identified as the most recent system checkpoint prior to a backup log<br />

point, and the point at which <strong>DB2</strong> starts scanning logs during a RESTORE SYSTEM recovery<br />

operation. <strong>DB2</strong> updates its BSDS (boot strap data set) with backup version in<strong>for</strong>mation and<br />

can keep track of up to 50 backup versions. In the case of data sharing the submitting<br />

member records the backup version in its BSDS and also in the SCA. This in<strong>for</strong>mation is also<br />

recorded in DFSMShsm control data sets.<br />

Note that in <strong>DB2</strong> V8, the SET LOG SUSPEND command also writes the RBLP to the DBD01<br />

header page.<br />

Concurrency and compatibility<br />

BACKUP SYSTEM can run concurrently with any other utility; however, it must wait <strong>for</strong> the<br />

following <strong>DB2</strong> events to complete be<strong>for</strong>e the copy can begin:<br />

► Extending data sets<br />

► Writing 32 KB pages <strong>for</strong> page sets with a VSAM CISZE that is different from the <strong>DB2</strong> page<br />

size<br />

► Writing close page set control log records<br />

► Creating data sets (<strong>for</strong> table spaces, indexes, and so <strong>for</strong>th)<br />

► Deleting data sets (<strong>for</strong> dropping tables spaces, indexes, and so <strong>for</strong>th)<br />

► Renaming data sets (<strong>for</strong> online reorganizing of table spaces, indexes, and so <strong>for</strong>th during<br />

the SWITCH phase)<br />

Only one BACKUP SYSTEM job can be running at one time.<br />

The log write latch is not obtained by the BACKUP SYSTEM utility, as is done by the SET<br />

LOG SUSPEND command. There<strong>for</strong>e, using the BACKUP SYSTEM utility should be less<br />

disruptive in most cases. There is no need to suspend logging when using the BACKUP<br />

SYSTEM utility, since <strong>DB2</strong> is now in control of taking the volume copies, where you are in<br />

charge of initiating copying the data in the case of using -SET LOG SUSPEND.<br />

RESTORE SYSTEM<br />

Use the RESTORE SYSTEM utility only when you want to recover a subsystem or data<br />

sharing group to an arbitrary point-in-time. The utility restores only the database copy pool of<br />

a data only or full system backup, and then applies logs until it reaches a point in the log equal<br />

to the log truncation point specified in a point-in-time conditional restart control record<br />

(SYSPITR CRCR) created with DSNJU003. You cannot explicitly name the backup to use <strong>for</strong><br />

recovery. That is implicitly determined by the log truncation point used to create the SYSPITR<br />

CRCR. Similar to the Recovery utility, Restore can optionally use the Fast Log Apply (FLA)<br />

option. As restore will be the only task running in <strong>DB2</strong>, we strongly advise you to enable Fast<br />

Log Apply in order to accelerate the recovery process.<br />

RESTORE SYSTEM LOGONLY can run without a BACKUP SYSTEM backup and can run<br />

with z/<strong>OS</strong> 1.3. By using this option, you indicate that the database volumes have already<br />

been restored using DFSMShsm or other means, and the restore phase will be skipped. A<br />

backup made in a SET LOG SUSPEND/RESUME cycle is required because SET LOG<br />

SUSPEND updates the RBLP in the DBD01 header page.<br />

<strong>DB2</strong> V8 Fast Log Apply behavior<br />

Fast Log Apply was introduced in <strong>DB2</strong> V6. It is activated by specifying a non-zero value <strong>for</strong><br />

the DSNZPARM parameter LOGAPSTG. The acceptable values are 0 to 100 MB with 100<br />

220 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


5.1.1 Per<strong>for</strong>mance<br />

MB as default. The FLA design consists of one log read task per recover job and one or more<br />

log apply tasks employing the use of multitasking whenever possible. It takes advantage of list<br />

prefetch and nearly eliminates duplicate synchronous read operations <strong>for</strong> the same page. It<br />

achieves these efficiencies by sorting groups of log records together that pertain to the same<br />

table space be<strong>for</strong>e applying those changes; it then applies those records in parallel using<br />

several log apply tasks, up to 99.<br />

When LOGAPSTG=0 is specified, <strong>DB2</strong> restart will still use a minimum buffer size of 100 MB<br />

<strong>for</strong> FLA during the <strong>for</strong>ward log recovery phase. RESTORE SYSTEM and RECOVER will not<br />

use FLA.<br />

When LOGAPSTG> 0 is specified then:<br />

► <strong>DB2</strong> will use that value <strong>for</strong> the FLA buffer at restart time with a default of 100 MB.<br />

► RESTORE SYSTEM will use FLA during the log apply phase. RESTORE, with APAR<br />

PQ95164, will always try to allocate a FLA buffer of 500 MB. If it cannot get the storage, it<br />

retries with 250 MB, 125 MB, and so on.<br />

► Each concurrent recover utility will use a buffer of 10 MB out of the storage defined by<br />

LOGAPSTG. If no more storage is available, the next concurrent recover utility will execute<br />

without FLA. This means that the maximum value of 100 MB <strong>for</strong> LOGAPSTG allows <strong>for</strong> 10<br />

concurrent recover utilities executing with FLA, the 11th recover will execute without FLA.<br />

For a detailed description on Point-in-Time Recovery, and other disaster recovery functions,<br />

see Disaster Recovery with <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-6370.<br />

In this section we describe the System Level point-in-time recovery per<strong>for</strong>mance<br />

measurement.<br />

Per<strong>for</strong>mance measurement description<br />

For this measurement we used:<br />

► z/<strong>OS</strong> V1R5 with DFSMS, DFSMSdss, and DFSMShsm V1R5<br />

► <strong>DB2</strong> V8<br />

► zSeries 2084 Model 316<br />

► ESS 2105-800, FlashCopy V2<br />

► Copy pool:<br />

– Database copy pool either 67 (27% full) or 195 volumes (10% full)<br />

– Log copy pool 13 volumes<br />

► Copy pool backup:<br />

– 211 volumes <strong>for</strong> the database copy pool<br />

Up to 3 versions available to the 67-volume copy pool<br />

One version only <strong>for</strong> the 195-volume copy pool<br />

– 13 volumes <strong>for</strong> the log copy pool<br />

1 version <strong>for</strong> the 13-volume log copy pool<br />

Per<strong>for</strong>mance measurement results<br />

In this section we present the System Level point-in-time recovery per<strong>for</strong>mance measurement<br />

results.<br />

FRBACKUP PREPARE measurements<br />

See Figure 5-1 <strong>for</strong> the measurement results of FRBACKUP PREPARE. The results show a<br />

non-linear behavior between elapsed time to prepare and the number of volumes in the pools.<br />

Chapter 5. Availability and capacity enhancements 221


Figure 5-1 FRBACKUP PREPARE elapsed time vs. #volumes in the copy pool<br />

Since the time to prepare the replication environment will increase with the number of<br />

volumes in the copy pool, this action should be executed be<strong>for</strong>e initiating the real backup.<br />

Figure 5-2 shows the measurement results increasing the number of versions.<br />

sec.<br />

sec.<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

200<br />

150<br />

100<br />

Figure 5-2 FRBACKUP PREPARE elapsed time vs.#versions <strong>for</strong> 67 volume copy pool<br />

Increasing the number of versions means increasing the number of target volumes, this<br />

significantly increases the time to prepare the replication environment. Again we recommend<br />

222 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

50<br />

0<br />

FRBACKUP PREPARE measurements<br />

1<br />

Elapsed Time <strong>for</strong> PREPARE<br />

8<br />

171<br />

13 67<br />

# of Vols<br />

195<br />

One <strong>Version</strong><br />

FRBACKUP PREPARE measurements…<br />

8<br />

Elapsed Time <strong>for</strong> PREPARE<br />

96<br />

265<br />

1 2 3<br />

# of <strong>Version</strong>s<br />

67-Vol


to execute the prepare outside the actual backup cycle since the time to prepare is a multiple<br />

of the time to take the actual backup.<br />

BACKUP SYSTEM measurements<br />

The BACKUP SYSTEM DATA ONLY utility invokes the command<br />

‘FRBACKUP COPYPOOL(DSN$location-name$DB) EXECUTE.<br />

See Figure 5-3 and <strong>for</strong> the measurement results.<br />

BACKUP SYSTEM DATA ONLY<br />

Invokes FRBACKUP ‘<br />

<br />

BACKUP SYSTEM measurements<br />

COPYPOOL(DSN$location-name$DB<br />

EXECUTE<br />

Figure 5-3 BACKUP SYSTEM DATA ONLY measurement<br />

The BACKUP SYSTEM FULL utility invokes the commands<br />

‘FRBACKUP COPYPOOL(DSN$location-name$DB) EXECUTE. followed by<br />

‘FRBACKUP COPYPOOL(DSN$location-name$LG) EXECUTE’<br />

See Figure 5-4 <strong>for</strong> the measurement results.<br />

sec.<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

Elapsed Time <strong>for</strong><br />

EXECUTE<br />

33<br />

63<br />

67 195<br />

# of Vols<br />

DB Pool<br />

Chapter 5. Availability and capacity enhancements 223


Figure 5-4 BACKUP SYSTEM FULL measurement<br />

If FlashCopy is the fast replication technique used, then DFSMShsm returns control to the<br />

system after a FlashCopy relationship <strong>for</strong> each volume has been established. However, the<br />

background copies <strong>for</strong> those volumes last longer, depending on the number of background<br />

copies being processed and the amount of other higher priority activity that exists in the<br />

storage subsystem.<br />

Another interesting measurement case is the concurrent execution of BACKUP SYSTEM<br />

DATA ONLY with the IRWW non-data sharing workload. See Table 5-1 <strong>for</strong> the results.<br />

Table 5-1 Concurrent execution of BACKUP SYSTEM and IRWW workload<br />

IRWW non-data sharing IRWW + BACKUP SYSTEM<br />

data only<br />

ETR (commit/sec.) 386.42 386.38<br />

CPU (%) 66.19 72.96<br />

Class 3 DB I/O related suspend<br />

time (msec.)<br />

Running the BACKUP SYSTEM utility concurrent with the IRWW workload shows no<br />

noticeable per<strong>for</strong>mance degradation. The external throughput rate (ETR) remains<br />

unchanged. CPU slightly increased but the <strong>DB2</strong> transaction CPU was not affected. The<br />

database related I/O suspend time increases but this was not reflected in the ETR due to the<br />

think time.<br />

RESTORE SYSTEM measurements<br />

The RESTORE SYSTEM utility invokes the command<br />

‘FRRECOV COPYPOOL(DSN$location-name$DB)’<br />

See Figure 5-5 <strong>for</strong> the measurement results.<br />

224 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

BACKUP SYSTEM measurements…<br />

• BACKUP SYSTEM FULL<br />

Invokes ‘FRBACKUP<br />

COPYPOOL(DSN$locationname$DB)<br />

EXECUTE’<br />

Then invokes ‘FRBACKUP<br />

COPYPOOL(DSN$locationname$LG)<br />

EXECUTE’<br />

sec.<br />

80<br />

60<br />

40<br />

20<br />

0<br />

Elapsed Time <strong>for</strong><br />

EXECUTE<br />

50<br />

76<br />

80 208<br />

# of Vols<br />

14.40 19.17<br />

DB & LG<br />

Pools


RESTORE SYSTEM measurements<br />

• RESTORE SYSTEM<br />

Invokes ‘FRRECOV<br />

COPYPOOL(DSN$location-name$DB)'<br />

Followed by LOGAPPLY phase<br />

• RESTORE SYSTEM<br />

LOGONLY<br />

Enters LOGAPPLY phase<br />

directly<br />

Figure 5-5 RESTORE SYSTEM measurement<br />

Remember that RESTORE SYSTEM only restores the database copy pool. The logs are<br />

applied after that restore.<br />

Make sure all of the background copies have completed from an invocation of the BACKUP<br />

SYSTEM utility be<strong>for</strong>e starting the restore utility.<br />

The log apply per<strong>for</strong>mance can be improved by activating fast log apply (FLA).<br />

Table 5-2 presents the log apply phase measurement results.<br />

Table 5-2 LOGAPPLY phase measurement<br />

IRWW non-data sharing Without FLA With FLA (100 MB) With FLA (500 MB)<br />

Log records processed (million) 3.800 3.642 3.772<br />

Elapsed time (sec.) 1,320 325 262<br />

Rate (log records/sec.) 2,900 11,200 14,400<br />

A FLA buffer size of 100 MB resulted in a 4 times improvement in elapsed time. With APAR<br />

PQ95164, the DSNZPARM parameter LOGAPSTG will not determine the FLA buffer size <strong>for</strong><br />

the RESTORE utility, only if it is used or not. <strong>DB2</strong> will first try to allocate a 500 MB FLA buffer;<br />

if not successful <strong>DB2</strong> will reduce the memory request to 250 MB, then 125 MB. During restore<br />

the RESTORE SYSTEM utility is the only process running and there should be no problem<br />

obtaining 500 MB of storage <strong>for</strong> the FLA feature at this time. The 500 MB FLA buffer further<br />

decreased the elapsed time by 28% compared to a 100 MB FLA buffer. Compared to the test<br />

case without FLA a 500 MB buffer resulted in nearly 5 times faster log apply phase.<br />

List prefetch is the major contributor to FLA improvements, so the more random the logging<br />

had been, the more advantage FLA will bring.<br />

sec.<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

Elapsed Time <strong>for</strong><br />

FRRECOV<br />

31<br />

52<br />

67 195<br />

# of Vols<br />

DB Pool<br />

Chapter 5. Availability and capacity enhancements 225


5.1.2 Conclusion<br />

The BACKUP SYSTEM utility provides an easier and minimally disruptive way to backup an<br />

entire <strong>DB2</strong> subsystem or data sharing group. Executing the BACKUP SYSTEM utility<br />

concurrent with your workload should not impact the per<strong>for</strong>mance.<br />

5.1.3 Recommendations<br />

We recommend that you execute the FRBACKUP prepare command outside the actual<br />

backup cycle in order to minimize the impact on the backup elapsed time.<br />

Fast log apply supports the system level point-in-time recovery and provides good<br />

per<strong>for</strong>mance. We highly recommend to activate fast log apply (LOGAPSTG DSNZPARM<br />

parameter), your system will benefit from it, not only the RESTORE SYSTEM utility but also<br />

during all RECOVER utility executions and at <strong>DB2</strong> restart.<br />

Individual recovery actions at the table space or index space level cannot use a BACKUP<br />

SYSTEM backup which implies these recoveries need a data set level copy. This data set<br />

level copy can be a <strong>DB2</strong> image copy or a non <strong>DB2</strong> backup (log only recovery), <strong>for</strong> example, a<br />

data set level FlashCopy backup (FlashCopy V2 required).<br />

5.2 Automated space management<br />

In general, a large percentage of your data sets are today managed with DFSMS storage<br />

pools, reducing the workload and the interaction of your <strong>DB2</strong> database administrators and<br />

storage administrators. Only the most critical data, as defined with service level agreements<br />

or as revealed by monitoring, may require special attention.<br />

Using DFSMS, the <strong>DB2</strong> administrator gains the following benefits:<br />

► Simplified data allocation<br />

► Improved allocation control<br />

► Improved per<strong>for</strong>mance management<br />

► Automated disk space management<br />

► Improved data availability management<br />

► Simplified data movement<br />

An important function, automated data set space management, was still lacking in this list.<br />

<strong>DB2</strong> provides this functionality in <strong>Version</strong> 8.<br />

The idea is that <strong>DB2</strong> will adjust the size of the secondary extent, when extending the data set,<br />

in such a way that the maximum allowable data set size is reached, be<strong>for</strong>e the maximum<br />

number of extents <strong>for</strong> that data set is reached, there<strong>for</strong>e avoiding out of space conditions.<br />

Remember that today space allocation supports a maximum number of 255 extents per<br />

component of a VSAM data set <strong>for</strong> multivolume data sets and a maximum of 123 extents <strong>for</strong> a<br />

single volume allocation. A striped VSAM data set can have up to 255 extents per stripe. Also<br />

new in DFSMS <strong>for</strong> z/<strong>OS</strong> 1.5 is that the system consolidates adjacent extents <strong>for</strong> a VSAM data<br />

set when extending the data set on the same volume.<br />

Users of <strong>DB2</strong> receive out of extent errors during data set extend processing when the<br />

maximum number of extents is reached, thus preventing a <strong>DB2</strong> managed page set from<br />

reaching maximum data set size. Although <strong>DB2</strong> issues warning messages (DSNP001I) of<br />

impending space shortage, user procedures in many cases cannot react quickly enough to<br />

spot the problem, use SQL ALTER to modify PRIQTY and SECQTY values, and then<br />

schedule a REORG. This is a significant problem today <strong>for</strong> large users of <strong>DB2</strong>, particularly <strong>for</strong><br />

226 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


users of ERP and CRM vendor solutions and ported applications with not well known growth,<br />

and can lead to application outages.<br />

Default PRIQTY and SECQTY values and often user provided PRIQTY and SECQTY values<br />

are too small, resulting in track allocation rather than cylinder allocation. As a result the<br />

per<strong>for</strong>mance of SQL SELECT and INSERT processing can be penalized by 2x or more.<br />

The first objective of this enhancement is to avoid the situation where a <strong>DB2</strong> managed page<br />

set reaches the VSAM maximum extent limit of 255 be<strong>for</strong>e it can reach the maximum data set<br />

size which may be less than 1 GB or 1 GB, 2 GB, 4 GB, 8 GB, 16 GB, 32 GB or 64 GB.<br />

The second objective of the enhancement is to remove the need <strong>for</strong> a user to specify the<br />

secondary quantity <strong>for</strong> a <strong>DB2</strong> managed page set, or even both the primary and secondary<br />

quantities, either when creating it initially or by using an ALTER statement later. The overall<br />

goal is to provide a solution which would benefit all users of <strong>DB2</strong> in terms of improved DBA<br />

productivity and preventing application outages.<br />

<strong>DB2</strong> V8 adds a new DSNZPARM parameter called MGEXTSZ (with a global scope) which<br />

enables the use of a “sliding secondary space allocation” <strong>for</strong> <strong>DB2</strong> managed data sets<br />

(STOGROUP defined). The values are: NO and YES. The default value <strong>for</strong> MGEXTSZ is NO.<br />

The enhancement will help to reduce the number of out of space conditions, eliminate need<br />

<strong>for</strong> PRIQTY and SECQTY specification on SQL CREATE, improve user productivity, and<br />

avoid the per<strong>for</strong>mance penalty associated with small extent sizes.<br />

This patented solution should benefit all users of <strong>DB2</strong>, not just <strong>for</strong> ERP and CRM solutions,<br />

ported and new applications. It delivers autonomic selection of data set extent sizes with a<br />

goal of preventing out of extent errors be<strong>for</strong>e reaching maximum data set size.<br />

An increasing secondary quantity size up to 127 extents is allocated and a constant number<br />

of 559 cylinders <strong>for</strong> 32 GB and 64 GB data sets is used thereafter. Figure 5-6 shows the<br />

sliding scale mechanism <strong>for</strong> 64 GB data sets with 255 extents. It assumes an initial extent of 1<br />

cylinder.<br />

Extent Size (CYLS)<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

16<br />

Sliding scale <strong>for</strong> 64 GB data sets<br />

32<br />

Figure 5-6 Sliding scale <strong>for</strong> 64 GB data sets<br />

64<br />

96<br />

128 255<br />

Extent Number<br />

Chapter 5. Availability and capacity enhancements 227


Figure 5-7 shows the sliding scale mechanism <strong>for</strong> a 16 GB data set with a maximum of 246<br />

extents.It assumes an initial extent of 1 cylinder.<br />

Extent size (CYLS)<br />

200<br />

150<br />

100<br />

50<br />

0<br />

Figure 5-7 Sliding scale <strong>for</strong> 16 GB data set<br />

An increasing secondary quantity size up to 127 extents is allocated and a constant number<br />

of 127 cylinders <strong>for</strong> data sets less than 1 GB or 1, 2, 4, 8 and 16 GB is used <strong>for</strong> the secondary<br />

allocation thereafter.<br />

This approach of sliding the secondary quantity minimizes the potential <strong>for</strong> wasted space by<br />

increasing the extents size slowly at first, and it also avoids very large secondary allocations<br />

from extents 128-255 which will most likely cause fragmentation where multiple extents have<br />

to be used to satisfy a data set extension. The solution will address new data sets which will<br />

be allocated and also existing data sets requiring additional extents.<br />

A new default PRIQTY value will be applied if not specified by the user and recorded in the<br />

Catalog. The actual value applied by <strong>DB2</strong> <strong>for</strong> default PRIQTY will be determined by the<br />

applicable TSQTY or IXQTY DSNZPARMs which were introduced with <strong>DB2</strong> V7. DSNZPARMs<br />

TSQTY and IXQTY will now have global scope. TSQTY will apply to non-LOB table spaces.<br />

For LOB table spaces a 10x multiplier will be applied to TSQTY to provide the default value <strong>for</strong><br />

PRIQTY. IXQTY will apply to indexes. DSNZPARMs TSQTY and IXQTY will continue to have<br />

a default value of 0 (zero), but this value will indicate a new default value of 720 KB (1<br />

cylinder) is to be applied. If TSQTY is set to 0 then 1 cylinder will be the default PRIQTY<br />

space allocation <strong>for</strong> non-LOB table spaces and 10 cylinders will be the default PRIQTY space<br />

allocation <strong>for</strong> LOB table spaces. If IXQTY is set to 0 then 1 cylinder will be the default PRIQTY<br />

space allocation <strong>for</strong> indexes.<br />

The user can provide override values <strong>for</strong> TSQTY and IXQTY DSNZPARMs to avoid wasting<br />

excessive DASD space. For example on a development subsystem, TSQTY and IXQTY may<br />

be set to 48KB <strong>for</strong> track allocation. The use of the default <strong>for</strong> PRIQTY will be recorded in the<br />

associated PQTY column as -1 in the SYSTABLEPART or SYSINDEXPART catalog table.<br />

<strong>DB2</strong> will always honor the PRIQTY value specified by the user and recorded in the associated<br />

PQTY column in SYSTABLEPART or SYSINDEXPART catalog table.<br />

228 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Sliding scale <strong>for</strong> 16 GB data sets<br />

16<br />

32<br />

64<br />

96<br />

128 246<br />

Extent number


5.2.1 Conclusion<br />

If MGEXTSZ is set to YES, <strong>DB2</strong> will always honor SECQTY value specified by the user in the<br />

Catalog if it is greater than the secondary quantity value calculated by the sliding scale<br />

methodology used by the solution. This allows the user to override with a larger SECQTY<br />

value to get to maximum data set size quicker.<br />

If no SECQTY value is specified by the user, it will be recorded as -1 in the associated SQTY<br />

column in SYSTABLEPART or SYSINDEXPART catalog table, <strong>DB2</strong> will calculate 10% of the<br />

PRIQTY value specified by the user in the Catalog but will cap by the maximum secondary<br />

quantity allocation according to the respective sliding scale.<br />

If you specify SECQTY 0, it will be honored by <strong>DB2</strong>. This results in SQLCODE -904 and<br />

reason code 00D70027 when <strong>DB2</strong> tries to extend the data set.<br />

For a striped data set, the proposed extent size will have to be divided by the number of<br />

stripes and each stripe can have up to 255 extents.<br />

When extent consolidation is in effect in z/<strong>OS</strong> V1.5 the secondary space allocation quantity<br />

can be smaller than specified or calculated by the sliding scale based on the physical extent<br />

number. PTF UQ89517 <strong>for</strong> APAR PQ88665 corrects this problem by using the logical extent<br />

number together with the sliding scale.<br />

No primary nor secondary allocation needs to be specified at create time. <strong>DB2</strong> determines<br />

the optimal values based on a combination of the DSSIZE, LARGE and PIECESIZE<br />

specifications and system parameters MGEXTSZ, TSQTY and IXQTY. The secondary<br />

allocation is automatically increased using a sliding scale until 127 extents and a constant<br />

size thereafter to avoid exhausting the maximum number of extents per data sets.<br />

The enhancement has the potential to improve SQL SELECT and INSERT per<strong>for</strong>mance,<br />

more efficient pre<strong>for</strong>mat, prefetch, and deferred write processing.<br />

This enhancement changes the PRIQTY default to achieve cylinder allocation, <strong>for</strong>ces tiny<br />

SECQTY allocations to use these defaults, and slides secondary quantity allocations<br />

upwards.<br />

Any penalty with having multiple extents goes down as the extent size increases. The size of<br />

the extents is actually more important than the actual number of extents. Above an extent size<br />

of 10 cylinders independent of the number of extents there is no noticeable difference in<br />

per<strong>for</strong>mance.<br />

Note that no space availability nor disk fragmentation is addressed by this enhancement, and<br />

still remain the responsibility of DFSMS and the storage administrator.<br />

5.2.2 Recommendations<br />

We recommend to start with activating automatic space management <strong>for</strong> secondary extents<br />

(MGEXTSZ=YES). Availability will increase by avoiding out of space abends due to maximum<br />

number of extents reached and, as I/Os will never span extents, your installation will benefit<br />

from better extent sizing when per<strong>for</strong>ming<br />

► Prefetch<br />

► Deferred write<br />

► Mass Insert<br />

► Utility Processing<br />

Chapter 5. Availability and capacity enhancements 229


Maybe you have implemented a space allocation strategy at your site. You do not have to alter<br />

your current strategy in order to benefit from the automated secondary quantity space<br />

management. Specifying MGEXTSZ=YES triggers <strong>DB2</strong> to manage the size of secondary<br />

allocations by the sliding scale mechanism. This guarantees that you will never run out of<br />

extents and still honors the SECQTY that you specified if greater than the <strong>DB2</strong> calculated<br />

value.<br />

5.3 Online schema<br />

Note: PTF UK08807 <strong>for</strong> APAR PK0564 provides a data set pre<strong>for</strong>mat quantity adjustment<br />

to take into account the larger sizes of secondary extents.<br />

In the past, <strong>DB2</strong> releases have implemented most DDL ALTER enhancements without<br />

actively addressing the problem of data unavailability while modifying object attributes.<br />

Some schema changes could already be done without having to drop and recreate an object,<br />

or stopping and starting the object, such as adding a column to a table, renaming a table,<br />

altering the primary and secondary quantity of an object, or changing partition boundaries.<br />

But many changes to table, table space, and index schemas (DDL) prior to <strong>DB2</strong> V8 require<br />

that you adhere to the following procedure to implement them:<br />

– Unload the data, extract the DDL and authorizations of the object you are about to<br />

change, and all dependent objects, like tables, indexes, views, synonyms, triggers, and<br />

so on.<br />

– Drop the object.<br />

– Create the object with the new definition and reestablish authorizations <strong>for</strong> the object.<br />

– Recreate all dependent objects, such as views and indexes, and so <strong>for</strong>th, and their<br />

authorizations.<br />

– Reload the data.<br />

– Rebind plans and packages.<br />

– Test that all is OK.<br />

Without the use of <strong>DB2</strong> administration tools, this is a cumbersome and error prone process.<br />

<strong>DB2</strong> V8 allows many more schema changes without having to drop and recreate the objects.<br />

5.3.1 Changing attributes<br />

Online schema evolution allows <strong>for</strong> table space, table and index attribute changes while<br />

minimizing impact on availability.<br />

The following schema changes are allowed in <strong>DB2</strong> V8:<br />

Alter column data type<br />

Column data types can be changed without losing data availability.<br />

► Increase column size within a data type<br />

► Change the data type<br />

After the change:<br />

► The table space is placed in Advisory Reorg Pending (AREO*) state.<br />

230 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► The data is accessible but until the table space is reorganized a per<strong>for</strong>mance penalty is<br />

paid.<br />

► Plans, packages and cached dynamic statements referring to the changed column are<br />

invalidated. If auto-rebind is enabled, the plans and packages referencing the changed<br />

table space are automatically rebound during the next access if not manually rebound<br />

previously.<br />

► Frequency statistics <strong>for</strong> columns are invalidated.<br />

► The new column type must be large enough to hold the maximum value possible <strong>for</strong><br />

original column.<br />

► If indexed, changes <strong>for</strong> character data type columns result in immediate index availability.<br />

This includes columns defined as CHAR, VARCHAR, GRAPHIC, or VARGRAPHIC.<br />

► If indexed, changes <strong>for</strong> numeric data type columns are immediate with delayed index<br />

availability. This includes columns defined as SMALLINT, INTEGER, DECIMAL or<br />

NUMERIC, FLOAT, REAL, or DOUBLE. Availability to the index is delayed until the index is<br />

rebuilt.<br />

► Scope of unavailability <strong>for</strong> dynamic SQL<br />

– Deletes are allowed <strong>for</strong> table rows, even if there are indexes in RBDP.<br />

– Updates and inserts are allowed <strong>for</strong> table rows, even if their corresponding non-unique<br />

indexes are in RBDP state.<br />

– Inserting or updating data rows which result in inserting keys into an index that is in<br />

RBDP state is disallowed <strong>for</strong> unique or unique where not null indexes.<br />

– For queries, <strong>DB2</strong> does not choose an index in RBDP <strong>for</strong> an access path.<br />

Recommendations<br />

When using this feature, make sure that you do not <strong>for</strong>get to assess which programs need to<br />

be changed. Host variables, <strong>for</strong> example, may need to be extended to cater to the extra<br />

length. To minimize any per<strong>for</strong>mance degradation, schedule a REORG as soon as possible<br />

after ALTER. This reestablishes fast column processing and eliminates the conversion from<br />

old row <strong>for</strong>mat to the new one when retrieved by the application.<br />

Rebuild any affected indexes and rebind plans and packages. Otherwise <strong>DB2</strong> might pick an<br />

inefficient access path during automatic rebind because the best suited index is currently not<br />

available.<br />

Schedule RUNSTATS to repopulate the catalog with accurate column and index statistics.<br />

Alter index<br />

Several changes can now be implemented via the ALTER INDEX statement:<br />

► Add a column to the end of an index<br />

Adding the column to the table and index in the same UOW will place the index in AREO*<br />

state. The index is immediately available.<br />

Adding an existing column to the index places the index in rebuild pending (RBDP) status.<br />

► Scope of unavailability <strong>for</strong> dynamic SQL<br />

Deletes are allowed <strong>for</strong> table rows, even if there are indexes in RBDP.<br />

Updates and inserts are allowed <strong>for</strong> table rows, even if their corresponding non-unique<br />

indexes are in RBDP state.<br />

Inserting or updating data rows which results in inserting keys into an index that is in<br />

RBDP state is disallowed <strong>for</strong> unique or unique where not null indexes.<br />

Chapter 5. Availability and capacity enhancements 231


For dynamically prepared queries, <strong>DB2</strong> does not choose an index in RBDP <strong>for</strong> an access<br />

path.<br />

► Alter an index VARCHAR columns to be non padded<br />

Prior to <strong>DB2</strong> V8, varying length columns in indexes are padded to the maximum length<br />

specified by VARCHAR(length). <strong>DB2</strong> V8 provides a new default index option NOT<br />

PADDED. Varying length columns are no longer padded to the maximum length in index<br />

keys and index-only access becomes available <strong>for</strong> VARCHAR data.<br />

This enhancement could also reduce storage requirements since only the actual data is<br />

stored and the index tree level could be reduced.<br />

The index can be altered between PADDED and NOT PADDED but will be placed in<br />

RBDP.<br />

Note that <strong>DB2</strong> V6 introduced the DSNZPARM RETVLCFK. This parameter controls the<br />

ability of the Optimizer to use index-only access when processing VARCHAR columns that<br />

are part of an index. However, when one of the columns in the SELECT list of the query is<br />

retrieved from the index when using index-only access, the column is padded to the<br />

maximum length, and the actual length of the variable length column is not provided.<br />

There<strong>for</strong>e, an application must be able to handle these “full-length” variable length<br />

columns. <strong>DB2</strong> V7 enhances this feature by allowing index-only access against variable<br />

length columns in an index, even with RETVLCFK=NO, if no variable length column is<br />

present in the SELECT list of the query. <strong>DB2</strong> V8 supports true varying-length key columns<br />

in an index. Varying-length columns are not padded to their maximum lengths.<br />

<strong>Version</strong>ing<br />

To support online schema evolution, <strong>DB2</strong> has implemented a new architecture, called<br />

versioning, to track object definitions at different times during its life by using versions.<br />

Altering existing objects may result in a new <strong>for</strong>mat <strong>for</strong> tables, table spaces, or indexes which<br />

indicates how the data should be stored and used. Since all the data <strong>for</strong> an object and its<br />

image copies cannot be changed immediately to match the <strong>for</strong>mat of the latest version,<br />

support <strong>for</strong> migrating the data over time in some cases is implemented by using versions of<br />

tables and indexes. This allows data access, index access, recovery to current, and recovery<br />

to a point-in-time while maximizing data availability.<br />

Availability considerations<br />

Today, when an index is in Rebuild Pending (RBDP), the optimizer is unaware of that and can<br />

still pick that index during access path selection when you are executing a query.<br />

In <strong>Version</strong> 8, <strong>DB2</strong> will try to avoid using indexes in RBDP <strong>for</strong> dynamically prepared queries.<br />

<strong>DB2</strong> will bypass indexes in Rebuild Pending (index is ignored):<br />

► For all DELETE processing<br />

► For all non-unique indexes <strong>for</strong> UPDATEs and INSERTs<br />

► A unique index in RBDP cannot be avoided <strong>for</strong> UPDATE or INSERT because <strong>DB2</strong> needs<br />

the index to be available to be able to en<strong>for</strong>ce uniqueness.<br />

The <strong>DB2</strong> optimizer treats RBDP indexes as follows:<br />

► Dynamic PREPARE:<br />

– Indexes in RBDP are avoided.<br />

► Cached statements:<br />

– If the statement is cached, the PREPARE is bypassed. But if the index is used by the<br />

statement that is cached, it is invalidated by the ALTER.<br />

232 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


5.3.2 Per<strong>for</strong>mance<br />

– Invalidation occurs during ALTER.<br />

► Static BIND does not avoid an index that is in RBDP:<br />

– Indexes in RBDP can still be chosen, and will get a resource unavailable condition at<br />

execution time.<br />

Dynamic partition management<br />

The enhancements related to partitions are:<br />

► Add, rotate, and rebalance partitions<br />

Execute the ALTER TABLE ADD PARTITION statement to add a partition to a partitioned<br />

table space and you are ready to go. You can start inserting/loading rows into the new<br />

partition immediately.<br />

Rotating partitions allows old data to “roll-off” while reusing the partition <strong>for</strong> new data with<br />

the ALTER TABLE ROTATE PARTITION FIRST TO LAST statement. When rotating, you<br />

can specify that all the data rows in the oldest (or logically first) partition are to be deleted,<br />

and then specify a new table space high boundary (limit key) so that the partition<br />

essentially becomes the last logical partition in sequence, ready to hold the data that is<br />

added. The emptied partition is available immediately, no REORG is necessary. Logical<br />

and physical partition numbering is now different. Refer to the columns DSNUM and<br />

LOGICAL_PART in catalog tables SYSTABLEPART and SYSCOPY <strong>for</strong> the actual physical<br />

to logical partition number correspondence. Recover to previous PIT is blocked as<br />

SYSCOPY and SYSLGRNX entries are deleted.<br />

Rebalancing partitions is done by means of the REORG TABLESPACE utility. Specifying<br />

the REBALANCE option when specifying a range of partitions to be reorganized allows<br />

<strong>DB2</strong> to set new partition boundaries <strong>for</strong> those partitions, so that all the rows that<br />

participate in the reorganization are evenly distributed across the reorganized partitions.<br />

However, if the columns used in defining the partition boundaries have many duplicate<br />

values perfect rebalancing may not be possible.<br />

Note that adding and rotating partitions will automatically convert index controlled to table<br />

controlled partitioning.<br />

► Alter partition boundaries<br />

In <strong>DB2</strong> V6, the ability to modify limit keys <strong>for</strong> table partitions was introduced. The<br />

enhancement in <strong>DB2</strong> V8 introduces the same capability <strong>for</strong> table-based partitioning with<br />

the ALTER TABLE ALTER PARTITION ENDING AT statement. The affected data partitions<br />

are placed into Reorg Pending state (REORP) until they have been reorganized.<br />

In this section we describe the online schema per<strong>for</strong>mance measurements.<br />

Per<strong>for</strong>mance measurement description<br />

The environment we used in this measurement:<br />

► z/<strong>OS</strong> V1R3<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 in NFM<br />

► <strong>IBM</strong> z900 Series 2064 4-way processor<br />

► ESS 2105-800 with FICON channels<br />

Per<strong>for</strong>mance measurement results<br />

Alter Column Data Types<br />

In a non-partitioned table with 17 columns and 2 indexes the following alters were executed:<br />

Chapter 5. Availability and capacity enhancements 233


► CHAR(8) to VARCHAR(8)<br />

► CHAR(8) to CHAR(10)<br />

► INTEGER to DECIMAL(10,0)<br />

The CPU time (microsec.) <strong>for</strong> FETCH and INSERT be<strong>for</strong>e ALTER, after ALTER and after<br />

REORG are measured. Figure 5-8 shows the results <strong>for</strong> FETCH.<br />

CPU time (microseconds)<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

C8 =>VC8 C8 =>C10 Int =>Dec<br />

Figure 5-8 CPU time be<strong>for</strong>e ALTER, after ALTER and after REORG<br />

A per<strong>for</strong>mance degradation of 21% to 23% is measured after ALTER and be<strong>for</strong>e REORG.<br />

After reorganization the per<strong>for</strong>mance overhead remains below 5%.<br />

The per<strong>for</strong>mance fluctuation reflects the change of <strong>for</strong>mat and that “fast path <strong>for</strong> column<br />

processing” is disabled after ALTER and re-enabled again after reorganization of the table<br />

space. Even improved per<strong>for</strong>mance after reorganization is possible, depending on the new<br />

data type as some data types tend to be less CPU intensive, <strong>for</strong> example change from<br />

decimal to integer.<br />

Fast path <strong>for</strong> column processing was introduced in <strong>DB2</strong> V4. For SELECT, FETCH, UPDATE<br />

and INSERT, <strong>DB2</strong> will process each column definition <strong>for</strong> the first three rows. For the fourth<br />

and subsequent rows <strong>DB2</strong> generates and uses an optimized procedure to access further<br />

rows.<br />

Figure 5-9 shows the results <strong>for</strong> INSERT.<br />

234 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Be<strong>for</strong>e Alter<br />

After Alter (AREO*)<br />

After Reorg (reset<br />

AREO*)


CPU time (microseconds)<br />

90<br />

80<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

Int =>Dec<br />

Figure 5-9 INSERT CPU time be<strong>for</strong>e ALTER, after ALTER and after REORG<br />

Be<strong>for</strong>e Alter<br />

After Alter (AREO*)<br />

After Reorg (reset<br />

AREO*)<br />

Almost no difference in INSERT per<strong>for</strong>mance is noticed after the ALTER in this case. The row<br />

is inserted in the new <strong>for</strong>mat, no conversion cost is associated with the INSERT and the fast<br />

path <strong>for</strong> column processing is not disabled. The slight increase in CPU time is due to the<br />

decimal data type being a more expensive data type in terms of CPU than an integer. The<br />

difference in CPU time after ALTER and be<strong>for</strong>e REORG compared to after REORG is<br />

negligible.<br />

INSERT after ALTER from CHAR to VARCHAR or CHAR(8) to CHAR(10) resulted in 13%<br />

increase.<br />

Conclusion<br />

After ALTER table the table space is placed in an AREO* status. The data remains accessible<br />

with some per<strong>for</strong>mance degradation. On SELECT the data is materialized to the latest <strong>for</strong>mat.<br />

On INSERT and UPDATE the entire row is saved using the new definition. Reorganization of<br />

the table space changes all rows to the latest <strong>for</strong>mat and access to the data shows no<br />

degradation. A degradation can occur only if altering to a more expensive data type. If altering<br />

to a less expensive data type, like from VARCHAR to CHAR, then an improvement would take<br />

place.<br />

Recommendations<br />

Schedule reorganization of the table space soon after ALTER to minimize per<strong>for</strong>mance<br />

degradation. We typically experience 20% degradation in FETCH, 10% in INSERT, prior to<br />

REORG.<br />

Alter Index Add Column<br />

We executed the following scenario on a 10 partitions table space, a 10 M rows table, 1 PI<br />

and 2 NPIs:<br />

1. CREATE INDEX on column C1<br />

2. SELECT C1, C2 WHERE C2=’XX’ - C2 is not in the index key<br />

3. ALTER INDEX add column C2 to the index<br />

4. REBUILD INDEX<br />

5. SELECT C1, C2 WHERE C2=’XX’ - C1, C2 are in the index key<br />

The elapsed and CPU time <strong>for</strong> step 2 and 5 were measured and compared, see Figure 5-10.<br />

Chapter 5. Availability and capacity enhancements 235


Be<strong>for</strong>e ALTER INDEX add column, a table space scan was used to access the data. After<br />

ALTER INDEX ADD of an existing column of the table to an index, the index was placed in a<br />

RBDP state and needs to be rebuilt. After rebuild, the access path changed from table space<br />

scan to non-matching index scan showing a 10 times elapsed time improvement.<br />

Class 1 Time (seconds)<br />

120<br />

100<br />

Figure 5-10 SELECT elapsed and CPU time be<strong>for</strong>e and after ALTER INDEX add column<br />

Conclusion<br />

A change of the access path from table space scan to an access path using the index<br />

improves the elapsed time. This is well known. What is worth noting is the ease of<br />

implementing the change. Remember that an index in RBDP state does not block access to<br />

the data. For non-unique indexes, static plans and packages that do not use the index to<br />

retrieve data, they will continue to function as be<strong>for</strong>e. For unique indexes placed in RBDP,<br />

those plans and packages that are dependent on them will get a -904 (unavailable resource)<br />

on an update of an existing row or insert of a new row. Deletes are no problem. For the time<br />

until rebuild, the optimizer simply ignores the index <strong>for</strong> dynamic SQL; <strong>for</strong> static SQL a rebind is<br />

necessary.<br />

Recommendations<br />

Once the index is available again, revert to optimal access paths by:<br />

► Rebinding affected plans and packages <strong>for</strong> static SQL.<br />

► Automatic invalidation of related statements in the dynamic statement cache when RBDP<br />

is reset. At next execution, the statement is prepared again, and can go back to the<br />

original access path.<br />

Important: The enhancement is designed to allow maximum availability <strong>for</strong> the situations<br />

where a new column is added to a table, and this new column is also desired as part of an<br />

existing index. By making changes within the same unit of work there is no unavailability.<br />

236 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

80<br />

60<br />

40<br />

20<br />

0<br />

SELECT elapsed time and CPU time<br />

Elapsed Time CPU Time<br />

Be<strong>for</strong>e Alter After Rebuild<br />

Index<br />

Index<br />

(2) (5)<br />

1. DDL Create Index<br />

CREATE INDEX ix1 ON tab1(c1) ...<br />

2. SELECT c1, c2 … WHERE c2 = ‘xx‘<br />

Column not indexed, table space<br />

scan<br />

3. ALTER INDEX ix1 ADD COLUMN (c2)<br />

Index in RBDP<br />

4. Rebuild Index<br />

5. SELECT c1, c2 … WHERE c2 = ‘xx‘<br />

Non matching index only scan<br />

10+ times Elapsed time<br />

improvement


Alter Index Padding<br />

In a first test with a non-partitioned table with 17 columns and 1 index the following scenario is<br />

executed and measured:<br />

1. CREATE PADDED INDEX index on C1, C2 and C3, each column being VARCHAR(10)<br />

2. ALTER INDEX to NOT PADDED and REBUILD INDEX<br />

3. ALTER INDEX to PADDED and REBUILD INDEX<br />

4. CREATE NOT PADDED INDEX on C1, C2 and C3, each column being VARCHAR(10)<br />

After each step the CPU time is measured <strong>for</strong> the following SQL:<br />

FETCH C1, C2, C3... WHERE C1=’XXXXXXXX’ AND C2=’YYYYYYYY’<br />

The results of this measurement are shown in Figure 5-11.<br />

CPU microseconds<br />

30<br />

25<br />

20<br />

15<br />

10<br />

Fetch CPU time …Alter Index Padding<br />

5<br />

0<br />

(1) (2) (3) (4)<br />

padded padded => not padded not padded<br />

ix not padded => padded ix<br />

Fetch CPU time comparison<br />

(2) vs. (1) : +6%<br />

(3) vs. (1) : No difference<br />

(4) vs. (1) : -17%<br />

Figure 5-11 FETCH CPU time - Alter index padded<br />

Index only<br />

access<br />

► After ALTER of the index to NOT PADDED and REBUILD the CPU time <strong>for</strong> FETCH<br />

increased by 6% (2 vs. 1)<br />

► Altering the index back to PADDED shows no difference in FETCH CPU time compared to<br />

the original situation (3 vs. 1)<br />

► Compared to an index that was created originally with the keyword NOT PADDED there is<br />

a FETCH CPU time increase of 23% (2 vs. 4)<br />

► The impact of NOT PADDED versus PADDED evaluates to a CPU time decrease of 17%<br />

(4 vs. 1) due to index-only access which outweighs the more expensive VARCHARs index<br />

key processing<br />

Note that the access path after the change from PADDED to NOT PADDED did not change to<br />

index-only access.<br />

We repeated this measurement and included a rebind of the application after altering the<br />

index from PADDED to NOT PADDED. See Figure 5-12 <strong>for</strong> the results.<br />

(1)<br />

N<br />

Chapter 5. Availability and capacity enhancements 237<br />

(2)<br />

N<br />

(3)<br />

N<br />

(4)<br />

Y


30<br />

25<br />

20<br />

15<br />

10<br />

Figure 5-12 FETCH CPU time - Alter index not padded and rebind<br />

The FETCH CPU time after rebind shows no difference compared to an originally created<br />

NOT PADDED index. Also an index-only access path is used after rebind.<br />

A second test was run with a set of 15 queries doing joins on two VARCHAR(10) columns.<br />

The join columns are accessed via matching index scan. We measured the query<br />

per<strong>for</strong>mance <strong>for</strong> this set of queries using padded keys. Then we altered the indexes to NOT<br />

padded, ran rebuild index and RUNSTATS and measured the query per<strong>for</strong>mance <strong>for</strong> 15<br />

queries using not padded keys. We repeated this test with VARCHAR(20) and VARCHAR(30)<br />

columns. In Figure 5-13 we show the CPU overhead using NOT PADDED indexes vs.<br />

PADDED indexes.<br />

238 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

5<br />

0<br />

(1) (2) (3) (4)<br />

CPU time (microseconds) Fetch CPU time …Alter Index Padding<br />

padded padded => rebind not padded not padded<br />

ix not padded program => padded ix<br />

Fetch CPU time reduced after application program rebind<br />

- access path changed to index-only access


Percent of CPU overhead<br />

Average CPU overhead <strong>for</strong> 15 Queries<br />

Query CPU overhead using NOT PADDED vs. PADDED keys<br />

Two varchar keys in two indexes are altered from padded to not padded<br />

8<br />

7<br />

6<br />

5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

VC10 VC20 VC30 VC40 VC50<br />

Figure 5-13 Query CPU overhead using NOT PADDED vs. PADDED index<br />

There is a cost associated with the use of not padded keys as together with the key also the<br />

length bytes are saved. As the VARCHARs become longer the CPU overhead decreases.<br />

The impact on index leaf pages and index getpages is shown in Figure 5-14.<br />

P<br />

P<br />

CPU overhead<br />

P:<br />

Projection<br />

Chapter 5. Availability and capacity enhancements 239


Percent of index pages<br />

Avg. Index Leaf Pages and Getpages <strong>for</strong> 15 Queries<br />

-10<br />

-20<br />

-30<br />

-40<br />

-50<br />

Figure 5-14 Average index leaf pages and index getpages<br />

Initially there is no benefit from not padded index keys as together with the key also the length<br />

bytes are saved. The longer the VARCHAR becomes the more the benefit from not padding<br />

becomes visible. Index storage requirements could be reduced as only the actual data is<br />

stored and the index tree may have fewer levels.<br />

In a third measurement the impact of NOT PADDED indexes on utilities was measured. We<br />

used a table with 10 M rows and one PADDED or NOT PADDED index. The following cases<br />

were measured:<br />

1. 10 M rows table with a one-column indexed key of VARCHAR(14) with varying length from<br />

1 to 14.<br />

2. 10 M rows table with a one-column indexed key of VARCHAR(1)<br />

3. 10 M rows table with a four-column indexed key of each VARCHAR(1)<br />

The tests were run <strong>for</strong> LOAD, REORG table space, REORG index, REBUILD, CHECK index<br />

and RUNSTATS index.<br />

See Figure 5-15 <strong>for</strong> the measurement result of test case 1.<br />

240 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

20<br />

10<br />

0<br />

Queries using NOT PADDED vs. PADDED keys<br />

VC10 VC20 VC30 VC40 VC50<br />

# of Leaf Pages<br />

Index Getpages


250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

Load Reorg IX Check IX<br />

Reorg TS Rebuild IX Runstats IX<br />

Figure 5-15 NOT PADDED index impact on utilities - Index VARCHAR(14)<br />

See Figure 5-16 <strong>for</strong> the measurement result of test case 2.<br />

time<br />

in<br />

seconds<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

NOT PADDED index impact on utility<br />

Table with one column index VARCHAR(14)<br />

NOT PADDED index impact on utility<br />

Load Reorg<br />

tablespace<br />

Table with one column index VARCHAR(1)<br />

Reorg<br />

Index<br />

Rebuild<br />

Index<br />

Figure 5-16 NOT PADDED index impact on utilities - Index VARCHAR(1)<br />

See Figure 5-17 <strong>for</strong> the measurement result of test case 3.<br />

CPU padded<br />

CPU not padded<br />

Elapsed padded<br />

Elapsed not padded<br />

Check<br />

Index<br />

Runstats<br />

Index<br />

CPU padded CPU not padded Elapsed padded Elapsed not padded<br />

Chapter 5. Availability and capacity enhancements 241


300<br />

250<br />

200<br />

time<br />

in<br />

seconds<br />

150<br />

100<br />

50<br />

Figure 5-17 NOT PADDED index impact on utilities - Index 4 columns VARCHAR(1)<br />

The results from these measurements show:<br />

► Up to 20% degradation in CPU with one-column indexed key<br />

► Up to 60% degradation in CPU with four-column indexed key<br />

► LOAD and REORG table space: Degradation in LOAD and BUILD phases<br />

► REORG INDEX and REBUILD INDEX and CHECK INDEX: Degradation in UNLOAD and<br />

BUILD or CHECK IX phases<br />

► RUNSTATS INDEX degrades 20% with one-column indexed key of VARCHAR(14) but<br />

only 14% with four-column indexed key of VARCHAR(1)<br />

► With NOT PADDED index key, two bytes are added to each key → less CPU degradation<br />

with bigger VARCHAR key length (>18 char)<br />

Note that VARCHAR(1) is not just a theoretical example. It was used in this measurement in<br />

order to illustrate the worst case scenario, but it is often present in SAP environments, and<br />

whenever an index was likely to be altered.<br />

Conclusion<br />

After ALTER index to NOT PADDED, REBUILD INDEX and rebind the applications in order to<br />

achieve better per<strong>for</strong>mance.<br />

Recommendations<br />

For those installations that avoid the use of long VARCHAR columns in indexes, there is now<br />

less reason <strong>for</strong> doing so.<br />

As a rule of thumb, start using not padded indexes <strong>for</strong> VARCHARs with length more than 18<br />

bytes. If you have VARCHAR(>18) columns in indexes consider altering these indexes to NOT<br />

PADDED, rebuild the indexes and rebind dependent packages that may be able to exploit the<br />

index-only access.<br />

242 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

0<br />

NOT PADDED index impact on utility<br />

Table with four columns index VARCHAR(1)<br />

Load Reorg<br />

tablespace<br />

Reorg<br />

Index<br />

Rebuild<br />

Index<br />

Check<br />

Index<br />

CPU padded CPU not padded Elapsed padded Elapsed not padded<br />

Runstats<br />

Index


Alter Table Rotate Partition<br />

We executed and measured the following test cases (TC) on a 10 partition table space, a 50<br />

M row table, 1 PI and 0, 1, 3 NPIs:<br />

► TC1 - Delete all rows of partition 1 with SQL<br />

► TC2 - Alter table rotate partition<br />

► TC3 - Load replace with dummy input followed by alter table rotate partition<br />

See Figure 5-18 <strong>for</strong> the results of the measurements.<br />

Class 1 Elapsed Time<br />

(seconds)<br />

Rotate partition - Elapsed time comparison<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

TC1 TC2 TC3<br />

1 PI, 0 NPI 1 PI, 1 NPI 1 PI, 3 NPIs<br />

TC1 = Delete Part 1 from Table<br />

TC2 = Alter Table Alter Part Rotate First To Last<br />

TC3 = 1. Load Replace Part 1 w/ Dummy Infile<br />

2. Alter Table Alter Part Rotate First To Last<br />

TC3 can be up to 100 times faster depending on the number of NPIs<br />

Figure 5-18 Rotate partition - Elapsed time comparison<br />

In TC1 we delete all the rows from partition 1. The slight difference with TC2 is due to <strong>DB2</strong><br />

predicate evaluation. Also ROTATE uses delete on part 1 but does not have to evaluate a<br />

predicate. If part 1 is emptied first by a dummy LOAD REPLACE elapsed time improves<br />

dramatically. NPIs must be scanned to delete the keys related to rows of part 1, the more<br />

NPIs defined the higher the impact on elapsed time.<br />

Conclusion<br />

Rotate will issue deletes <strong>for</strong> the partition to be reused. Consider the impact on logging and<br />

per<strong>for</strong>mance. A DBD lock will be held <strong>for</strong> the duration of the ROTATE.<br />

Recommendations<br />

In order to reduce the impact on logging and speed up the delete process consider first<br />

archiving the data in the affected partition and running a LOAD table PART n REPLACE with<br />

a dummy input. Be aware that ROTATE cannot be undone. Backup your data be<strong>for</strong>e rotating.<br />

Chapter 5. Availability and capacity enhancements 243


REORG REBALANCE<br />

We executed and measured the following test cases (TC) on a 10 partition table space, a 50<br />

M row table, 8 partitions with 5 M rows, 1 partition with 1 M rows and 1 partition with 9 M rows,<br />

1 PI and 0, 1, 3 NPIs:<br />

► TC1 - REORG table space REBALANCE all partitions<br />

► TC2 - REORG table space REBALANCE partition 9 and 10<br />

See Figure 5-19 <strong>for</strong> the partition distribution be<strong>for</strong>e and after REORG REBALANCE.<br />

Reorg Rebalance… Partition Distribution<br />

Millions<br />

# Rows in Partitio<br />

10<br />

Figure 5-19 Partition distribution be<strong>for</strong>e and after REORG REBALANCE<br />

REORG REBALANCE resulted in an even distribution of rows over all partitions.<br />

See Figure 5-20 <strong>for</strong> the elapsed time measurement result.<br />

244 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

8<br />

6<br />

4<br />

2<br />

0<br />

Be<strong>for</strong>e Reorg Rebalance After Reorg Rebalance<br />

P-1 P-2 P-3 P-4 P-5 P-6 P-7 P-8 P-9 P-10<br />

Partition distribution : 8(5M) + 1(1M) + 1(9M)<br />

Resulted in even partition sizes


Class 1 Elapsed Tim<br />

(Seconds)<br />

Reorg Rebalance… Elapsed Time<br />

1000<br />

800<br />

600<br />

400<br />

200<br />

0<br />

Figure 5-20 REORG REBALANCE elapsed time<br />

TC1 TC2<br />

1 PI, 0 NPI 1 PI, 1 NPI 1 PI, 3 NPIs<br />

Partition distribution : 8(5M) + 1(1M) + 1(9M)<br />

TC1 - reorg tsp rebalance all parts<br />

TC2 - reorg tsp rebalance parts 9 and 10<br />

40% to 80% faster if Reorg Rebalance parts 9 and 10 only<br />

In test case 1 all partitions are read and updated even if not all partitions needed to be<br />

rebalanced. Depending on the number of NPIs REORG REBALANCE runs 40% to 80%<br />

faster if only partition 9 and 10 are rebalanced.<br />

Conclusion<br />

Rebalancing could be executed in prior versions of <strong>DB2</strong> by altering the partitioned index limit<br />

keys followed by a reorganization. But the affected partitions were placed in a REORGP state<br />

and the data was unavailable until the reorganization completed. Rebalancing can be done<br />

with SHRLEVEL REFERENCE and so the data remains available <strong>for</strong> readers almost all the<br />

time. Only during the switch phase, the data is unavailable. It is also during the switch phase<br />

that <strong>DB2</strong> updates the limit keys to reflect the new partition boundaries.<br />

Recommendations<br />

The use of rebalancing instead of altering the partitioned index key limits will enhance the<br />

availability of your data.<br />

Note: REORG REBALANCE might not be possible if the logical and physical partition<br />

numbers <strong>for</strong> the specified table space do not match. This situation can be created by a<br />

series of ALTER ROTATEs and ALTER ADD PARTs. The partition range that you specify<br />

on the REORG REBALANCE statement is a range of physical partitions. When<br />

rebalancing, <strong>DB2</strong> unloads, sorts, and reloads the data based on logical partition numbers.<br />

Message DSNU1129I is issued and REORG terminates.<br />

Chapter 5. Availability and capacity enhancements 245


5.4 Volatile table<br />

5.4.1 Conclusion<br />

<strong>DB2</strong> V6 introduced a new parameter, NPGTHRSH, which will cause the <strong>DB2</strong> Optimizer to<br />

favor index access <strong>for</strong> tables whose statistics indicate fewer than a given number of pages.<br />

For a given table, if NPAGES is fewer than the NPGTHRSH value, index access <strong>for</strong> the table<br />

will be preferred over a table space scan. After the initial install of ERP application packages,<br />

there are many empty or small tables which could grow rapidly in size. There are also a<br />

number of tables which are very volatile, meaning the number of rows can change very<br />

quickly and in large amounts. If a RUNSTATS is run on these tables when they are small, the<br />

<strong>DB2</strong> optimizer would favor a table space scan, which would be inappropriate when the table<br />

grows. Prior to this enhancement, the recommendation was to update the catalog statistics<br />

<strong>for</strong> volatile tables.<br />

<strong>DB2</strong> V8 introduces the VOLATILE keyword on the CREATE and ALTER statements. A volatile<br />

table is a table whose contents can vary from zero to very large at run time. <strong>DB2</strong> often does a<br />

table space scan or non-matching index scan when the data access statistics indicate that a<br />

table is small, even though matching index access is possible. This is a problem if the table is<br />

small or empty when statistics are collected, but the table is large when it is queried. In that<br />

case, the statistics are not accurate and can lead <strong>DB2</strong> to pick an inefficient access path.<br />

Forcing index access may be desired <strong>for</strong> tables whose size can vary greatly.<br />

In some applications, and often with SAP, a <strong>DB2</strong> table, called a cluster table, can be made up<br />

of logical rows, with each logical row consisting of multiple physical rows from that table. A<br />

logical row is identified by the primary key with a “sequence number” appended to provide the<br />

logical ordering of the physical rows. When accessing this type of table, the physical rows are<br />

intended to be accessed in this order (primary key + sequence number). This reduces the<br />

chance of deadlocks occurring when two applications attempt to lock the same logical row but<br />

touch the underlying physical rows in a different order. This means that certain types of<br />

access paths are disabled <strong>for</strong> these types of tables. They are: list prefetch hybrid join and<br />

multi-index access.<br />

Although volatile tables and the NPGTHRSH subsystem parameter both cause <strong>DB2</strong> to favor<br />

index access, they behave differently and have different granularities. NPGTHRSH favors<br />

index access on a subsystem level when the number of pages drops below the threshold. The<br />

NPGTHRSH subsystem parameter causes <strong>DB2</strong> to prefer index access in all of these cases,<br />

even when statistics are not accurate. Volatile tables are designated at the table level instead<br />

of the subsystem level, which allows you to favor index access <strong>for</strong> specific tables and specific<br />

queries because only those tables that are defined as volatile favor index access. Finally,<br />

volatile tables differ from the NPGTHRSH subsystem parameter by further restricting the<br />

types of access to preserve the access sequence that is provided by the primary key.<br />

5.4.2 Recommendations<br />

Use the VOLATILE keyword on the CREATE table statement instead of the NPGTHRSH<br />

DSNZPARM parameter in order to favor index access <strong>for</strong> volatile and cluster tables at the<br />

table level.<br />

5.5 Index enhancements<br />

With the table-controlled partitioning concept in <strong>DB2</strong> V8, clustering, being partitioned, and<br />

being the partitioning index are now separate concepts. When using table-controlled<br />

partitioning, a table does not require a partitioning index, since the partitioning is based on<br />

246 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


the PARTITION BY clause in the CREATE TABLE statement. Since the partitioning index is<br />

no longer required, another index may also be used as a clustering index.<br />

Remember that index-controlled partitioning is still supported in <strong>DB2</strong> V8 but several new<br />

enhancements are only supported when using table-controlled partitioning.<br />

We now review index terminology and classification.<br />

Indexes on table-controlled partitioned tables can be classified as follows:<br />

► Based on whether or not an index is physically partitioned:<br />

– Partitioned index: The index is made up of multiple physical partitions (not just index<br />

pieces)<br />

– Non-partitioned index: The index is a single physical data set (or multiple pieces)<br />

► Based on whether or not the columns in the index correlate with the partitioning columns<br />

of the table (the left most partitioning columns of the index are those specified in the<br />

PARTITION BY clause of the table):<br />

– Partitioning index: The columns in the index are the same as (and have the same<br />

collating sequence), or start with the columns in the PARTITION BY clause of the<br />

CREATE TABLE statement.<br />

– Secondary index: Any index in which the columns do not coincide with the partitioning<br />

columns of the table.<br />

– Data-partitioned secondary indexes: Any index defined with the PARTITIONED option<br />

(see later).<br />

► Based on whether or not the index determines the clustering of the data. Note that when<br />

using table-controlled partitioning:<br />

– Clustering index: The index determines the order in which the rows are stored in the<br />

partitioned table.<br />

– Non-clustering index: The index does not determine the data order in the partitioned<br />

table.<br />

5.5.1 Partitioned table space without index<br />

5.5.2 Clustering index<br />

Because the table definition of a table-controlled partitioned table is complete after executing<br />

the CREATE TABLE statement, no partitioning index is required. So you can have a<br />

table-controlled partitioned table without a partitioning index. Due to the non-unique nature of<br />

DPSIs it is advised to specify predicates on partitioning key columns in order to enable<br />

partition pruning from queries using predicates <strong>for</strong> DPSI columns.<br />

In <strong>DB2</strong> V8, any index on a table-controlled partitioned table can be the clustering index,<br />

including a secondary index. If predicates used to access the table controlled partitioned table<br />

do not refer to the partitioning columns, a clustering index can now be defined <strong>for</strong> these<br />

predicates.<br />

5.5.3 Clustering index always<br />

If no explicit clustering index is specified <strong>for</strong> a table, the V8 REORG utility recognizes the first<br />

index created on each table as the implicit clustering index when ordering data rows.<br />

Chapter 5. Availability and capacity enhancements 247


If explicit clustering <strong>for</strong> a table is removed (changed to NOT CLUSTER), that index is still used<br />

as the implicit clustering index until a new explicit clustering index is chosen.<br />

5.5.4 DPSI and impact on utilities and queries<br />

With <strong>DB2</strong> V7, secondary indexes on partitioned tables are non-partitioned indexes.<br />

Secondary indexes cannot be physically partitioned. They can only be allocated across<br />

multiple pieces to reduce I/O contention. <strong>DB2</strong> V8 introduces the ability to physically partition<br />

secondary indexes. The partitioning scheme introduced is the same as that of the table<br />

space. That is, there are as many index partitions in the secondary index as table space<br />

partitions, and index keys in partition “n” of the index reference only data in partition “n” of the<br />

table space. Such an index is called a Data-Partitioned Secondary Index (DPSI).<br />

Description<br />

When an index is created and no additional keywords are specified, the index is<br />

non-partitioned. If the keyword PARTITIONED is specified, the index is partitioned. The index<br />

is both data-partitioned and key-partitioned when it is defined on the partitioning columns of<br />

the table. Any index on a partitioned table space that does not meet the definition of a<br />

partitioning index is a secondary index. When a secondary index is created and no additional<br />

keywords are specified, the secondary index is non-partitioned (NPSI). If the keyword<br />

PARTITIONED is specified, the index is a data-partitioned secondary index (DPSI).<br />

You create a DPSI by specifying the new PARTITIONED keyword in the CREATE INDEX<br />

statement and defining keys on some columns that coincide with the partitioning columns of<br />

the table. When defining a DPSI, the index cannot be created as UNIQUE or UNIQUE<br />

WHERE NOT NULL. This is to avoid having to search each part of the DPSI to make sure the<br />

key is unique.<br />

Benefits of DPSIs are:<br />

► Allow partition-level operation <strong>for</strong> utilities operating on secondary indexes such as REORG<br />

INDEX, RUNSTATS INDEX<br />

► Eliminate contention on index pages <strong>for</strong> utilities operating on partition level with DPSI.<br />

► Utilize concurrent LOAD PART more efficiently while inserting DPSI keys<br />

► Eliminate the BUILD2 phase during Online REORG of a partition<br />

► Reduce data sharing overhead<br />

For a detailed description of DPSIs see <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever<br />

Wanted to Know, ... and More, SG24-6079.<br />

Per<strong>for</strong>mance<br />

In this section the per<strong>for</strong>mance impact of DPSIs on utilities and queries is evaluated.<br />

Per<strong>for</strong>mance measurement description<br />

For this measurement we used:<br />

► z/<strong>OS</strong> V1R3<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 in NFM<br />

► <strong>IBM</strong> z900 Series 2064 4-way processor<br />

► ESS model F20 with FICON channels<br />

Per<strong>for</strong>mance measurement result <strong>for</strong> utilities and DPSIs<br />

We used a partitioned table of 20 M rows with 10 partitions<br />

248 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► With one NPI or one DPSI<br />

► With 3 DPSIs and 2 NPIs<br />

► With 5 DPSIs or 5 NPIs<br />

The following measurement cases were run:<br />

► Load table<br />

► Reorg table space<br />

► Rebuild index<br />

► Check index<br />

► Runstats index<br />

Figure 5-21 shows the result of a measurement where one partition was loaded of a 20 M row<br />

table with 10 partitions and 1 NPI vs. 1 DPSI.<br />

time<br />

in<br />

seconds<br />

Load a partition of table of 20M rows 10<br />

partitions with 1 NPI and table with 1 DPSI<br />

80<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

CPU Elapsed time<br />

Table with 1 NPI<br />

62 76<br />

Table with 1 DPSI 28 25<br />

Figure 5-21 Load with 1 NPI vs. 1 DPSI<br />

The reduction in CPU of the test case with a DPSI is mostly due to better code method: Load<br />

of the DPSI (a page at the time) instead of Insert in the NPI case.<br />

In Figure 5-22 we compare the load of a single partition of a 20 M row table with 10 partitions<br />

with 5 NPIs or 5 DPSIs versus the load of the whole table.<br />

Chapter 5. Availability and capacity enhancements 249


Load table of 20M rows, 10 partitions with 5 NPI or 5 DPSI<br />

tim e<br />

in<br />

seconds<br />

8 0 0<br />

7 0 0<br />

6 0 0<br />

5 0 0<br />

4 0 0<br />

3 0 0<br />

2 0 0<br />

1 0 0<br />

Figure 5-22 Load with 5 NPIs vs. 5 DPSIs<br />

When we compare the single partition load to the previous test case with 1 NPI or 1 DPSI, a<br />

bigger reduction in CPU <strong>for</strong> 5 DPSIs compared to 5 NPIs is noticed because the index keys<br />

were loaded <strong>for</strong> all DPSI index physical partitions while keys were inserted into all 5 NPI index<br />

logical partitions during the Build phase. Contention on NPIs is possible.<br />

In case the whole table is loaded the DPSI case shows a slight increase in CPU compared to<br />

the NPI case. In this case 5 NPI data sets vs. 5 DPSI data sets are loaded.<br />

Figure 5-23 presents the measurement results of a reorganization of a partition of a 20 M<br />

rows table with 10 partitions and 1 NPI or 1 DPSI.<br />

Figure 5-23 REORG with 1 NPI vs. 1 DPSI<br />

250 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

0<br />

5 D P S I<br />

single part<br />

5 N P I<br />

single part<br />

5 D P S I<br />

w h o le<br />

ta b le<br />

5 N P I<br />

w h o le<br />

ta b le<br />

C P U 6 9 2 2 5 7 0 3 6 8 6<br />

Elapsed tim e 4 2 8 7 3 4 0 3 4 2<br />

Reorg a partition of table of 20M rows 10 partitions with 1<br />

NPI and table with 1 DPSI<br />

time<br />

in<br />

seconds<br />

80<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

CPU Elapsed time<br />

Table with 1 NPI 51 72<br />

Table with 1<br />

DPSI<br />

25 45


The reduction in CPU of DPSI is due to better code method: Load instead of INSERT as in<br />

the NPI case. Note that in the DPSI test case the BUILD2 phase is eliminated.<br />

In Figure 5-24 we compare the reorganization of a single partition of a 20 M rows table with<br />

10 partitions with 5 NPIs or 5 DPSIs versus the reorganization of the whole table.<br />

Reorg tablespace of 20M rows, 10 partitions with 5 DPSI or<br />

5 NPI<br />

time<br />

in<br />

seconds<br />

700<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

5 DPSI<br />

single part<br />

Figure 5-24 REORG with 5 NPIs vs. 5 DPSIs<br />

5 NPI<br />

single part<br />

5 DPSI<br />

whole table<br />

5 NPI<br />

whole table<br />

CPU 66 208 658 650<br />

Elapsed time 41 78 354 338<br />

The single partition reorganization compared to the previous reorganization test case with 1<br />

NPI or 1 DPSI shows a bigger reduction in CPU <strong>for</strong> 5 DPSIs compared to 5 NPIs because the<br />

index keys were loaded <strong>for</strong> all DPSI index physical partitions while keys were inserted to all 5<br />

NPI index logical partitions during the BUILD2 phase. Contention on NPIs is possible.<br />

In case the whole table is reorganized, the DPSI case shows a slight increase in CPU<br />

compared to the NPI case. In this case 5 NPI data sets vs. 50 DPSI data sets are loaded in<br />

the index Build phase.<br />

In Figure 5-25 we compare the rebuilding of a partition of a PI, NPI and DPSI.<br />

Chapter 5. Availability and capacity enhancements 251


Times in seconds<br />

20<br />

18<br />

16<br />

14<br />

12<br />

10<br />

8<br />

6<br />

4<br />

2<br />

0<br />

Figure 5-25 Rebuild index partition of PI, NPI and DPSI<br />

Equivalent per<strong>for</strong>mance between DPSI and PI is noticed, per<strong>for</strong>mance of NPI is impacted by<br />

the key Insert processing vs. Load of PI and DPSI partitions.<br />

In Figure 5-26 we compare the rebuilding of the complete PI, NPI and DPSI.<br />

seconds<br />

Figure 5-26 Rebuild index PI, NPI, and DPSI<br />

For the PI and DPSI indexes a parallel Unload, Sort and Build is executed. For the NPI<br />

Unload and Sort are done in parallel followed by a single Merge task and a single Build task<br />

of the NPI. Per<strong>for</strong>mance is equivalent <strong>for</strong> DPSI and PI but better compared to NPI.<br />

In Figure 5-27 check index on a partition of a PI, NPI and DPSI is compared.<br />

252 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Rebuild index partition of PI, NPI, and DPSI<br />

CPU Elapsed time<br />

PI 10 14<br />

NPI 14 18<br />

DPSI 11 14<br />

1 6 0<br />

1 4 0<br />

1 2 0<br />

1 0 0<br />

8 0<br />

6 0<br />

4 0<br />

2 0<br />

0<br />

Rebuild Index of PI, NPI, and DPSI<br />

C P U E la p s e d t im e<br />

P I 1 0 7 3 8<br />

N P I 1 3 8 6 1<br />

D P S I 1 1 8 3 6


time<br />

in<br />

second<br />

Check Index a partition of PI, NPI, and DPSI<br />

180<br />

160<br />

140<br />

120<br />

100<br />

80<br />

60<br />

40<br />

20<br />

0<br />

Figure 5-27 Check index PI, NPI and DPSI<br />

PI NPI DPSI PI part NPI part DPSI<br />

part<br />

Check index of a partition of DPSI showed equivalent per<strong>for</strong>mance as with partition of PI<br />

which had better per<strong>for</strong>mance compared to Check Index of a logical part of a NPI.<br />

In Figure 5-28 we compared executing RUNSTATS INDEX on a PI, NPI and DPSI and<br />

RUNSTATS INDEX on a partition of a PI, NPI and DPSI.<br />

Figure 5-28 Runstats index PI, NPI and DPSI<br />

CPU Elapsed time<br />

Runstats Index a partition of PI, NPI, and DPSI<br />

180<br />

160<br />

140<br />

120<br />

100<br />

time<br />

in<br />

seconds<br />

80<br />

60<br />

40<br />

20<br />

0<br />

PI NPI DPSI PI part NPI part DPSI<br />

part<br />

CPU Elapsed time<br />

Chapter 5. Availability and capacity enhancements 253


RUNSTATS INDEX PARTITION of a DPSI showed equivalent per<strong>for</strong>mance to a partition of a<br />

PI. Comparing to RUNSTATS INDEX of a logical part of a NPI, the per<strong>for</strong>mance was better.<br />

Per<strong>for</strong>mance measurement result <strong>for</strong> queries and DPSIs<br />

We executed queries against 3 partitioned tables with an NPI and a DPSI on the same<br />

columns. The measurements were done with and without parallelism.<br />

The tables used are:<br />

► CVR - 1,654,700 rows, 10 partitions<br />

► EVE - 931,174 rows, 6 partitions<br />

► PLC - 624,473 rows, 8 partitions<br />

Attention: Make sure PTF UQ93972 <strong>for</strong> APAR PQ92227, which addresses SQL<br />

per<strong>for</strong>mance problems with DPSIs, is applied.<br />

Table 5-3 shows the measurement results <strong>for</strong> the following query:<br />

SELECT COUNT(*) FROM CVR<br />

Table 5-3 NPI vs. DPSI SELECT COUNT query<br />

This is the case of an index scan. Almost the same number of index getpages are executed<br />

<strong>for</strong> DPSI as <strong>for</strong> NPI. The results shown are those of the second execution of the queries (data<br />

sets are all open) but the data is not preloaded. The query with predicates that only reference<br />

DPSI indexed columns experiences a reduction in CPU time of 23% compared to an NPI on<br />

the same columns. Since these queries are close to CPU bound, a similar reduction in<br />

elapsed time of 19% is experienced.<br />

The same query was also executed with parallelism enabled. The results are presented in<br />

Table 5-4.<br />

Table 5-4 NPI vs. DPSI SELECT COUNT query parallelism<br />

Parallelism helps quite a lot in improving the elapsed time because of the probing in parallel of<br />

the DPSI. The reduction in CPU is somewhat offset by the activation of parallelism, but the<br />

elapsed time improvement is 64%.<br />

Now we evaluate a query which qualifies data on NPI and DPSI columns in order to verify the<br />

overhead of DPSI over NPI:<br />

SELECT COUNT(*) FROM EVE, PLC WHERE EVE_DPSI>=PLC_DPSI AND PLC_DPSI = constant<br />

Table 5-5 shows the results <strong>for</strong> this query.<br />

254 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

NPI DPSI % difference<br />

Access path index only (2285 pages) index only (2302 pages) =<br />

CPU (sec.) 0.759703 0.587190 -23%<br />

Elapsed (sec.) 0.825141 0.668409 -19%<br />

NPI DPSI % difference<br />

Access path index only (2312 pages) index only (2342 pages) =<br />

CPU (sec.) 0.718432 0.657405 -9%<br />

Elapsed (sec.) 0.637515 0.231345 -64%


Table 5-5 DPSI overhead<br />

Access path PLC - index only<br />

EVE - index only<br />

The DPSI overhead is explained by <strong>DB2</strong> having to probe each DPSI partition in order to<br />

evaluate the predicates. The access path remains the same in both test cases.<br />

In order to illustrate an access path change from changing use of a NPI to a DPSI we<br />

evaluated the following query:<br />

SELECT COUNT(DISTINCT CSCD) FROM CVR<br />

Table 5-6 shows the measurement results.<br />

Table 5-6 DPSI access path change<br />

NPI DPSI % difference<br />

PLC - index only<br />

EVE - index only<br />

CPU (sec.) 0.021699 0.083861 + 281<br />

Elapsed (sec.) 0.037188 0.305458 + 721<br />

Index getpages 8 17,000<br />

NPI DPSI % difference<br />

Access path index only table space scan + sort<br />

CPU (sec.) 1.21221 8.30175 + 585<br />

Elapsed (sec.) 1.317186 24.67209 + 1773<br />

Getpages 2k index getpages 139k data getpages +<br />

29k work file getpages<br />

Conclusion<br />

Utility processing benefits from the use of DPSIs. Query processing using only the DPSI in<br />

the access path has to probe every partition of the DPSI to evaluate the predicates due to the<br />

non-unique nature of the DPSI. In a data sharing environment, if some workloads are partition<br />

and member specific, reduced data sharing overhead is possible with DPSIs as intersystem<br />

read/write interest on physical partitions can be eliminated vs. non-partitioned indexes, where<br />

keys belonging to different data partitions are spread throughout the non-partitioned index.<br />

Recommendations<br />

Replacing all NPIs by DPSIs is not the objective. NPIs will still prove to be useful. Utilities will<br />

definitely benefit from DPSIs while contention at the logical partition level is eliminated.<br />

Queries that combine predicates on the partitioning columns and the DPSI will per<strong>for</strong>m well.<br />

Explicitly coding the partitioning columns in the predicate allows the <strong>DB2</strong> optimizer to<br />

eliminate not qualifying partitions from the query. This is called partition pruning. Pruning can<br />

be deferred until execution time if host variables are used. The pruning takes place once the<br />

contents of the host variables are known.<br />

When using DPSIs part of the responsibility is shifted from DBA to development. Coding the<br />

correct predicates to allow <strong>for</strong> partition pruning is crucial to per<strong>for</strong>mance.<br />

The use of DPSIs versus NPIs is dictated by availability considerations. If, <strong>for</strong> example, even<br />

the outage due to the BUILD2 phase of an online REORG cannot be tolerated DPSIs are the<br />

solution.<br />

Chapter 5. Availability and capacity enhancements 255


Note that when the qualified partitions cannot be determined at BIND time because the literal<br />

value in the predicate is unknown (<strong>for</strong> example, because a host-variable, parameter marker,<br />

or special register is used), then <strong>DB2</strong> will determine what the qualified partitions are at<br />

execution time. By doing this, only the qualified partitions will be accessed, even if <strong>DB2</strong> could<br />

not determine which partitions were qualified at BIND time. (This enhancement does NOT<br />

require the use of REOPT(VARS)). In addition, the <strong>DB2</strong> access path selection has been<br />

enhanced to make use of all leading partitioning key columns when determining the qualified<br />

partitions. (Currently, only the first column of the partitioning key is used to determine which<br />

partitions qualify. This can result in more partitions being in the range of qualified partitions<br />

than actually do qualify.)<br />

This enhancement will not only benefit cases that use a DPSI to access the data, but any<br />

case where a partitioned table space was accessed with too many partitions qualified.<br />

5.6 Other availability enhancements<br />

Other <strong>DB2</strong> V8 availability enhancements and also recent enhancements introduced via<br />

maintenance are discussed in this section.<br />

5.6.1 More online DSNZPARMs<br />

In order to minimize downtime when making DSNZPARM parameter changes effective, <strong>DB2</strong><br />

V7 introduced the online change <strong>for</strong> subsystem parameters. This function allows you to load a<br />

new subsystem parameter load module into storage without recycling <strong>DB2</strong>. To do this, you<br />

can use the normal installation parameter update process to produce a new load module,<br />

which includes any desired changes to parameter values. You can then issue the -SET<br />

SYSPARM command to load the new module in order to affect the change.<br />

<strong>DB2</strong> V8 adds more online changeable parameters.<br />

Not all subsystem parameters are dynamically changeable. Refer to the Appendix of <strong>DB2</strong><br />

<strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 <strong>DB2</strong> Command Reference, SC18-7416, <strong>for</strong> a list of all parameters,<br />

the macros where they are defined, and whether or not they are changeable online.<br />

5.6.2 Monitor long running UR back out<br />

During restart processing, <strong>DB2</strong> issues progress messages during the <strong>for</strong>ward and backward<br />

phase of the restart. Message DSNR031I is issued in 2 minute intervals, showing the current<br />

log RBA being processed and the target RBA to complete the restart phase. With <strong>DB2</strong> V8, a<br />

new progress message is issued during the back out of postponed URs as well. This<br />

message is first issued after the process has at least exceeded one two minute interval and is<br />

repeated every two minutes until the back out process is complete.<br />

5.6.3 Monitor system checkpoints and log offload activity<br />

With <strong>DB2</strong> V7, you had the chance to monitor the actuality of system checkpoints and the<br />

status of the log offload activity using <strong>DB2</strong> command -DISPLAY LOG, which was introduced<br />

to <strong>DB2</strong> V6. Sometimes, however, there are situations where <strong>DB2</strong> stopped taking system<br />

checkpoints or was stuck during its log offload activity. Since both situations might cause<br />

problems during operations, <strong>DB2</strong> V8 provides you with new messages, which help you<br />

identify problems faster. In addition a new IFCID 0335 record is produced if a statistics class 3<br />

is active.<br />

256 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


5.6.4 Improved LPL recovery<br />

One source of unplanned outages that many <strong>DB2</strong> customers have struggled with is LPL<br />

(logical page list) pages. <strong>DB2</strong> puts pages into the LPL typically when I/O or coupling facility<br />

read or write errors are encountered. Once a page is entered into the LPL, that page is<br />

inaccessible until it is recovered. LPL recovery can be done using:<br />

► -START DATABASE command with SPACENAM option<br />

► RECOVER utility<br />

The -START DATABASE command drains the entire table space or partition, there<strong>for</strong>e making<br />

the entire page set or partition unavailable <strong>for</strong> the duration of the LPL recovery process even if<br />

only one page is in the LPL <strong>for</strong> that table space or partition. During the execution of the<br />

recover utility the table space or partition is unavailable.<br />

<strong>DB2</strong> V8 always attempts to automatically recover the LPL pages at the time that the pages<br />

are added to LPL. Those pages are deleted from the LPL when the automatic LPL recovery<br />

completes successfully.<br />

Even more important than automatic LPL recovery is that with <strong>DB2</strong> V8, during LPL recovery,<br />

all pages that are not in the LPL are accessible by SQL. Up to <strong>DB2</strong> V7, the entire table space<br />

or partition was unavailable during LPL recovery.<br />

5.6.5 Partitioning key update enhancement<br />

Some customers find the current implementation that allows update of values in partitioning<br />

key columns unusable because it does not allow concurrency if an update of a partitioning<br />

key changes the partition to which the row belongs.<br />

If the update requires moving the data row from one partition to another, <strong>DB2</strong> tries to take<br />

exclusive control of the objects to per<strong>for</strong>m the update by acquiring DRAIN locks. Because of<br />

this, no other application can access the range of partitions affected by update of values in<br />

partitioning key columns.<br />

Description<br />

Up to <strong>DB2</strong> V7, <strong>DB2</strong> takes the exclusive control to per<strong>for</strong>m the partitioned key update on:<br />

► The partition of the table space from which the row is moving, the partition of the table<br />

space to which the row is moving, and all partitions in between,<br />

► The partition of the partitioning index from which the partitioning key is moving, the<br />

partition of the partitioning index to which the partitioning key is moving, and all partitions<br />

in between<br />

► Non partitioning indexes defined on the table space.<br />

When updating values in columns that define the partitioning key, <strong>DB2</strong> V8 will NOT take<br />

exclusive control of the objects to per<strong>for</strong>m the update.<br />

If a row moves from one partition to another in a table that is a dependent table in a<br />

Referential Integrity relationship, there is a possibility of missing the row when checking <strong>for</strong> RI.<br />

To prevent this, if any update changes the row’s partition, a COMMIT duration S lock will be<br />

acquired on the parent table rows.<br />

Change to DSNZPARM parameter PARTKEYU<br />

The existing system parameter PARTKEYU specifies whether values in columns that<br />

participate in partitioning keys may be updated.<br />

► “YES” - Values in such columns may be updated. This is the default value.<br />

Chapter 5. Availability and capacity enhancements 257


► “NO” - Values in such columns may not be updated.<br />

► “SAME” - Values in such columns may be updated if and only if the update leaves the row<br />

belonging to the same partition.<br />

5.6.6 Lock holder can inherit WLM priority from lock waiter<br />

Assume that a transaction executes with a low WLM priority and makes updates to the<br />

database. Because it is updating, it must acquire X-locks on the rows of the pages that it<br />

modifies and then these X-locks are held until the transaction reaches a commit point. This is<br />

business as usual. If such a transaction holds an X-lock on a row in which another transaction<br />

is interested, the other transaction is <strong>for</strong>ced to wait until the first transaction (with a low WLM<br />

priority) commits. If the lock waiter per<strong>for</strong>ms very important work and is thus assigned a high<br />

WLM priority, it would be desirable that it is not slowed down by other transactions that<br />

execute in a low priority service class.<br />

To reduce the time the high priority transaction has to wait <strong>for</strong> that lock to be given up by the<br />

low priority transaction, it would be better if the waiting transaction could temporarily assign its<br />

own priority to the transaction that holds the lock until this transaction frees the locked<br />

resource.<br />

<strong>DB2</strong> V8 exploits WLM enqueue management. When a transaction has spent roughly half of<br />

the lock timeout value waiting <strong>for</strong> a lock, then the WLM priority of the transaction, which holds<br />

the lock, is increased to the priority of the lock waiter if the latter has a higher priority. If the<br />

lock holding transaction completes, it resumes its original service class. In case multiple<br />

transactions hold a common lock, this procedure is applied to all of these transactions.<br />

This function is implemented by the PTF <strong>for</strong> APAR PK19303, currently open.<br />

5.6.7 Detecting long readers<br />

Prior to <strong>DB2</strong> V8, <strong>DB2</strong> issues warning messages DSNR035I and DSNJ031I <strong>for</strong> a long running<br />

unit of recovery (UR) based on a number of system checkpoints taken since the beginning of<br />

the UR or the number of log records written.<br />

<strong>DB2</strong> V8 takes this one step further by also alerting you when you have a long-running reader<br />

in the system. It is probably less well known that not only updates have to commit frequently.<br />

Also read-only transactions should commit regularly. This is to allow utilities (that need to<br />

drain the object) to take control of the object, <strong>for</strong> example, during the switch phase of online<br />

REORG, the utility needs full control of the object to switch between the shadow data set and<br />

the actual data set used by <strong>DB2</strong>. For parallel operations, <strong>DB2</strong> records this in<strong>for</strong>mation only <strong>for</strong><br />

the originating task.<br />

A new system parameter LONG-RUNNING READER THRESHOLD, LRDRTHLD, is provided<br />

to specify the number of minutes that a read claim can be held by an agent be<strong>for</strong>e <strong>DB2</strong> will<br />

write an IFCID 313 record to report it as a long-running reader when statistics class 3 is<br />

active.<br />

IFCID 313 records all the LONG-RUNNING URs during a checkpoint or after exceeding the<br />

LOG RECORD’s written threshold without commit or all the LONG-RUNNING readers after<br />

exceeding the elapsed time threshold without commit.<br />

5.6.8 Explain a stored procedure<br />

This function allows you to run EXPLAIN without needing the authority to run the SQL to be<br />

explained.<br />

258 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Application programmers need to be able to make sure that SQL will per<strong>for</strong>m correctly, but in<br />

many cases they should not have the authority to read the actual data the SQL will be<br />

selecting or updating, <strong>for</strong> example, sensitive payroll data. OWNER(SYSADM)<br />

DYNAMICRULES(BIND) allows a user to EXPLAIN SQL statements without having the<br />

privilege to execute those SQL statements. However, the drawback of this setting is that the<br />

owner becomes the default qualifier <strong>for</strong> unqualified tables and views inside the SQL.<br />

PTFs UQ92322 (<strong>DB2</strong> V7) and UQ92323 (<strong>DB2</strong> V8) <strong>for</strong> the two APARs PQ90022 and<br />

PQ93821 add a new sample stored procedure called DSN8EXP that can be used to work<br />

around these constraints. DSN8EXP accepts an SQL statement of up to 32700 single-byte<br />

characters, passed as an input parameter from its caller. It first sets the current SQLID to<br />

locate EXPLAIN tables, then it issues the EXPLAIN statement <strong>for</strong> the input SQL. You can<br />

optionally let the stored procedure parse the SQL and add the qualifier ahead of those<br />

unqualified tables/views if there are any unqualified tables/views in the SQL. For<br />

insert-within-select and common table expressions, you need to disable the parsing function,<br />

and add the qualifier manually. DSN8EXP returns the SQLCODE, SQLSTATE, and diagnostic<br />

text from the EXPLAIN by output parameter.<br />

Visual Explain <strong>for</strong> <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 provides an easy-to-use interface to call the<br />

DSN8EXP stored procedure.<br />

Installation<br />

This PTF also provides a new sample job called DSNTEJXP that you can use to prepare and<br />

bind the DSN8EXP stored procedure. DSNTEJXP is not customized by the <strong>DB2</strong> installation<br />

CLIST. See the prolog of DSNTEJXP <strong>for</strong> guidance on customizing it to run at your site.<br />

Running DSN8EXP from Visual Explain<br />

In the Subsystem Parameters Panel there are fields to specify the stored procedure's schema<br />

name and procedure name. When all necessary fields are filled in the TuneSQL panel, note<br />

there is a field called "Table qualifier <strong>for</strong> Explain stored procedure:" When this field has a<br />

non-blank value, it is used as the input parameter QUALIFIER <strong>for</strong> the stored procedure and<br />

the parsing function will be enabled; if this field is blank, then the parsing is disabled. There is<br />

also a button called "Explain with stored procedure" shown in the TuneSQL panel, which<br />

actually invokes the EXPLAIN stored procedure. The original EXPLAIN button still issues<br />

normal Explain statements.<br />

5.6.9 PLAN_TABLE access via a <strong>DB2</strong> alias<br />

Up to V7, you did not have the capability to access Explain tables with different OWNER and<br />

QUALIFIER names. OWNER refers to the creator of the EXPLAIN table; QUALIFIER refers to<br />

the user that issues the EXPLAIN statement. A limitation of the EXPLAIN command has been<br />

that only the owner of the EXPLAIN tables can issue the EXPLAIN statement to populate<br />

his/her tables. This has prevented you from being able to consolidate your plan tables under a<br />

single AUTHID.<br />

Starting with V8, you can use the ALIAS mechanism to populate EXPLAIN tables created<br />

under a different AUTHID. The following external EXPLAIN tables can now have aliases<br />

defined on them:<br />

► PLAN_TABLE<br />

► DSN_STATEMNT_TABLE<br />

► DSN_FUNCTION_TABLE<br />

The alias name must have the <strong>for</strong>mat userid.table_name where tablename can be<br />

PLAN_TABLE, DSN_STATEMNT_TABLE or DSN_FUNCTION_TABLE.<br />

Chapter 5. Availability and capacity enhancements 259


5.6.10 Support <strong>for</strong> more than 245 secondary AUTHIDs<br />

With PTF UQ92698 <strong>for</strong> APAR PQ90147, support <strong>for</strong> 1,012 secondary authorization ids is<br />

provided. The connection and sign on exits DSN3@ATH and DSN3@SGN can supply 1,012<br />

secondary authorization IDs in the AIDL, which will be used in <strong>DB2</strong> authorization checking.<br />

Description<br />

<strong>DB2</strong> V8 will be updated to support 1,012 secondary authorization IDs. Customers may need<br />

to review their modified connection and sign-on exits, DSN3@ATH and DSN3@SGN, to see if<br />

changes are required to support 1,012 secondary authorization IDs. <strong>IBM</strong> supplied samples<br />

DSN3SATH and DSN3SSGN do not require changes to support 1,012 secondary<br />

authorization ids.<br />

260 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 6. Utilities<br />

The utilities have all been enhanced to support all other major enhancements that <strong>DB2</strong> V8<br />

has introduced. For instance, extensive updates have been required to provide support <strong>for</strong><br />

long names, Unicode, 64-bit addressing, the new data partitioning techniques, online schema<br />

evolution, and system point-in-time recovery. Refer to “Related publications” on page 425 <strong>for</strong><br />

details.<br />

In this chapter we concentrate on availability and per<strong>for</strong>mance aspects of V8 utilities:<br />

► Online CHECK INDEX: CHECK INDEX with option SHRLEVEL CHANGE increases<br />

availability and satisfies the requirement of customers who cannot af<strong>for</strong>d the application<br />

outage. Its also dramatically cuts down elapsed time due to parallel processing and usage<br />

of FlashCopy V2.<br />

► LOAD and REORG: With <strong>DB2</strong> V8, LOAD and REORG utilities have the option<br />

SORTKEYS as a default, this provides per<strong>for</strong>mance improvement <strong>for</strong> multiple index key<br />

sort.<br />

► LOAD and UNLOAD delimited input and output: This usability and <strong>DB2</strong> family<br />

compliance enhancement makes it much easier to move data into <strong>DB2</strong> with good<br />

per<strong>for</strong>mance.<br />

► RUNSTATS enhancements: The RUNSTATS utility adds the new functionality of<br />

calculating the frequencies <strong>for</strong> non-indexed columns. It updates <strong>DB2</strong> catalog tables and<br />

leads to better access path selection <strong>for</strong> queries.<br />

► Cross Loader: This functionality enables you to use a single LOAD job to transfer data<br />

from one location to another location or from one table to another table at the same<br />

location. A new PTF <strong>for</strong> V7 and V8 provides a large per<strong>for</strong>mance boost to cross loader<br />

per<strong>for</strong>mance.<br />

► For the new BACKUP and RESTORE SYSTEM utilities, introduced to ease the<br />

implementation of point-in-time recovery, see 5.1, “System level point-in-time recovery” on<br />

page 218.<br />

All these functions are available in CM except <strong>for</strong> BACKUP and RESTORE SYSTEM.<br />

6<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 261


6.1 Online CHECK INDEX<br />

Online CHECK INDEX is a new capability of <strong>DB2</strong> V8, added by APARs PQ92749 (PTF<br />

UK04683) and PQ96956 (still OPEN), which allows you to have read-write access to<br />

applications during CHECK INDEX and contributes to decreasing read-only time <strong>for</strong> users.<br />

This function satisfies the high availability requirement of users with very large tables who<br />

cannot af<strong>for</strong>d the application outage caused by the extensive read-only time required to run<br />

the normal CHECK INDEX.<br />

CHECK INDEX is an online utility which is used to test whether an index is consistent with its<br />

data. It is generally useful after a conditional restart or point-in-time recovery. It is also<br />

recommended to run CHECK INDEX be<strong>for</strong>e CHECK DATA, especially if you specify DELETE<br />

YES. Running CHECK INDEX be<strong>for</strong>e CHECK DATA ensures that the indexes that CHECK<br />

DATA uses are valid. In <strong>DB2</strong> V8 the utility statement CHECK INDEX was enhanced to<br />

designate the current read-only behavior as SHRLEVEL REFERENCE, and designate a<br />

reduction of restricted availability with the new SHRLEVEL CHANGE option. In addition<br />

CHECK INDEX provides a parallel processing structure similar to REBUILD INDEX.<br />

SHRLEVEL REFERENCE and SHRLEVEL CHANGE<br />

There are two options to indicate the type of access that is allowed <strong>for</strong> objects to be checked<br />

during the procedure. Figure 6-1 shows the utility process with the two options.<br />

indexes<br />

tablespaces<br />

UNLOAD<br />

phase<br />

unload index<br />

entries<br />

Figure 6-1 CHECK INDEX SHRLEVEL REFERENCE and SHRLEVEL CHANGE<br />

If you specify SHRLEVEL REFERENCE, which is also the default, the application can read<br />

from but cannot write to the index, table space, or partition that is to be checked.<br />

262 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CHECK INDEX SHRLEVEL REFERENCE<br />

SORT<br />

phase<br />

Sort index<br />

entries<br />

Temporary work datasets<br />

CHKIDX<br />

phase<br />

Scan tablespace<br />

data to validate<br />

CHECK INDEX SHRLEVEL CHANGE<br />

SNAPSHOT COPY (e.g., FlashCopy 2)<br />

tablespaces<br />

tablespaces Shadow dataset Shadow dataset<br />

tablespaces<br />

tablespaces<br />

UNLOAD<br />

phase<br />

unload from<br />

table space<br />

to workfile<br />

SORT<br />

phase<br />

Sort index<br />

keys<br />

MERGE<br />

phase<br />

Merge index<br />

keys (only<br />

in NPI)<br />

CHKIDX<br />

phase<br />

Scan index<br />

to validate<br />

indexes<br />

Temporary work datasets<br />

indexes


If you specify SHRLEVEL CHANGE, the applications can read from and write to the index,<br />

table space or partition that is being checked. The phases of processing inside CHECK<br />

INDEX differ in SHRLEVEL REFERENCE and SHRLEVEL CHANGE. In the case of<br />

SHRLEVEL REFERENCE, <strong>DB2</strong> unloads the index entries, sorts the index entries, and scans<br />

the data to validate index entries. On the other hand, SHRLEVEL CHANGE first goes to the<br />

table space data set and unloads the data and sorts the index keys and merges (if the index is<br />

non-partitioned), and then scans the index to validate.<br />

CHECK INDEX with option SHRLEVEL CHANGE per<strong>for</strong>ms the following actions:<br />

► Issues QUIESCE WRITE YES <strong>for</strong> the specified object and all of its indexes (this drains the<br />

writers so no updates are allowed <strong>for</strong> a while)<br />

► Invokes DFSMSdss at the data set level to copy the table space and all indexes to shadow<br />

data sets<br />

Note: Online CHECK INDEX will use FlashCopy V2 if available, otherwise concurrent<br />

copy will be used, this can elongate the read-only time.<br />

► Allows write access to the specified object and indexes<br />

► Runs CHECK INDEX on the shadow data sets<br />

Tip: FlashCopy V2 is needed since it supports data set copy (FlashCopy V1 works only at<br />

the volume level). Another advantage is that the source and target of a FlashCopy V2 can<br />

be a different logical subsystem within the Enterprise Storage System.<br />

Index processing with SHRLEVEL CHANGE<br />

SHRLEVEL CHANGE has a new architecture. SHRLEVEL REFERENCE unload phase<br />

unloads keys from the index and the check phase compares sorted keys against the data via<br />

tablespace scan. SHRLEVEL CHANGE unload phase does a table space scan extracting<br />

keys and the check phase compares sorted keys against the keys in the index.<br />

CHECK INDEX in V8 can provide parallel processing like REBUILD INDEX, which minimizes<br />

elapsed time <strong>for</strong> checking the data and indexes. If you specify more than one index to check<br />

and the SHRLEVEL CHANGE option, CHECK INDEX checks the indexes in parallel unless<br />

constrained by available memory or sort work files. Checking indexes in parallel reduces the<br />

elapsed time <strong>for</strong> a CHECK INDEX job by sorting the index keys and checking multiple indexes<br />

in parallel, rather than sequentially.<br />

It is important <strong>for</strong> parallel processing to specify appropriate values in the SORTDEVT and<br />

SORTNUM parameter. SORTDEVT specifies the device type <strong>for</strong> temporary data sets that are<br />

to be dynamically allocated by the DFSORT. SORTNUM can specify the number of temporary<br />

data sets dynamically allocated by the sort program (DFSORT). Example 6-1 is a sample JCL<br />

of CHECK INDEX.<br />

Example 6-1 Sample JCL of CHECK INDEX SHRLEVEL CHANGE<br />

//CHKIDXB EXEC PGM=DSNUTILB,REGION=4096K,PARM='SSTR,CHKINDX1'<br />

//SYSPRINT DD SYSOUT=A<br />

//SYSUDUMP DD SYSOUT=A<br />

//UTPRINT DD SYSOUT=A<br />

//DSNTRACE DD SYSOUT=A<br />

//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(5,2)),VOL=SER=SCR03<br />

//SYSOUT DD UNIT=SYSDA,SPACE=(CYL,(5,2)),VOL=SER=SCR03<br />

//SORTLIB DD DISP=SHR,DSN=SYS1.SORTLIB<br />

Chapter 6. Utilities 263


SORTOUT DD UNIT=SYSDA,SPACE=(CYL,(5,2)),VOL=SER=SCR03<br />

//SYSERR DD UNIT=SYSDA,SPACE=(CYL,(5,2)),VOL=SER=SCR03<br />

//SYSIN DD *<br />

LISTDEF CHKIDXB_LIST INCLUDE INDEXSPACE DBOT55*.* ALL<br />

CHECK INDEX LIST CHKIDXB_LIST SHRLEVEL CHANGE<br />

WORKDDN SYSUT1<br />

SORTDEVT SYSDA<br />

SORTNUM 4<br />

/*<br />

You should estimate the size of the sort work file which you write in the SORTWKnn DD<br />

statement of the JCL. If a sort is required, you must provide the DD statement that the sort<br />

program requires <strong>for</strong> the temporary data sets.<br />

Note: To find the size of the sort work, the following steps should be taken.<br />

1. For each table, multiply the number of records in the table by the number of indexes on<br />

the table that need to be checked.<br />

2. Add the products that you obtain in step 1.<br />

3. Add 8 to the length of the longest key. For non padded indexes, the length of the longest<br />

key is the maximum possible length of the key with all varying-length columns in the key<br />

padded to their maximum length, plus 2 bytes <strong>for</strong> each varying-length column.<br />

4. Multiply the sum from step 2 by the sum from step 3.<br />

Availability enhancement<br />

To improve availability, the DRAIN_WAIT, RETRY, and RETRY_DELAY parameters were<br />

added to CHECK INDEX. This is similar to online REORG. Rather than waiting the lock time<br />

out time, the utility multiplier <strong>for</strong> threads to relinquish the write claim, the utility will wait the<br />

DRAIN_WAIT value to get all writers drained and if the drain is not successful, wait the<br />

specified delay, and then retry the specified number of times. This will lessen the impact on<br />

applications when the utility is unable to drain all objects.<br />

Recommendation in creating shadow data sets<br />

When you execute the CHECK INDEX utility with the SHRLEVEL CHANGE option, the utility<br />

uses shadow data sets. For user-managed data sets, you must preallocate the shadow data<br />

sets be<strong>for</strong>e you execute CHECK INDEX SHRLEVEL CHANGE.<br />

If a table space, partition, or index that resides in <strong>DB2</strong>-managed data sets and shadow data<br />

sets does not already exist when you execute CHECK INDEX, <strong>DB2</strong> creates the shadow data<br />

sets. At the end of CHECK INDEX processing, the <strong>DB2</strong>-managed shadow data sets are<br />

deleted. We recommend you create the shadow data set in advance <strong>for</strong> <strong>DB2</strong>-managed data<br />

sets also, especially <strong>for</strong> the shadow data sets of the logical partitions of non-partitioned<br />

secondary indexes.<br />

See <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Utility Guide and Reference, SC18-7427, <strong>for</strong> more<br />

in<strong>for</strong>mation about this topic.<br />

6.1.1 Per<strong>for</strong>mance measurement<br />

Several per<strong>for</strong>mance studies have been done about online CHECK INDEX. Here we describe<br />

the measurement environment and results.<br />

Test environment and scenarios<br />

264 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


► Configuration<br />

– <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 NFM<br />

– Non-data sharing<br />

– z/<strong>OS</strong> Release 1.5<br />

– DFSMSdss V1R5<br />

– <strong>IBM</strong> z900 Series 2064 4-way processor<br />

– ESS 800 DASD<br />

– FlashCopy V2<br />

► Workload <strong>for</strong> measurement<br />

– 20 M rows, 6 indexes, 1 table space with 10 partitions<br />

► Measurement scenarios<br />

– CHECK INDEX SHRLEVEL(REFERENCE), CHECK INDEX SHRLEVEL(CHANGE)<br />

against<br />

Partitioned Index<br />

Non-partitioned index<br />

All indexes (6) of the table space<br />

– Concurrent CHECK INDEX SHRLEVEL(REFERENCE) PART of all partitions of the<br />

table space versus single CHECK INDEX SHRLEVEL(CHANGE) against<br />

Partitioned index<br />

Non-partitioned index<br />

CHECK INDEX measurement results and study<br />

We look at several measurements using and not using FlashCopy, and executing CHECK<br />

INDEX on concurrent partitions.<br />

SHRLEVEL CHANGE with FlashCopy vs. SHRLEVEL REFERENCE<br />

This test case measures the CPU and elapsed time to compare CHECK INDEX with option<br />

SHRLEVEL CHANGE using FlashCopy V2 to CHECK INDEX with option SHRLEVEL<br />

REFERENCE. The results of this test case are shown in Figure 6-2. SHRLEVEL CHANGE<br />

using FlashCopy reduces the elapsed time dramatically.<br />

The observations of this study are as follows:<br />

► With the SHRLEVEL CHANGE option, <strong>DB2</strong> uses parallel tasks in the execution of the<br />

utility. In the case of a partitioned index (PI), the UNLOAD, SORT and CHECKIDX tasks<br />

are processed in parallel in each partition of the table space. In the case of a<br />

non-partitioned index (NPI), the UNLOAD and SORT tasks are processed in parallel, like<br />

<strong>for</strong> PI, but the CHECKIDX and MERGE phases do not use parallel processing.<br />

► Most CPU time improvement in SHRLEVEL CHANGE of partitioned index comes from the<br />

CHECKIDX phase. Also SHRLEVEL CHANGE of non-partitioned index improves CPU<br />

time in the CHECKIDX phase in comparison with SHRLEVEL REFERENCE, but the total<br />

CPU time increases in SHRLEVEL CHANGE because of SORT and MERGE phases. The<br />

MERGE phase exists only in the case of a non-partitioned index and SHRLEVEL<br />

CHANGE.<br />

If we only look at the CHECKIDX phase, we can say that SHRLEVEL CHANGE improved<br />

CPU time significantly both in PI and NPI. SHRLEVEL CHANGE makes the total elapsed<br />

time decrease dramatically both in PI and NPI. A PI can benefit from the per<strong>for</strong>mance<br />

improvement of online CHECK INDEX more than an NPI.<br />

► CHECK INDEX 6 indexes of the table space with SHRLEVEL CHANGE has 18 tasks.<br />

– UNLOAD 6 indexes in parallel<br />

Chapter 6. Utilities 265


– SORT 6 indexes in parallel<br />

– CHECK 6 indexes in parallel<br />

time in seconds<br />

Figure 6-2 SHRLEVEL CHANGE vs. SHRLEVEL REFERENCE with FlashCopy<br />

SHRLEVEL CHANGE w/o FlashCopy vs. SHRLEVEL REFERENCE<br />

This test case measures the CPU and elapsed time comparing CHECK INDEX with option<br />

SHRLEVEL CHANGE without FlashCopy to CHECK INDEX with option SHRLEVEL<br />

REFERENCE. DFSMSdss does not find FlashCopy V2 enabled in the ESS and reverts to<br />

concurrent copy. In this case the elapsed time of SHRLEVEL CHANGE increases<br />

significantly. The results are shown in Figure 6-3.<br />

266 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

900<br />

800<br />

700<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

Check Index SHRLEVEL CHANGE with FlashCopy<br />

versus SHRLEVEL REFERENCE<br />

PI (10 partitions) NPI 6 indexes<br />

CPU SHRLEVEL(REFERENCE) CPU SHRLEVEL(CHANGE)<br />

Elapsed time SHRLEVEL(REFERENCE) Elapsed time SHRLEVEL(CHANGE)


time in seconds<br />

6.1.2 Conclusion<br />

180<br />

160<br />

140<br />

120<br />

100<br />

Figure 6-3 SHRLEVEL CHANGE vs. SHRLEVEL REFERENCE w/o FlashCopy<br />

Online CHECK INDEX (SHRLEVEL CHANGE) dramatically cuts down elapsed time. The first<br />

reason is that the parallel processing structure minimizes elapsed time in cross checking the<br />

data and indexes. The second reason is using FlashCopy V2. Compared to online CHECK<br />

INDEX with a non-partitioned index, online CHECK INDEX with a partitioned index could<br />

provide better per<strong>for</strong>mance. The most important aspect from the availability point of view is<br />

that using CHECK SHRLEVEL(CHANGE) with FlashCopy 2 the table and the indexes are<br />

available <strong>for</strong> RW after a few seconds, while with SHRLEVEL(REFERENCE) they are both in<br />

UTRO <strong>for</strong> most of execution time.<br />

Another study shows the better per<strong>for</strong>mance of CHECK INDEX with SHRLEVEL CHANGE in<br />

one task, when compared to CHECK INDEX with SHRLEVEL REFERENCE as concurrent<br />

jobs of each table space partition. It means you should always choose SHRLEVEL CHANGE<br />

<strong>for</strong> shorter CPU and elapsed time, rather than SHRLEVEL REFERENCE, when FlashCopy<br />

V2 is available.<br />

The two options have a different behavior:<br />

► SHRLEVEL REFERENCE Unload phase unloads keys from the indexes and then the<br />

Check phase compares sorted keys against the data via tablespace scan.<br />

► SHRLEVEL CHANGE Unload phase does a tablespace scan extracting keys and then the<br />

Check phase compares sorted keys against the keys in the index.<br />

6.1.3 Recommendations<br />

80<br />

60<br />

40<br />

20<br />

0<br />

Check Index SHRLEVEL CHANGE versus<br />

SHRLEVEL REFERENCE no FlashCopy<br />

PI NPI<br />

CPU SHRLEVEL(REFERENCE) CPU SHRLEVEL(CHANGE)<br />

Elapsed time SHRLEVEL(REFERENCE) Elapsed time SHRLEVEL(CHANGE)<br />

Use online CHECK INDEX whenever availability is needed. You should use online CHECK<br />

INDEX in conjunction with FlashCopy V2, otherwise concurrent copy is invoked which<br />

increases elapsed time and elongates the time when the data and index are read-only. To<br />

Chapter 6. Utilities 267


make <strong>DB2</strong> take the maximum parallelism in sort tasks it is recommended to estimate the sort<br />

work data set size correctly.<br />

Note: APAR PQ92749 and PQ96956 provide the CHECK INDEX availability<br />

enhancement.<br />

6.2 LOAD and REORG<br />

SORTKEYS <strong>for</strong> LOAD and REORG, and SORTDATA <strong>for</strong> REORG are keywords which<br />

generally contribute to better per<strong>for</strong>mance. In V7 SORTKEYS and SORTDATA were not the<br />

default, so you had to specify explicitly these parameters to activate the methods providing<br />

better per<strong>for</strong>mance. In V7 if SORTKEYS is not specified, and if data is 100% clustered and<br />

there is only one index on the table, LOAD utilities skip the SORT phase. If you want to exploit<br />

the functions, you need to change the utility jobs to add these keywords. In V8, SORTKEYS in<br />

the LOAD utility is the default and SORTDATA and SORKEYS are the default in the REORG<br />

utility. The SORT phase is en<strong>for</strong>ced in LOAD and REORG in V8.<br />

SORTKEYS cuts down the elapsed time of the index key sort by reducing I/O to the work file,<br />

since using SORTKEYS index keys are passed in memory rather than written to the work file.<br />

In addition, SORTKEYS provides a method of parallel index build. If there is more than one<br />

index on your table space or partition, it reduces the elapsed time of LOAD jobs.<br />

SORTDATA in the REORG utility specifies that the data is to be unloaded by a table space<br />

scan, and sorted in clustering order. This allows a consistent execution time <strong>for</strong> REORG and<br />

good per<strong>for</strong>mance whether the data is disorganized or not.<br />

6.2.1 LOAD with default per<strong>for</strong>mance measurement<br />

The following per<strong>for</strong>mance measurement has been done to observe LOAD per<strong>for</strong>mance with<br />

the default option of SORTKEYS. The purpose of the measurement is to assess the<br />

per<strong>for</strong>mance benefit of the SORTKEYS method provided as default. In this measurement we<br />

run a comparison of LOAD utilities in V7 and V8 over table spaces with 1 index, 2 indexes,<br />

and 6 indexes. The following is the description of our test environment.<br />

► 1 partitioned table with 10 partitions<br />

► 1,000,000 rows in one partition (total 10 million rows) and 118 byte row size<br />

► 26 columns of CHAR, INTEGER, and DECIMAL data type<br />

Figure 6-4 summarizes the results.<br />

LOAD executed against the table space with just one index shows up to 11% CPU<br />

degradation and 7% elapsed time degradation in V8 compared to V7. When more than 1<br />

index exists, V8 per<strong>for</strong>ms better in terms of CPU and elapsed time. The dramatic elapsed<br />

time reduction in V8 with 6 indexes comes from parallel processing. One thing to be<br />

considered is that more work file space is needed to accommodate parallel processing.<br />

268 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


time in second<br />

500<br />

450<br />

400<br />

350<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

6.2.2 Conclusion<br />

Figure 6-4 LOAD with default SORTKEYS<br />

In V8, SORT parameters are always en<strong>for</strong>ced, this provides per<strong>for</strong>mance improvement<br />

because of shorter I/O in index key sort and parallel index build. However, if the index keys<br />

are already sorted in perfect order or there is only one index in the table space, SORTKEYS<br />

does not provide much advantage.<br />

6.2.3 Recommendations<br />

LOAD with default SORTKEYS per<strong>for</strong>mance<br />

V7 one index V8 one index V7 2 indexes V8 2 indexes V7 6 indexes V8 6 indexes<br />

CPU Elapsed time<br />

You take advantage of the high per<strong>for</strong>mance of SORT parameters, if more than one index<br />

exists in a table space.<br />

To improve SORT per<strong>for</strong>mance during LOAD, you can also specify the appropriate value in<br />

the SORTKEYS option. The SORTKEYS option is an estimate of the number of keys <strong>for</strong> the<br />

job to sort, so that the index keys are passed in memory and avoid I/Os to the work file. To<br />

read how to estimate the number of keys, refer to topic Improved per<strong>for</strong>mance with<br />

SORTKEYS in <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Utility Guide and Reference, SC18-7427.<br />

Also you should not specify sort work data set like SORTWKxx DD statements, while using<br />

SORTKEY, make sure <strong>DB2</strong> uses memory instead of sort work data sets.<br />

See the in<strong>for</strong>mational APAR II14047 <strong>for</strong> useful in<strong>for</strong>mation on the changes of using DFSORT<br />

by <strong>DB2</strong> V8 utilities.<br />

Note: With PTF UK03983 <strong>for</strong> APAR PK04076, LOAD sort is avoided <strong>for</strong> LOAD SHRLEVEL<br />

NONE if data is sorted and only one index exists.<br />

Chapter 6. Utilities 269


6.3 LOAD and UNLOAD delimited input and output<br />

In V7, the LOAD utility input file is required to be of positional <strong>for</strong>mat. If you want to move data<br />

to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, you must write a program to convert the data into the positional <strong>for</strong>mat that<br />

the LOAD utility can understand, or use INSERT statements, thereby not exploiting the<br />

per<strong>for</strong>mance advantage that the LOAD utility offers <strong>for</strong> a large amount of data.<br />

In <strong>DB2</strong> V8, the LOAD utility is enhanced to accept data from a delimited file. The UNLOAD<br />

utility is also enhanced to produce a delimited file when unloading the data. These<br />

enhancements help to simplify the process of moving or migrating data into and out of <strong>DB2</strong><br />

<strong>for</strong> z/<strong>OS</strong>.<br />

Re<strong>for</strong>matting data <strong>for</strong> <strong>DB2</strong> (be<strong>for</strong>e V8)<br />

Re<strong>for</strong>matting data <strong>for</strong> <strong>DB2</strong> is a very time consuming procedure. Prior to <strong>DB2</strong> V8, you can load<br />

data only from an input flat file, either a partitioned data set or a regular flat file. The file must<br />

include length in<strong>for</strong>mation <strong>for</strong> those fields that become VARCHAR columns in a <strong>DB2</strong> table.<br />

Re<strong>for</strong>matting the data <strong>for</strong> <strong>DB2</strong> means adding 2 bytes of binary data to the beginning of such a<br />

field. These 2 bytes contain a binary number representing the length of the data within the<br />

field. The following steps were needed to re<strong>for</strong>mat data <strong>for</strong> <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>.<br />

1. Unload the data from a table residing on another relational database and transmit the file<br />

to z/<strong>OS</strong> and store it (either as member in a PDS, or as a sequential file).<br />

2. Write a program, possibly using REXX, to determine the length of the variable character<br />

data and generate the 2 byte binary length fields. Also the program should output a file<br />

with the positions and length of the fields which can be useful to set up LOAD utility<br />

statements.<br />

3. Prepare <strong>for</strong> a input control file used <strong>for</strong> a program, describing where is the beginning of<br />

each field and what kind of data will be encountered in input file records.<br />

4. Run the program, input the data from the other RDBMS and the input control file.<br />

5. Setup the LOAD utility control statement using the output of the program and specifying<br />

the generated input data in INDDN in the JCL statement, and then run the LOAD utility to<br />

load data into <strong>DB2</strong>. See Example 6-2 <strong>for</strong> an example of the LOAD statement.<br />

Example 6-2 Sample LOAD statement<br />

LOAD DATA INDDN(CPRSRECS) LOG NO RESUME YES<br />

INTO TABLE PAOLOR2.DATA_TYPE<br />

(DATA_TYPE P<strong>OS</strong>ITIN(1) VARCHAR,<br />

DESCRIPTION P<strong>OS</strong>ITION(9) VARCHAR)<br />

Delimited file input and output<br />

In V8, the LOAD utility accepts a delimited file, and the UNLOAD utility can produce a<br />

delimited file. Most relational databases including <strong>DB2</strong> on Linux, UNIX, Windows, Oracle®<br />

and Sybase can unload data in delimited <strong>for</strong>mat, where each record is a row, and columns<br />

are separated by commas, <strong>for</strong> example. So this enhancement eases dramatically the import<br />

or export of a large amount of data from other operating system plat<strong>for</strong>ms to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

and vice versa. And also this eliminates the requirement to write a program to convert<br />

non-z/<strong>OS</strong> plat<strong>for</strong>m data into positional <strong>for</strong>mat <strong>for</strong> the LOAD utility, so you can avoid the data<br />

re<strong>for</strong>matting process described above.<br />

For instance, if you want to move data from a spreadsheet from a Windows workstation to<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, you need to take the following steps:<br />

► Save the spreadsheet data in comma separated value (CSV) <strong>for</strong>mat<br />

270 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


6.3.1 Per<strong>for</strong>mance<br />

► Upload the saved data to the host in one of the following <strong>for</strong>mats:<br />

– text (the data is converted from ASCII to EBCDIC be<strong>for</strong>e it is stored on the host)<br />

– binary (the data is stored in ASCII)<br />

To upload the data, you can either use your terminal emulator’s file transfer program, or<br />

use FTP.<br />

► Create a <strong>DB2</strong> table with the appropriate number of columns and data types (consistent<br />

with the number of cells and the types of data stored in a spreadsheet), either as an<br />

EBCDIC (default option), or an ASCII table.<br />

► Use the LOAD utility with FORMAT DELIMITED specified as follows:<br />

– If the spreadsheet data is uploaded to the host in text <strong>for</strong>mat, specify it as shown in<br />

Example 6-3.<br />

Example 6-3 LOAD DATA text <strong>for</strong>mat<br />

LOAD DATA INTO TABLE tablename<br />

FORMAT DELIMITED<br />

– If the spreadsheet data is uploaded to the host in binary <strong>for</strong>mat, specify it as shown in<br />

Figure 6-4.<br />

Example 6-4 LOAD DATA binary <strong>for</strong>mat<br />

LOAD DATA INTO TABLE tablename<br />

FORMAT DELIMITED ASCII<br />

If you want to move the data from <strong>DB2</strong> to a spreadsheet, you take the following steps:<br />

► Use the UNLOAD utility with DELIMITED specified as follows:<br />

– If you want the unloaded data to be in EBCDIC <strong>for</strong>mat, specify as shown in<br />

Example 6-5. The data and the delimiters are unloaded in EBCDIC. Transmit the data<br />

to the workstation to be used by the spreadsheet in text <strong>for</strong>mat.<br />

Example 6-5 UNLOAD DATA in EBCDIC <strong>for</strong>mat<br />

UNLOAD DATA FROM TABLE tablename<br />

FORMAT DELIMITED EBCDIC<br />

– If you want the unloaded data to be in ASCII <strong>for</strong>mat, specify as shown in Example 6-6.<br />

The data and the delimiters are unloaded in ASCII. Transmit the data to the workstation<br />

to be used by the spreadsheet in binary <strong>for</strong>mat.<br />

Example 6-6 UNLOAD DATA in ASCII <strong>for</strong>mat<br />

UNLOAD DATA FROM TABLE tablename<br />

FORMAT DELIMITED ASCII<br />

See <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Utility Guide and Reference, SC18-7427, <strong>for</strong> more<br />

in<strong>for</strong>mation about this topic.<br />

We have tested loading the data from a workstation system with delimited <strong>for</strong>mat into <strong>DB2</strong><br />

and UNLOAD from <strong>DB2</strong> to the data which is used by spreadsheet. The LOAD and UNLOAD<br />

of internal and external <strong>for</strong>mat data have been measured to compare with LOAD and<br />

UNLOAD delimited data.<br />

Chapter 6. Utilities 271


6.3.2 Conclusion<br />

We measured the CPU time <strong>for</strong> both LOAD and UNLOAD using three variations (internal<br />

<strong>for</strong>mat, external <strong>for</strong>mat, and delimited <strong>for</strong>mat) and our tested hardware was a z900 Turbo.<br />

There are 10 columns, including 4 CHAR, 1 VARCHAR, 3 DECIMAL, 1 SMALLINT and 1<br />

DATE and no index exists in our test table. Delimited requires using external <strong>for</strong>mat <strong>for</strong><br />

numeric. For example, INTEGER or SMALLINT is treated as if they were INTEGER<br />

EXTERNAL, and DECIMAL is treated as DECIMAL EXTERNAL. DATE is always treated as<br />

EXTERNAL, which causes the DATE fields to always have a large impact on UNLOAD<br />

per<strong>for</strong>mance, even though you might prefer internal <strong>for</strong>mat in several cases like migrating the<br />

DATE data to a different table.<br />

The results are shown in Table 6-1.<br />

Table 6-1 Delimited Load and Unload CPU comparisons<br />

External is more expensive than internal because DECIMAL and SMALLINT data in external<br />

<strong>for</strong>mat has to contain a character string that represents a number in specific <strong>for</strong>ms. However,<br />

it should be noted that external per<strong>for</strong>ms significantly worse than internal, especially with<br />

UNLOAD.<br />

When compared to LOAD and UNLOAD of external undelimited <strong>for</strong>mat, delimited <strong>for</strong>mat<br />

LOAD and UNLOAD have more impact on per<strong>for</strong>mance. It makes sense because in UNLOAD<br />

delimited <strong>for</strong>mat <strong>DB2</strong> has to build the output data to be either in character string or numeric<br />

external <strong>for</strong>mat, and also has to add column delimiters (default is comma) and a double<br />

quotation mark (") <strong>for</strong> the character string and a period (.) <strong>for</strong> the decimal point character.<br />

LOAD costs more because of the need to scan the VARCHAR data to define the length.<br />

In our test UNLOAD of external <strong>for</strong>mat significantly increased CPU time compared to internal<br />

<strong>for</strong>mat.<br />

6.4 RUNSTATS enhancements<br />

In this section we first show some per<strong>for</strong>mance improvements in executing RUNSTATS with<br />

different options, and then we discuss the new function which allows us to gather distribution<br />

statistics.<br />

6.4.1 General per<strong>for</strong>mance improvements<br />

Table 6-2 shows the measurements <strong>for</strong> RUNSTATS of a table with 10 million rows and 6<br />

indexes.<br />

The measurements were implemented on a <strong>IBM</strong> z900 Series 2064 processor.<br />

Table 6-2 Summary of RUNSTATS improvements<br />

RUNSTATS<br />

<strong>DB2</strong> V7 (sec.) <strong>DB2</strong> V8 (sec.) Delta CPU Delta ET<br />

option<br />

CPU Elapsed CPU Elapsed % %<br />

272 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

internal external delimited delta (del/ext)<br />

LOAD (sec.) 11.41 16.3 26.5 +63%<br />

UNLOAD (sec.) 13.3 30.57 34.75 +14%<br />

TABLESPACE 15.7 39 8.6 40 -45.23 2.57


RUNSTATS<br />

option<br />

TABLE 137 140 115 118 -16.06 -15.72<br />

TABLE and 6<br />

INDEXES<br />

6.4.2 DSTATS<br />

<strong>DB2</strong> V7 (sec.) <strong>DB2</strong> V8 (sec.) Delta CPU Delta ET<br />

CPU Elapsed CPU Elapsed % %<br />

189 193 168 173 -11.12 -10.37<br />

The RUNSTATS utility has been enhanced in V8 and can collect distribution statistics on any<br />

column or groups of columns, indexed or non-indexed columns, specified by table level. This<br />

enhancement lets the <strong>DB2</strong> optimizer calculate more accurately the filter factor of a query and<br />

helps to improve SQL per<strong>for</strong>mance.<br />

For versions prior to V8 you can use a tool called DSTATS (Distribution Statistics <strong>for</strong> <strong>DB2</strong> <strong>for</strong><br />

<strong>OS</strong>/390) which you can download from the Web site:<br />

http://www.ibm.com/support/docview.wss?uid=swg24001598<br />

This tool is available <strong>for</strong> use with <strong>DB2</strong> V5, V6, and V7. DSTATS is a standalone <strong>DB2</strong><br />

application program, written in PL/I, which contains dynamic and static SQL statements. The<br />

tool collects additional statistics on column distributions and column frequencies that were not<br />

collected by RUNSTATS be<strong>for</strong>e <strong>DB2</strong> V8. With <strong>DB2</strong> V8, equivalent function is provided by the<br />

RUNSTATS utility. The enhanced RUNSTATS utility collects additional in<strong>for</strong>mation on column<br />

distribution and frequencies, and updates the <strong>DB2</strong> catalog with the more accurate statistics. It<br />

greatly enhances the per<strong>for</strong>mance of the query if there are non-uni<strong>for</strong>m data distributions in<br />

your tables or indexes.<br />

6.4.3 Description of distribution statistics in V8<br />

When there is a skewed distribution of values <strong>for</strong> a certain column, this can cause bad<br />

response time of a query, especially in ad hoc query applications. The collection of correlation<br />

and skew statistics <strong>for</strong> non-leading indexed columns and non-indexed columns can help the<br />

optimizer to compute accurate filter factors. This leads to better access path selection and<br />

improves query per<strong>for</strong>mance.<br />

The enhancement of the RUNSTATS utility allows you to use RUNSTATS to collect distribution<br />

statistics on any column in your tables, whether or not the columns are part of an index, and<br />

whether or not the columns are the leading columns of an index. It updates the <strong>DB2</strong> catalog<br />

with the specified number of highest frequencies and optionally with the specified number of<br />

lowest frequencies. The new functionality also optionally collects multi-column cardinality <strong>for</strong><br />

non-indexed column groups and updates the catalog.<br />

The summary of the new functionality of RUNSTATS is as follows:<br />

► Collect distribution statistics on any column, or groups of columns, indexed or<br />

non-indexed, specified at the table level<br />

► Frequency distributions <strong>for</strong> non-indexed columns or groups of columns<br />

► Cardinality values <strong>for</strong> groups of non-indexed columns<br />

► LEAST frequently occurring values, along with M<strong>OS</strong>T frequently occurring values, <strong>for</strong> both<br />

index and non-indexed column distributions (<strong>DB2</strong> V7 only gathers the most frequently<br />

occurring value)<br />

Chapter 6. Utilities 273


Options <strong>for</strong> cardinality and distribution statistics<br />

To support these new functionalities, several new options are introduced in the RUNSTATS<br />

utility. New keywords COLGROUP, LEAST, M<strong>OS</strong>T and BOTH enable the collection of<br />

distribution statistics on any table column and group of columns. The existing keywords<br />

FREQVAL and COUNT also can be used. You can specify the following options <strong>for</strong> collecting<br />

cardinality and distribution statistics:<br />

► COLGROUP: When you specify the COLGROUP keyword, the specified set of columns is<br />

treated as a group and RUNSTATS collects correlation statistics <strong>for</strong> the specified column<br />

group. You can specify the COLGROUP keyword repeatedly, if you want to collect<br />

statistics on a different set of columns.<br />

► FREQVAL: This keyword controls the collection of frequent value statistics. These are<br />

collected either on the column group or on individual columns depending on whether<br />

COLGROUP is specified or not. You can specify the FREQVAL keyword together with the<br />

NUMCOLS keyword when you run RUNSTATS INDEX. But when you run table-level<br />

statistics, FREQVAL can only be specified together with the COLGROUP keyword. If<br />

FREQVAL is specified, then it must be followed by the keyword COUNT.<br />

► COUNT: This indicates the number of frequent values to be collected. Specifying an<br />

integer value of 20 means to collect 20 frequent values <strong>for</strong> the specified columns. No<br />

default value is assumed <strong>for</strong> COUNT. This can be optionally followed by the keyword<br />

M<strong>OS</strong>T (which is the default), LEAST, or BOTH.<br />

Note: The following statement:<br />

RUNSTATS TABLESPACE DBGBTEST.TSGBRUNS<br />

TABLE(ALL) INDEX(ALL) KEYCARD<br />

does collect FREQVAL values on the indexes by default.<br />

If you do not want to collect any FREQVAL data, you need to specify the following<br />

options:<br />

RUNSTATS TABLESPACE DBGBTEST.TSGBRUNS<br />

TABLE(ALL) INDEX(ALL) KEYCARD<br />

FREQVAL NUMCOLS 1 COUNT 0<br />

► M<strong>OS</strong>T: The most frequent values are collected when the keyword M<strong>OS</strong>T is specified.<br />

► LEAST: The least frequent values are collected when the keyword LEAST is specified.<br />

► BOTH: The most frequent values and the least frequent values are collected when the<br />

keyword BOTH is specified.<br />

Options <strong>for</strong> using sort work data sets<br />

When you are collecting distribution statistics <strong>for</strong> column groups or collecting statistics on a<br />

data-partitioned secondary index, <strong>for</strong> example, it is necessary <strong>for</strong> <strong>DB2</strong> to use sort work to sort<br />

the statistics. As a new option of V8, you can specify the SORTDEVT and SORTNUM<br />

keywords <strong>for</strong> using dynamic allocation of the sort work data sets:<br />

► SORTDEVT: This specifies the device type that DFSORT uses to dynamically allocate the<br />

sort work data set.<br />

► SORTNUM: This specifies the number of required sort work data sets that DFSORT is to<br />

allocate.<br />

If you do not use dynamic allocation <strong>for</strong> the SORT program, and if you collect the statistics <strong>for</strong><br />

which sort data is required, you have to define data sets through JCL. You need to specify<br />

ST01WKnn and STATWK01 in DD statements depending on the statistics you collect:<br />

274 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


6.4.4 Per<strong>for</strong>mance<br />

► ST01WKnn: You need to specify the data set name <strong>for</strong> the temporary data sets of sort<br />

input and output when collecting statistics on at least one data-partitioned secondary<br />

index.<br />

► STATWKnn: You need to specify the data set name <strong>for</strong> the temporary data sets of sort<br />

input and output when collecting distribution statistics <strong>for</strong> column groups.<br />

Note: To calculate the approximate size (in bytes) of the ST01WKnn data set, use the<br />

following <strong>for</strong>mula:<br />

2 × (maximum record length × numcols × (count + 2) × number of indexes)<br />

The values in the <strong>for</strong>mula are as follows:<br />

► Maximum record length: The maximum length of the SYSCOLDISTATS record on<br />

which RUNSTATS is to collect frequency statistics. You can obtain this value from the<br />

RECLENGTH column in SYSTABLES.<br />

► Numcols: The number of key columns to concatenate when you collect frequent values<br />

from the specified index.<br />

► Count: The number of frequent values that RUNSTATS is to collect.<br />

When you plan to use distribution statistics, make sure that the following maintenance is<br />

applied <strong>for</strong> correct functionality and good per<strong>for</strong>mance:<br />

► PTF UQ88754 <strong>for</strong> APAR PQ88375 provides the right value of cardinality <strong>for</strong> partitioned<br />

table spaces.<br />

► PTF UQ91099 <strong>for</strong> APAR PQ87509 is required <strong>for</strong> correctness of frequency values.<br />

► PTF UQ93177 <strong>for</strong> APAR PQ90884 is required <strong>for</strong> better (200%) per<strong>for</strong>mance.<br />

DSTATS per<strong>for</strong>mance comparison of V7 and V8 with PQ90884<br />

In this test we first run RUNSTATS in V7 followed by the standalone DSTATS tool. We<br />

measure class 1 elapsed and CPU time and get the total time of both. In the second case we<br />

measure V8 RUNSTATS with distribution statistics where we collect equivalent statistics to<br />

those taken in V7 with the DSTATS tool. Be<strong>for</strong>e running this case we have applied the PTF <strong>for</strong><br />

PQ90884.<br />

We use an internal query workload and the test table contains about 931k rows. The<br />

description of the test environment is:<br />

► <strong>DB2</strong> V7 and V8 (non-data sharing)<br />

► Table: 1 test table in 1 table space<br />

► Number of pages: 77601<br />

► Number of rows: 931,174<br />

► Number of indexes: 4 (1 partitioned index, 3 non-partitioned indexes)<br />

► Number of partitions of table space: 6<br />

► 2 columns are non-indexed columns (used <strong>for</strong> statistics)<br />

– Column1 cardinality=15104<br />

– Column2 cardinality=24<br />

To explain our test case more clearly, let us show you a part of our control statements <strong>for</strong><br />

testing. We have done equivalent RUNSTATS in V7 and V8, and we have taken equivalent<br />

statistics in V7 with the DSTATS tool, and in V8 with RUNSTATS. We are specifying 2 columns<br />

<strong>for</strong> statistics and both are non-indexed columns. The description of the statistics is:<br />

Chapter 6. Utilities 275


► Number of column groups: 1<br />

► Number of columns in column group: 2 (2 columns in one table)<br />

► Frequent values <strong>for</strong> distribution statistics: 10 most and 10 least frequent values<br />

Example 6-7 shows the sample statement of RUNSTATS in V7.<br />

Example 6-7 RUNSTATS statement in V7<br />

//SYSIN DD *<br />

RUNSTATS TABLESPACE INSQDB01.EVENTS TABLE(EVEN)<br />

REPORT(YES)<br />

Example 6-8 shows the sample statement of DSTATS tool used in V7.<br />

Example 6-8 DSTATS tool in V7<br />

//SYSIN DD *<br />

VALUES 10,10<br />

CARDINALITY MUST<br />

COLCARDF1 SCAN<br />

CARDF ALLOW 0<br />

USRT001.EVEN.CLID,TXCD<br />

Example 6-9 shows the RUNSTATS job used in V8 to collect distribution statistics.<br />

Example 6-9 RUNSTATS with distribution statistics in V8<br />

//SYSIN DD *<br />

RUNSTATS TABLESPACE INSQDB01.EVENTS TABLE(EVEN)<br />

COLGROUP(CLID,TXCD) FREQVAL COUNT 10 BOTH<br />

REPORT(YES)<br />

The result of this measurement is shown in Figure 6-5. If we compare the V7 RUNSTATS plus<br />

DSTATS tool, with the V8 RUNSTATS distribution statistics, we notice that both CPU and<br />

elapsed time are equivalent or better in V8.<br />

V8 RUNSTATS with distribution statistics shows a 15% improvement on elapsed time (51.5<br />

sec. vs. 44.5 sec.) and a 10% improvement on CPU time (43.8 sec. vs. 39.6 sec.).<br />

276 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Time in Sec.<br />

DSTATS per<strong>for</strong>mance comparison<br />

180<br />

160<br />

140<br />

120<br />

100<br />

80<br />

60<br />

40<br />

20<br />

0<br />

V7 RUNSTATS +<br />

DSTATS tool<br />

Figure 6-5 Distribution statistics per<strong>for</strong>mance comparison<br />

V8 RUNSTATS with DSTATS<br />

(PQ90884 applied)<br />

Elapsed CPU<br />

DSTATS measurement with different number of columns<br />

As an additional study of the cost of RUNSTATS with distribution statistics, we have tested in<br />

both V7 and V8 (with PQ90884) several cases collecting distribution statistics of different<br />

numbers of columns or column groups. As a base, we measure simple RUNSTATS against a<br />

table, and then measure RUNSTATS against a table and all related indexes. After that, we<br />

collect distribution statistics against different numbers of columns and column groups. We use<br />

the same environment as the previous test case and the following is the column in<strong>for</strong>mation<br />

used <strong>for</strong> the distribution statistics:<br />

► 3 columns are non-indexed columns (used <strong>for</strong> statistics)<br />

► column1 cardinality=15104<br />

► column2 cardinality=24<br />

► column3 cardinality=41<br />

We have measured the following six test cases:<br />

1. RUNSTATS against one table<br />

2. RUNSTATS against one table and indexes<br />

3. RUNSTATS against one table and distribution statistics on one column<br />

4. RUNSTATS against one table and distribution statistics on one column group specifying 2<br />

columns<br />

5. RUNSTATS against one table and indexes, and distribution statistics on one column group<br />

specifying 2 columns<br />

6. RUNSTATS against one table, and distribution statistics on two column groups in which we<br />

specify 2 columns in the first column group and specify 1 column in the second column<br />

group.<br />

Table 6-3 shows the results of the test cases run in V7. From Case 3 to Case 6, we ran the<br />

RUNSTATS utility followed by the DSTATS tool. So class 1 elapsed and CPU time in these<br />

Chapter 6. Utilities 277


cases is the total time of RUNSTATS plus DSTATS. The overhead of DSTATS is derived from<br />

the percentage of DSTATS time over RUNSTATS time (DSTATS time / RUNSTATS time *100).<br />

Table 6-3 RUNSTATS with DSTATS measurement data in V7<br />

Class 1<br />

elapsed<br />

(sec.)<br />

Class 1<br />

CPU time<br />

(sec.)<br />

DSTATS<br />

CL1 ELT<br />

(sec.)<br />

DSTATS<br />

CL1 CPU<br />

(sec.)<br />

DSTATS<br />

Overhead<br />

ELT (%)<br />

DSTATS<br />

Overhead<br />

CPU (%)<br />

Case 1<br />

Runstats<br />

table<br />

Case 2<br />

RUNSTAT<br />

S<br />

table, idx<br />

Take a look at the DSTATS overhead in Case 3 (collecting distribution statistics on 1 column):<br />

DSTATS overhead is 20% <strong>for</strong> elapsed time. In V7 the overhead of using the DSTATS tool<br />

shows a high percentage in general, because of the cost of running and binding DSTATS as a<br />

standalone program on top of the cost of RUNSTATS. The largest overhead appears when<br />

going from 1 column to 2 in one column group (case 3 to 4). In this case there is 24.8%<br />

degradation in elapsed time and 31.3% degradation in CPU time.<br />

When the number of column groups goes from 1 to 2 (case 4 to 6), there is 11% per<strong>for</strong>mance<br />

degradation in elapsed time and 6.8% degradation in CPU time.<br />

Table 6-4 shows the results of the same test cases with V8 RUNSTATS with distribution<br />

statistics. DSTATS times are now the difference between RUNSTATS with distribution<br />

statistics and RUNSTATS only time (<strong>for</strong> example, DSTATS in Case 3 is the difference of Case<br />

3 and Case 1 in terms of class 1 time).<br />

278 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Case 3<br />

RUNSTAT<br />

S<br />

table+<br />

1 column<br />

Case 4<br />

RUNSTAT<br />

S<br />

table+<br />

1 colgrp<br />

w/ 2 cols<br />

Case 5<br />

RUNSTAT<br />

S<br />

table idx+<br />

1 colgrp<br />

w/ 2 cols<br />

25.91 29.70 31.09 38.80 42.59 43.08<br />

19.31 20.94 21.97 28.85 30.49 30.80<br />

N/A N/A 5.18 12.88 12.88 17.17<br />

N/A N/A 2.66 9.54 9.54 11.49<br />

N/A N/A 20 49.7 43.4 66.3<br />

N/A N/A 13.8 49.4 45.6 59.5<br />

Case 6<br />

RUNSTAT<br />

S<br />

table+<br />

2 colgrp<br />

w/ 2 ,1 cols


Table 6-4 RUNSTATS with DSTATS measurement data in V8<br />

Class 1<br />

elapsed<br />

(sec.)<br />

Class 1<br />

CPU time<br />

(sec.)<br />

DSTATS<br />

CL1 ELT<br />

(sec.)<br />

DSTATS<br />

CL1 CPU<br />

(sec.)<br />

DSTATS<br />

Overhead<br />

ELT (%)<br />

DSTATS<br />

Overhead<br />

CPU (%)<br />

Case 1<br />

RUNSTAT<br />

S<br />

table<br />

Case 2<br />

RUNSTAT<br />

S<br />

table idx<br />

Case 3<br />

RUNSTAT<br />

S<br />

table<br />

1 column<br />

Case 4<br />

RUNSTAT<br />

S<br />

table<br />

1 colgrp<br />

w/ 2 cols<br />

Case 5<br />

RUNSTAT<br />

S<br />

table idx<br />

1 colgrp<br />

w/ 2 cols<br />

26.04 29.26 28.00 27.99 30.59 39.67<br />

19.10 21.62 24.50 24.32 26.62 32.22<br />

N/A N/A 1.96 1.94 1.32 13.63<br />

N/A N/A 5.39 5.22 5.00 13.12<br />

N/A N/A 7.5 7.5 4.5 52.3<br />

N/A N/A 28.3 27.3 23.1 68.7<br />

In V8 we can observe the CPU overhead when running RUNSTATS specifying distribution<br />

statistics. In case 3, which is the base scenario of DSTATS, we see a 28.3% overhead in CPU<br />

time, and in case 4 (adding 1 column to the COLGROUP) we see 27.3%.<br />

However, in Case 6 (2 column groups) it is 68.7%. We can conclude that, in V8, increasing<br />

the number of column groups drives the CPU cost higher than increasing the number of<br />

columns.<br />

There is almost no difference when 1 column is added in 1 column group (Case 3 to 4). On<br />

the other hand, there is 29.7% degradation in elapsed time and 21% degradation in CPU time<br />

of the total RUNSTATS time, when the column group of statistics goes to 2 (Case 4 to 6).<br />

In general, V8 RUNSTATS cuts down the elapsed time well compared to V7.<br />

Case 6<br />

Runstats<br />

table<br />

2 colgrp<br />

w/ 2 ,1 cols<br />

Access path improvement<br />

To verify the usefulness of DSTATS we have tested the access path improvement of 6 queries<br />

out of 25 queries of the query workload after running distribution statistics. We have gathered<br />

distribution statistics on 10 columns manually picked. After that, most of the queries have<br />

shown positive access path changes.<br />

Bind cost<br />

You need to consider that RUNSTATS executions, by adding the frequency values in the<br />

SYS<strong>IBM</strong>.SYSCOLDIST catalog table, cause high bind cost. Especially high CPU<br />

consumption occurs <strong>for</strong> dynamic prepare when FREQVAL COUNT in SYSCOLDIST is<br />

greater than 100. In this case a large portion of CPU time is used to remove duplicate<br />

frequency values. PTF UK00296 <strong>for</strong> APAR PQ94147 is meant to reduce such large bind cost.<br />

Chapter 6. Utilities 279


6.4.5 Conclusion<br />

Statistics Advisor tool<br />

This tool is a function of the new Visual Explain and it can help you cut down the ef<strong>for</strong>t in<br />

determining what kind of distribution statistics you need to run and set up the RUNSTATS<br />

control statements. For in<strong>for</strong>mation about the Statistics Advisor tool refer to 3.15.3, “Statistics<br />

Advisor” on page 116.<br />

V8 RUNSTATS with distribution statistics achieves a better per<strong>for</strong>mance compared to V7<br />

RUNSTATS and the DSTATS tool. You no longer need to run the separate DSTATS program<br />

to collect distribution statistics, in V8 RUNSTATS will do it and cut down CPU and elapsed<br />

time. Measurements show that increasing the number of columns or column groups to collect<br />

statistics may significantly impact CPU and elapsed time. However, access path<br />

improvements provided by distribution statistics can be quite remarkable.<br />

6.4.6 Recommendations<br />

6.5 Cross Loader<br />

To get good per<strong>for</strong>mance when using RUNSTATS distribution statistics in V8, it is important to<br />

be current with maintenance, apply the fixes <strong>for</strong> PQ90884 and PQ94147 (dynamic prepare).<br />

We also recommend you use the Statistics Advisor tool to define the right statistics <strong>for</strong> your<br />

application: The Statistics Advisor suggests what RUNSTATS and DSTATS are needed <strong>for</strong><br />

your queries. The CPU overhead observed when there are hundreds of frequency values in<br />

SYSCOLDIST can be reduced by deleting unnecessary in<strong>for</strong>mation from the catalog table.<br />

The Cross Loader function enables you to use a single LOAD job to transfer data from one<br />

location to another location or from one table to another table at the same location. You can<br />

use either a local server or any DRDA-compliant remote server as a data input source <strong>for</strong><br />

populating your tables. Your input can even come from other sources besides <strong>DB2</strong>; you can<br />

use <strong>IBM</strong> In<strong>for</strong>mation Integrator <strong>for</strong> access to data from other relational or non-relational data<br />

sources. For more in<strong>for</strong>mation abut the cross loader function of the LOAD utility, see <strong>DB2</strong><br />

<strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Utility Guide and Reference, SC18-7427.<br />

6.5.1 Per<strong>for</strong>mance APAR<br />

APAR PQ84160, opened on V7, has optimized the code reducing the path length by a large<br />

percentage. Prior to this fix, the cross loader took longer than the normal LOAD and UNLOAD<br />

utilities. With two times per<strong>for</strong>mance improvement provided by this rework, the cross loader is<br />

now at the same level as LOAD and UNLOAD in terms of per<strong>for</strong>mance.<br />

PTFs are available <strong>for</strong> both V7 and V8:<br />

► V7: UQ91416<br />

► V8: UQ91422<br />

280 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 7. Networking and e-business<br />

7<br />

This chapter describes enhancements related to distributed processing and e-business<br />

applications.<br />

► DDF enhancements: A requester database alias, a server location alias and member<br />

routing in a TCP/IP network are provided in DDF. The DRDA architecture allows larger<br />

query blocks: the number of network exchanges between the workstation and a <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> V8 server is about half that when accessing the <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V7 server.<br />

► Multi-row FETCH and INSERT in DRDA: Multi-row FETCH and INSERT have a<br />

significant positive impact on per<strong>for</strong>mance in a DRDA client/server environment. However,<br />

that per<strong>for</strong>mance impact differs when <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 acting as a DRDA application<br />

server is being accessed from a <strong>DB2</strong> Connect Client running on Linux, Unix and Windows<br />

or another <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 acting as a DRDA application requester.<br />

► WebSphere and <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC: In the past, access to a<br />

Linux, UNIX and Windows server and a z/<strong>OS</strong> server used different database connection<br />

protocols. To provide transparent access across the <strong>DB2</strong> Family, these protocols are now<br />

standardized, and all of them use the Open Group’s DRDA <strong>Version</strong> 3 standard. This new<br />

architecture is called the Universal Driver. The first deliverable of this new architecture is<br />

the <strong>IBM</strong> <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC <strong>Version</strong> 1.0, also known as the <strong>IBM</strong><br />

Java Common Connectivity.<br />

► ODBC enhancements: Several <strong>DB2</strong> ODBC enhancements such as Unicode support,<br />

improved authentication, long name support, 2 MB SQL statements and SQLcancel are<br />

briefly presented in this section.<br />

► XML support in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>: In <strong>DB2</strong> V7, you could use the XML extender feature <strong>for</strong><br />

manipulating XML data in and out of <strong>DB2</strong>. The SQL/XML Publishing Functions become<br />

available in <strong>DB2</strong> V8 and provide a set of SQL built-in functions that allow applications to<br />

generate XML data from relational data with high per<strong>for</strong>mance. It reduces application<br />

development ef<strong>for</strong>ts in generating XML data <strong>for</strong> data integration, in<strong>for</strong>mation exchange,<br />

and web services, thus enhancing the leadership position of <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> as the<br />

enterprise database server. This is the first step <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> takes to more tightly<br />

integrate XML into the database engine.<br />

► Enterprise Workload Manager: Enterprise Workload Manager (EWLM) enables you to<br />

automatically monitor and manage multi-tiered, distributed, heterogeneous or<br />

homogeneous workloads across an IT infrastructure to better achieve defined business<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 281


goals <strong>for</strong> end-user services. We show the preliminary tests to evaluate the impact on<br />

throughput of an EWLM implementation on a server combination WebSphere/AIX with<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8.<br />

282 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


7.1 DDF enhancements<br />

A requester database alias, a server location alias and member routing in a TCP/IP network<br />

are provided in DDF.<br />

7.1.1 Requester database alias<br />

During this discussion, in which we want to differentiate between <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>DB2</strong> <strong>for</strong><br />

Linux, UNIX, and Windows, we call the latter <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms.<br />

A <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database is known in the network by its database name. This<br />

database name is used by applications to connect to an instance of a <strong>for</strong> Multiplat<strong>for</strong>ms<br />

database. A <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> requester uses a location name to connect to an instance of a <strong>DB2</strong><br />

<strong>for</strong> Multiplat<strong>for</strong>ms database. A location name maps to a <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database<br />

name. When a <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database is deployed to a large number of servers, in<br />

some cases in the thousands, the database is commonly deployed with the same name in<br />

different locations.<br />

The current Communications Database catalog tables require a one to one mapping with a<br />

location and a network address. A location can only be defined to one network address. To<br />

allow a z/<strong>OS</strong> requester to access multiple <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms databases with the same<br />

database name, a new column is added to SYS<strong>IBM</strong>.LOCATIONS table called DBALIAS. This<br />

column allows a database administrator to specify multiple locations <strong>for</strong> a <strong>DB2</strong> <strong>for</strong><br />

Multiplat<strong>for</strong>ms database deployed on multiple locations. A z/<strong>OS</strong> application would then<br />

specify a location name to access an instance of a <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database and the<br />

SYS<strong>IBM</strong>.LOCATIONS would map the location name to the <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database<br />

name which is then used to connect to the <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms database.<br />

7.1.2 Server location alias<br />

A <strong>DB2</strong> server is known in the network by its location name. This name is used by applications<br />

to identify an instance of a <strong>DB2</strong> subsystem or a group of data sharing <strong>DB2</strong> subsystems.<br />

When two or more <strong>DB2</strong> subsystems are migrated to a single data sharing group, multiple<br />

locations must be consolidated into a single location. When the locations are consolidated, all<br />

applications using the old location name need to be changed to access the new data sharing<br />

group location name.<br />

When there is a large number of remote applications deployed across the network, in some<br />

cases in the thousands, it is impossible to effectively change each application simultaneously<br />

to use the new location name. In order to support the migration from multiple locations to a<br />

single location, eight location alias names can be defined <strong>for</strong> a <strong>DB2</strong> subsystem or group of<br />

data sharing <strong>DB2</strong> subsystems.<br />

A location alias is another name that a requester can use to access a <strong>DB2</strong> subsystem. <strong>DB2</strong><br />

accepts requests from applications that identify the <strong>DB2</strong> server with its location name or any<br />

of its location alias names. The Change Log Inventory utility allows a user to define up to eight<br />

alias names in addition to the location name. The Print Log Map utility prints any location alias<br />

names defined <strong>for</strong> the <strong>DB2</strong> subsystem.<br />

7.1.3 Member routing in a TCP/IP Network<br />

In a sysplex environment, setting up rows in the new SYS<strong>IBM</strong>.IPLIST table at a requester in<br />

conjunction with defining location aliases at the server provides the ability <strong>for</strong> a DBA to<br />

override the default TCP/IP workload balancing. Currently, connections are automatically<br />

Chapter 7. Networking and e-business 283


alanced across all members. With the new SYS<strong>IBM</strong>.IPLIST table, a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> application<br />

requester can define a specific member or a subset of members in a group to route requests.<br />

At the server, location alias names do not need to be defined to allow these applications to<br />

access the <strong>DB2</strong> server with the alternate location names. Aliases are only needed <strong>for</strong><br />

member subsetting when the application requester is non-<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> (like <strong>DB2</strong> Connect).<br />

The location <strong>DB2</strong>PLEX might represent three <strong>DB2</strong> subsystems in a group: <strong>DB2</strong>A, <strong>DB2</strong>B, and<br />

<strong>DB2</strong>C. As in previous versions, the location <strong>DB2</strong>PLEX is set up to use the group domain<br />

name to route requests to all available members. If a DBA wants to provide member routing to<br />

<strong>DB2</strong>A and <strong>DB2</strong>B but not to <strong>DB2</strong>C, a location name <strong>DB2</strong>PLEXA is defined in<br />

SYS<strong>IBM</strong>.LOCATIONS and a row is inserted <strong>for</strong> <strong>DB2</strong>A and <strong>DB2</strong>B in the SYS<strong>IBM</strong>.IPLIST table<br />

with their member domain name. If an application wants to route requests to either <strong>DB2</strong>A or<br />

<strong>DB2</strong>B, it connects using location <strong>DB2</strong>PLEXA. When an application wants to route requests to<br />

the least loaded member, it connects using location <strong>DB2</strong>PLEX.<br />

With this new service, applications can now route requests using a name different than the<br />

group location name. If the application contains SQL statements that qualify object names<br />

with a name other than the group location name, a location alias needs to be defined. In the<br />

above example, <strong>DB2</strong>A and <strong>DB2</strong>B need to define location alias <strong>DB2</strong>PLEXA using the Change<br />

Log Inventory utility. When an application connects to <strong>DB2</strong>PLEXA and issues a<br />

SELECT * FROM <strong>DB2</strong>PLEXA.COLLECTION.TABLE;<br />

the <strong>DB2</strong> member recognizes the fully qualified object as a local object.<br />

7.1.4 DRDA allows larger query blocks<br />

The DRDA architecture has been enhanced to allow query blocks up to 10 MB.<br />

Description<br />

A query block is a group of rows that fits into a (query) block and is sent as a single network<br />

message. The default query block size used by <strong>DB2</strong> in <strong>Version</strong> 7 is 32 KB. The number of<br />

rows that <strong>DB2</strong> puts into a query block depends on the row length, as well as the OPTIMIZE<br />

FOR n ROWS clause. Blocking is used by both <strong>DB2</strong> Private Protocol and DRDA. When<br />

blocking is not used, <strong>DB2</strong> will send a single row across the network.<br />

To support the larger network bandwidths and customer requirements to control the amount<br />

of data returned on each network request, the DRDA architecture has been enhanced to<br />

allow query blocks up to 10 MB. This way, a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 requester can ask <strong>for</strong> a query<br />

block size of up to 10 MB from a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 server. This allows the requester to better<br />

manage and control the size of blocks returned from <strong>DB2</strong>.<br />

<strong>DB2</strong> Connect V8 and <strong>DB2</strong> V8 clients can specify a query block size of up to 65,535 in size but<br />

only the <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 DDF server will support this. Thus, one will notice that the number<br />

of network exchanges between the workstation and <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 server is about half that<br />

when accessing the <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V7 server. <strong>DB2</strong> V7 can only support a query block size up<br />

to 32,767.<br />

Per<strong>for</strong>mance<br />

Per<strong>for</strong>mance measurement description<br />

In this measurement we used:<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, V7 and V8<br />

► z/<strong>OS</strong> Release 1.4<br />

► z900<br />

► <strong>DB2</strong> Connect EE, Client V8 on 1.3 GHz P690 with AIX<br />

284 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The following query was utilized:<br />

SELECT X, Y, Z FROM CUSTOMER OPTIMIZE FOR 240001 ROWS FOR FETCH ONLY<br />

All column data is CHAR or VARCHAR<br />

240000 rows at 133 bytes per row were returned resulting in a result set size of 31,920,000<br />

bytes.<br />

Per<strong>for</strong>mance measurement results<br />

See Table 7-1 <strong>for</strong> the results.<br />

Table 7-1 <strong>DB2</strong> connect evaluation <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8<br />

<strong>DB2</strong> Connect and client V8 per<strong>for</strong>med better <strong>for</strong> large result sets with <strong>DB2</strong> V8 as the DRDA<br />

application server compared to <strong>DB2</strong> V7. The retrieval of data from <strong>DB2</strong> V8 is 15.2% faster<br />

than from <strong>DB2</strong> V7. This improvement is achieved through the support of a 64 KB query block<br />

size and the automatic use of multi-row fetch by DDF in <strong>DB2</strong> V8.<br />

Conclusion<br />

The 64 KB query block size can reduce the network transfers by 50% in <strong>DB2</strong> V8 compared to<br />

<strong>DB2</strong> V7.<br />

Recommendation<br />

In order to benefit from the larger query block size supported by <strong>DB2</strong> V8 when dealing with<br />

large result sets, you should update the <strong>DB2</strong> client configuration parameter RQRIOBLK value<br />

to 65,635 since the default is 32,767.<br />

7.1.5 <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> Multiplat<strong>for</strong>ms <strong>Version</strong> 8.1 was the first member of the <strong>DB2</strong> Family to introduce<br />

the new JDBC Driver, called the <strong>IBM</strong> <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC. This new<br />

Java driver architecture is the future basis of all <strong>DB2</strong>-related Java ef<strong>for</strong>ts. It supports what is<br />

called the JDBC type 2 and type 4 Driver.<br />

These drivers are currently supported on <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> Linux, Unix, and Windows and <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> <strong>Version</strong> 8. They are also available <strong>for</strong> <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 <strong>Version</strong> 7, through the<br />

maintenance stream via UQ85607.<br />

Note that with PTF UQ94429 (<strong>DB2</strong> V7) and UQ94430 (<strong>DB2</strong> V8) <strong>for</strong> APAR PQ93458, release<br />

2.3 of the <strong>DB2</strong> Universal Driver became available.<br />

Refer to 7.3, “WebSphere and the <strong>DB2</strong> Universal Driver” on page 292 <strong>for</strong> more in<strong>for</strong>mation.<br />

7.2 Multi-row FETCH and INSERT in DRDA<br />

Elapsed time (sec.) Transfer rate (MB/sec.)<br />

<strong>DB2</strong> V7 7.111 4.28<br />

<strong>DB2</strong> V8 6.176 4.93<br />

Client applications that use the <strong>DB2</strong> CLI/ODBC API could already use multi-row fetch and<br />

insert on the client side. The function SQLExtendedFetch() per<strong>for</strong>ms an array fetch of a set of<br />

rows. Also <strong>for</strong> multiple insert, delete, or update, <strong>DB2</strong> CLI/ODBC provides an array input<br />

Chapter 7. Networking and e-business 285


method. Prior to <strong>DB2</strong> V8 those array fetch and insert requests only affect the processing<br />

between the application program and the <strong>DB2</strong> CLI/ODBC Driver on the workstation.<br />

<strong>DB2</strong> V8 introduces multi-row fetch and insert. This function is by default enabled <strong>for</strong> DRDA<br />

requests and client application array requests. In Figure 7-1 we show how the usage of<br />

multi-row operations saves cross-memory trips between the distributed address space and<br />

the database engine. This improvement can significantly reduce elapsed time and CPU cost<br />

on the server.<br />

Connect<br />

Prepare<br />

Open<br />

Cursor<br />

Fetches<br />

Close<br />

Cursor<br />

Commit<br />

Figure 7-1 Multi-row FETCH distributed <strong>DB2</strong> V7 vs. <strong>DB2</strong> V8<br />

Multi-row in DRDA becomes already active in CM <strong>for</strong> client CLI/ODBC and host to host SQL<br />

requests.<br />

In the following sections the per<strong>for</strong>mance of multi-row FETCH and INSERT is evaluated.<br />

7.2.1 Per<strong>for</strong>mance - Distributed host to host<br />

In this section we present the per<strong>for</strong>mance measurements in a distributed host to host<br />

environment.<br />

Per<strong>for</strong>mance measurements description<br />

In these measurements we used:<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, V7 and V8<br />

► z/<strong>OS</strong> Release 1.3<br />

286 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Multi-row fetch distributed be<strong>for</strong>e V8 vs. V8<br />

DIST DBM1 MSTR IRLM<br />

Connect<br />

Prepare<br />

Open<br />

Cursor<br />

Close<br />

Cursor<br />

Commit<br />

Fetch<br />

rowset<br />

DIST DBM1 MSTR IRLM


► <strong>IBM</strong> z900 Series 2064 2-way processor<br />

► ESS 800 DASD (with FICON channel)<br />

Per<strong>for</strong>mance measurement results<br />

In these measurements <strong>DB2</strong> V8 is acting as a DRDA application server, accessed by another<br />

<strong>DB2</strong> V8 acting as a DRDA application requestor. We fetch 100,000 20 column rows from a<br />

cursor without and with rowset positioning. The size of one row is 100 bytes.<br />

We look at three cases: using multi-row fetch implicitly, explicitly and insert.<br />

The results <strong>for</strong> implicit multi-row are presented in Figure 7-2. Note that the impact of multi-row<br />

fetch depends on network per<strong>for</strong>mance, the number of columns and rows fetched in one fetch<br />

request, the row size and the complexity of the SQL call. This means that your results are<br />

likely to differ from what is presented here.<br />

The requestor class 1 elapsed time is derived from requestor (class 2 elapsed time + (class 1<br />

CPU time - class 2 CPU time)) in order to avoid wide fluctuation reported in accounting class<br />

1 elapsed time.<br />

(Sec)<br />

9<br />

6<br />

3<br />

0<br />

5.7<br />

Multi-row Fetch, Distributed - Host to Host<br />

(Total rows fetched : 100,000 rows)<br />

Requester Class 1 elapsed time<br />

5.4<br />

10.3<br />

V8 default = V8 without explicit multi-row FETCH<br />

V8 n1 x n2 = V8 with explicit multi-row FETCH<br />

n1= # of FETCH<br />

n2= # of rows per MR FETCH<br />

Figure 7-2 Multi-row FETCH - Distributed host to host<br />

4<br />

3.4 3.2<br />

v7 v8 10k 1k 100 10 (n1)<br />

default 10 100 1K 10K (n2)<br />

Note is that in the case of implicit multi-row fetch, the requestor application does not need to<br />

be changed.<br />

In <strong>DB2</strong> V8 implicit multi-row FETCH (default), the results listed in Table 7-2 show a 5%<br />

elapsed time improvement at the requestor and a 47% CPU time improvement at the server<br />

(Sec)<br />

2<br />

1<br />

0<br />

Server Class 1 CPU time<br />

1.76<br />

0.93<br />

2.01<br />

1.13 1.03 1<br />

v7 v8 10k 1k 100 10 (n1)<br />

default 10 100 1K 10K (n2)<br />

Chapter 7. Networking and e-business 287


when compared to <strong>DB2</strong> V7. At the server side the DIST task requests the DBM1 to FETCH<br />

automatically a query block instead of rows. At the requester the rows are still fetched one by<br />

one. With implicit multi-row FETCH the query block size is 32 KB. Accounting class 2 does<br />

not have any impact here since class 2 data collection is done <strong>for</strong> each block, not <strong>for</strong> each row<br />

fetched.<br />

Table 7-2 <strong>DB2</strong> V8 with implicit multi-row FETCH vs. V7<br />

Requestor elapsed<br />

time (sec.)<br />

With explicit multi-row FETCH the elapsed time improved up to 43% at the requestor <strong>for</strong> a<br />

rowset size of 10k due to an increase in the message block size from 32 KB up to 10 MB, see<br />

Table 7-3.<br />

Table 7-3 <strong>DB2</strong> V8 with explicit multi-row FETCH vs. V7<br />

The requester had only to issue 10 FETCH requests to the server to retrieve the result set. At<br />

the server a 43% CPU time improvement is realized. To benefit from this improvement the<br />

requestor application must be changed to use cursors with rowset positioning.<br />

Network transfers go down proportionally to the number of fetch SQL calls issued. One fetch<br />

of a rowset is one network transfer.<br />

If the rowset size is reduced, the corresponding per<strong>for</strong>mance numbers degrade. A rowset size<br />

of 10 per<strong>for</strong>ms worse compared to V7 and V8 default. Note that the rowset size also<br />

determines the number of rows in each query block. For a 10 rows rowset 10000 network<br />

transfers are needed compared to about 326 network transfers <strong>for</strong> V7 and V8 default. But<br />

more network transfers do not result always in degraded per<strong>for</strong>mance. In the case of rowset<br />

size 100, 1000 network transfers were needed but the savings at the application requestor,<br />

due to fewer cross memory requests between the application address space and the DBM1<br />

address space, and the savings at the application server due to handling rowsets between<br />

the DIST and DBM1 address spaces, compensate <strong>for</strong> the less efficient network transfer.<br />

The server CPU improvement <strong>for</strong> explicit 10k rowset (43%) is less than the V8 default, 320<br />

rows (47%). This delta can be attributed to measurement noise, they should be equivalent.<br />

In the next measurement INSERT processing in a DRDA host to host environment is<br />

evaluated. <strong>DB2</strong> V8 acting as a DRDA application server is accessed by another <strong>DB2</strong> V8<br />

acting as a DRDA application requestor. In this test case a total of 10,000 20 column rows<br />

were inserted. The results are presented in Figure 7-3.<br />

By default INSERTs only process a single row at a time. For DRDA each single row insert<br />

causes 1 network transfer from the requester to the server. Compared to <strong>DB2</strong> V7 the elapsed<br />

288 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8 % difference<br />

5.70 5.39 -5<br />

Server CPU time (sec.) 1.768 0.93 -47<br />

Network transfers 326 326 0<br />

Requestor elapsed<br />

time (sec.)<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8 % difference<br />

5.703 3.225 -43<br />

Server CPU time (sec.) 1.758 0.999 -43<br />

Network transfers 326 10 -97


time <strong>for</strong> an insert increases by 3.7% and the CPU time by 17% due to the architectural<br />

changes in <strong>DB2</strong> V8.<br />

If we change the requesting application to insert an array of 10, 100, 1000 or 10000 rows<br />

each with 20 columns we notice that the corresponding elapsed time at the DRDA application<br />

requestor and CPU time at the DRDA application server drop significantly compared to the 1<br />

row insert in <strong>DB2</strong> V7. The best result is obtained with a rowset size of 10000 where the DRDA<br />

application server CPU time is reduced by -72% and the DRDA application requestor elapsed<br />

time by 89%.<br />

(seconds)<br />

9<br />

6<br />

3<br />

0<br />

Multi-row Insert, Distributed - Host to Host<br />

(Total rows Inserted : 100,000 rows)<br />

Requester Class 1 Elapsed time Server Class 1 CPU time<br />

7.9<br />

8.2<br />

v7 v8 10k 1k 100 10 (n1)<br />

default 10 100 1K 10K (n2)<br />

V8 default = V8 without explicit multi-row Insert<br />

V8 n1 x n2 = V8 with explicit multi-row Insert,<br />

n1= # of Insert SQL calls<br />

n2= # of rows per MR Insert SQL call<br />

Figure 7-3 Multi-row INSERT - Distributed host to host<br />

1.8<br />

1.3<br />

1 0.9<br />

v7 v8 10k 1k 100 10 (n1)<br />

default 10 100 1K 10K (n2)<br />

Conclusion<br />

With implicit multi-row FETCH your applications will benefit immediately from the multi-row<br />

FETCH enhancement in a host to host DRDA environment without having to change the<br />

applications. Explicit multi-row support requires an application change. Host variable arrays<br />

are used to receive multi-fetch rowsets or serve as input <strong>for</strong> multi-row INSERT.<br />

Recommendation<br />

In host to host DRDA multi-row operations the best per<strong>for</strong>mance is obtained when the size of<br />

the host variable array matches the query block size which is 10 MB or 32767 rows whichever<br />

limit is first reached. Program virtual storage usage increases with the size of the arrays used.<br />

Explicit multi-row operations require <strong>DB2</strong> V8 in new-function mode (NFM).<br />

In general, 100 rows is just about the maximum needed to get the optimal per<strong>for</strong>mance.<br />

There is very little return beyond 100.<br />

(Sec)<br />

2<br />

1<br />

0<br />

1.6<br />

1.88<br />

0.73 0.68<br />

0.49 0.45<br />

Chapter 7. Networking and e-business 289


7.2.2 Per<strong>for</strong>mance - Distributed client to Host<br />

In this section we present the per<strong>for</strong>mance measurements in a distributed client to host<br />

environment.<br />

Per<strong>for</strong>mance measurement description<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, V7 and V8<br />

► z/<strong>OS</strong> Release 1.3<br />

► <strong>IBM</strong> z900 Series 2064 2-way processor<br />

► ESS 800 DASD (with FICON channel)<br />

► <strong>DB2</strong> Connect/client V8 acting as a DRDA application requester<br />

Per<strong>for</strong>mance measurement results<br />

<strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms V8 acting as client still does not support explicit multi-row FETCH<br />

when accessing <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8. Multi-row fetch is supported when using dynamic scrollable<br />

cursors in CLI coming from a distributed plat<strong>for</strong>m. However the client application and the <strong>DB2</strong><br />

<strong>for</strong> z/<strong>OS</strong> V8 server will benefit from the <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 multi-row enhancement. By default<br />

the DIST address space will issue multi-row FETCH requests to DBM1 <strong>for</strong> read-only cursors<br />

with the rowset size determined by the query block size.<br />

Figure 7-4 presents the result of a test case in which 100,000 20 column rows were fetched.<br />

Class 1 time (seconds)<br />

5<br />

4<br />

3<br />

2<br />

1<br />

0<br />

3.95<br />

2.91<br />

Figure 7-4 Multi-row fetch - <strong>DB2</strong> client to host<br />

Compared to <strong>DB2</strong> V7, we notice a decrease in CPU at the DRDA application server of 53%<br />

and a decrease in elapsed time of 26% at the client application due to the larger query block<br />

size, up to 64 KB is supported by <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8.<br />

The 64 KB query block size can reduce the network transfers by 50% in <strong>DB2</strong> V8, compared to<br />

<strong>DB2</strong> V7.<br />

In <strong>DB2</strong> V8 per<strong>for</strong>mance of CLI/ODBC applications will benefit from array insert. If we compare<br />

single row insert in <strong>DB2</strong> V8 to single row in <strong>DB2</strong> V7 elapsed time at the client increases with<br />

290 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Multi-row Fetch, Distributed (<strong>DB2</strong> client to host)<br />

Total rows fetched : 100,000<br />

Client Elapsed time Server CPU Time<br />

1.79<br />

0.84<br />

V7 V8 V7 V8<br />

default default


2.3% and CPU time at the server with 8.1% again due to the architectural changes in <strong>DB2</strong> V8,<br />

see Figure 7-5.<br />

seconds<br />

6<br />

4<br />

2<br />

0<br />

5.7 5.6<br />

single<br />

row<br />

n=<br />

10<br />

V7 : n= # of single-row Insert SQL calls / message<br />

V8 : n= # of rows per multi-row Insert SQL call / message<br />

Figure 7-5 Multi-row insert - <strong>DB2</strong> client to host<br />

Multi-row Insert Per<strong>for</strong>mance<br />

Distributed - <strong>DB2</strong> client Host<br />

(10,000 rows Inserted / test)<br />

Client<br />

Elapsed Time<br />

2.0<br />

1.4 1.5 1.4 1.4<br />

1.0<br />

0.8 0.8<br />

n=<br />

100<br />

n=<br />

1000<br />

n=<br />

10000<br />

2.0 1.9<br />

single<br />

row<br />

1.1<br />

0.7<br />

V8 V7<br />

If the client application is coded to use array insert the difference with <strong>DB2</strong> V7 becomes<br />

significant. In <strong>DB2</strong> V7 this results still in single row inserts (the array insert only affects the<br />

processing between the application and the CLI/ODBC Driver) but in <strong>DB2</strong> V8 full advantage is<br />

taken from multi-row insert between the DIST and DBM1.<br />

For an application that inserts 10 times an array of 1,000 rows this results in a CPU time<br />

improvement of 51% at the DRDA application server side, and an elapsed time improvement<br />

of 47% <strong>for</strong> the client application, compared to <strong>DB2</strong> V7.<br />

If the ODBC Driver detects <strong>DB2</strong> V8 as the server it translates the insert into a network<br />

transfer of 1 insert of 1,000 rows. If the ODBC Driver detects a pre-V8 server then each<br />

network transfer becomes 1,000 inserts of 1 row each.<br />

Conclusion<br />

Although there is no <strong>DB2</strong> client support <strong>for</strong> native multi-row fetch, the CLI/ODBC<br />

SQLExtendedFetch() function fetches arrays from the query block result sets. At the server<br />

side the DIST address space will start using multi-row fetch by default and fetch a number of<br />

rows that will fit the query block size which results in significant CPU savings.<br />

If your CLI/ODBC applications currently use array insert, you will immediately benefit from this<br />

enhancement as this SQL syntax will now be honored by <strong>DB2</strong> V8 in NFM and not be<br />

translated by the CLI/ODBC Driver into a series of individual row inserts.<br />

n=<br />

10<br />

Server<br />

CPU Time<br />

1.0 1.0<br />

0.5 0.5 0.5<br />

n=<br />

100<br />

n=<br />

1000<br />

1.1<br />

n=<br />

10000<br />

Chapter 7. Networking and e-business 291


Recommendation<br />

If you currently do not use array fetch and insert in your CLI applications we recommend that<br />

you start using array operations. There is no default optimal rowset size. The improvement<br />

that can be realized will depend on the number of columns, the size of the row, the network<br />

bandwidth,... As you can conclude from this measurement the larger the rowset the less<br />

significant the improvement. As a rule of thumb we recommend that you experiment with a<br />

rowset size that fits in a 64 KB communication buffer. Note that column-wise binding of the<br />

application array variables is more efficiently supported by the CLI/ODBC Driver than<br />

row-wise binding.<br />

7.3 WebSphere and the <strong>DB2</strong> Universal Driver<br />

In this section we discuss the <strong>IBM</strong> <strong>DB2</strong> <strong>UDB</strong> Universal Driver <strong>for</strong> SQLJ and JDBC, also known<br />

as the Java Common Connectivity (JCC), from a per<strong>for</strong>mance perspective and the <strong>DB2</strong><br />

enhancements that will benefit Java in general.<br />

JDBC is a vendor-neutral SQL interface that provides data access to your application through<br />

standardized Java methods.<br />

These methods and interfaces are packaged as <strong>DB2</strong> JDBC Drivers and numbered from 1 to<br />

4:<br />

► Type 1<br />

This is the oldest type of driver. It was provided by Sun to promote JDBC when no<br />

database-specific drivers were available. With this driver, the JDBC API calls an ODBC<br />

Driver to access the database. This driver type is commonly referred to as a JDBC-ODBC<br />

bridge driver. Its shortcoming is that ODBC must be implemented and installed on all<br />

clients using this driver type. This restricts it to plat<strong>for</strong>ms that have ODBC support, and as<br />

such is mostly Windows centric. Since it also has to translate every JDBC call into an<br />

equivalent ODBC call, the per<strong>for</strong>mance of a Type 1 Driver is not great. <strong>IBM</strong> does not<br />

provide a Type 1 Driver.<br />

This type is no longer commonly used, because virtually every database vendor nowadays<br />

supports JDBC and provides their own (vendor-specific) driver.<br />

► Type 2<br />

A JDBC type 2 Driver relies on plat<strong>for</strong>m- and database-specific code to access the<br />

database. The application loads the JDBC Driver and the driver uses plat<strong>for</strong>m- and<br />

database-specific code to access <strong>DB2</strong>. This driver is also known as the “app” driver which<br />

refers to the implementation class name com.ibm.db2.jdbc.app.<strong>DB2</strong>Driver. This name and<br />

driver class name only applies to the old driver (not the universal) and applies only to <strong>DB2</strong><br />

<strong>for</strong> Multiplat<strong>for</strong>ms. This is the most common driver type used, and offers the best<br />

per<strong>for</strong>mance. However, as the driver code is plat<strong>for</strong>m-specific, a different version has to be<br />

coded (by the database vendor) <strong>for</strong> each plat<strong>for</strong>m.<br />

The new Universal Driver has a Type 2 implementation available.<br />

► Type 3<br />

With this driver type, also referred to as the “net” driver (implementation class<br />

com.ibm.db2.jdbc.net.<strong>DB2</strong>Driver), the JDBC API calls are routed through a middleware<br />

product using standard network protocols such as TCP/IP. The driver itself is written in<br />

Java. The middleware translates these calls into database-specific calls to access the<br />

target database and returns data to the calling application. In the case of <strong>DB2</strong>, this task is<br />

per<strong>for</strong>med by a program called the JDBC applet server. <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 does<br />

not supply a Type 3 Driver. <strong>DB2</strong> <strong>for</strong> Linux, Unix and Windows still has a so-called network<br />

292 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


or net driver, but if you are not using it already, you are strongly encouraged to use the<br />

Type 4 Driver instead.<br />

► Type 4<br />

A Type 4 Driver is fully written in Java, and provides remote connectivity using DRDA<br />

within <strong>IBM</strong> products. As the driver is fully written in Java, it can be ported to any plat<strong>for</strong>m<br />

that supports that DBMS protocol without change, thus allowing applications to also use it<br />

across plat<strong>for</strong>ms without change.<br />

This driver type has been implemented through the <strong>IBM</strong> <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ<br />

and JDBC. This driver is also known as the <strong>DB2</strong> Universal Driver <strong>for</strong> Java Common<br />

Connectivity or JCC. In addition, the Universal Driver also provides Type 2 connectivity.<br />

For more in<strong>for</strong>mation on these Drivers, see the book <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390: Ready <strong>for</strong><br />

Java, SG24-6435.<br />

The <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC is an entirely new driver, rather than a<br />

follow-on to any other <strong>DB2</strong> JDBC drivers. The <strong>DB2</strong> Universal Driver has the following<br />

advantages over the previous solutions:<br />

► One single driver <strong>for</strong> the Unix, Windows, and z/<strong>OS</strong> plat<strong>for</strong>ms, improving portability and<br />

consistent behavior of applications.<br />

► Improved integration with <strong>DB2</strong>.<br />

► Type 4 Driver functionality <strong>for</strong> thin clients, as well as Type 2 functionality.<br />

► Easier installation and deployment. As a Type 4 Driver is completely written in Java, it is<br />

easy to deploy; you only have to ship the jar files containing the Driver code to the required<br />

machine, change the classpath, and you are done. In addition, the use of a Type 4 Driver<br />

does not require any setup in <strong>DB2</strong>, such as cataloging entries in the Database, Node, and<br />

DCS directories. For <strong>DB2</strong> on z/<strong>OS</strong> you only have to use the following URL syntax:<br />

jdbc:db2://:/<br />

► 100 percent Java application development process <strong>for</strong> SQLJ<br />

► 100 percent JDBC 3.0 compliance. Since <strong>DB2</strong> <strong>UDB</strong> V8.1.3 (FixPak 3), the Universal<br />

Driver is JDBC 3.0 compliant. The version that is made available with z/<strong>OS</strong> is also JDBC<br />

3.0 compliant.<br />

► Significant per<strong>for</strong>mance improvements <strong>for</strong> both JDBC and SQLJ applications on the Linux,<br />

Unix, and Windows plat<strong>for</strong>ms.<br />

► Trace improvements.<br />

In general, you should use Universal Driver type 2 connectivity <strong>for</strong> Java programs that run on<br />

the same z/<strong>OS</strong> system as the target <strong>DB2</strong> subsystem. Use Universal Driver type 4 connectivity<br />

<strong>for</strong> Java programs that run on a different system from the target <strong>DB2</strong> subsystem.<br />

For Java applications, application connectivity from a z/<strong>OS</strong> LPAR to a remote <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong><br />

system does not need a <strong>DB2</strong> instance anymore. The z/<strong>OS</strong> Application Connectivity to <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> optional feature can be installed to provide Universal Driver type 4 connectivity.<br />

7.3.1 Per<strong>for</strong>mance measurement<br />

The per<strong>for</strong>mance objectives were to verify that:<br />

► The <strong>DB2</strong> Universal JDBC type 2 Driver provides better or equivalent per<strong>for</strong>mance <strong>for</strong><br />

workloads using container managed persistence (CMP) and better per<strong>for</strong>mance <strong>for</strong><br />

traditional workloads that use the type 2 <strong>IBM</strong> <strong>DB2</strong> App Driver.<br />

Chapter 7. Networking and e-business 293


► The <strong>DB2</strong> Universal JDBC type 4 Driver provides better per<strong>for</strong>mance than the current<br />

JDBC type 3 Driver. Note that the type 3 JDBC Driver or “net” driver is deprecated.<br />

► The balancing features of the <strong>DB2</strong> Universal Driver offer good per<strong>for</strong>mance and a good<br />

choice of functions.<br />

Starting with V5.0.2 WebSphere is supporting the new <strong>DB2</strong> Universal Driver.<br />

WebSphere V5.0.2 z/<strong>OS</strong> - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 - Servlet workload<br />

Different test cases were measured and are presented in this section.<br />

<strong>DB2</strong> universal type 2 Driver vs. legacy JDBC 2.0 Driver - local environment<br />

WAS V5.0.2 and <strong>DB2</strong> V8 are running in the same LPAR. The throughput of this configuration<br />

with the Type 2 legacy Driver is compared to the configuration with the new Type 2 Driver, see<br />

Figure 7-6.<br />

WebSphere z/<strong>OS</strong> - <strong>DB2</strong> z/<strong>OS</strong> V8 - Servlet workload<br />

Legacy JDBC 2.0 driver vs. JCC type 2<br />

WebSphere<br />

V502<br />

servlet<br />

WebSphere<br />

V502<br />

servlet<br />

z/<strong>OS</strong> 1.4<br />

legacy<br />

JDBC<br />

type 2<br />

JCC<br />

T2<br />

1.8.36<br />

<strong>DB2</strong> V8 <strong>for</strong><br />

z/<strong>OS</strong><br />

<strong>DB2</strong> V8 <strong>for</strong><br />

z/<strong>OS</strong><br />

Figure 7-6 <strong>DB2</strong> Universal Type 2 Driver vs. legacy JDBC 2.0 Driver<br />

An increase of 2% throughput is noticed with the <strong>DB2</strong> Universal Type 2 Driver. There is no<br />

reason to stop you from using the new JCC Type 2 Driver.<br />

If you still have the legacy Drivers in your CLASSPATH, you must make sure that the<br />

db2jcc.jar file is in the CLASSPATH, ahead of the legacy Driver files, because some classes<br />

have the same name in the legacy and the <strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC.<br />

However, to avoid confusion it is probably best to only have one set of drivers (old or new) in<br />

the CLASSPATH.<br />

<strong>DB2</strong> universal type 2 Driver - Gateway <strong>DB2</strong> vs. <strong>DB2</strong> universal type 4 Driver<br />

Although it seems unusual to establish a connection to a remote <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> with a fully<br />

implemented <strong>DB2</strong> subsystem, it was your only choice in the past since there was no <strong>DB2</strong><br />

client on the z/<strong>OS</strong> plat<strong>for</strong>m available. Besides the license cost <strong>for</strong> the <strong>DB2</strong> software, the <strong>DB2</strong><br />

subsystem used also memory and CPU resources on the WAS LPAR.<br />

294 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Trans/sec - higher is better<br />

350<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

2 %<br />

Legacy Driver<br />

JCC


With the z/<strong>OS</strong> Application Connectivity to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> feature that provides <strong>DB2</strong> universal<br />

Driver type 4 connectivity, the use of a gateway <strong>DB2</strong> is avoided and a 73% increase in<br />

throughput on the WAS LPAR is realized, see Figure 7-7.<br />

WebSphere<br />

V502<br />

servlet<br />

WebSphere<br />

V502<br />

servlet<br />

WebSphere z/<strong>OS</strong> - <strong>DB2</strong> z/<strong>OS</strong> V8 - Servlet workload<br />

JCC type 2/Gateway <strong>DB2</strong> vs. JCC type 4<br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.3<br />

JCC<br />

T2<br />

1.8.36<br />

JCC<br />

T4<br />

1.8.36<br />

<strong>DB2</strong> V8<br />

<strong>for</strong> z/<strong>OS</strong><br />

D<br />

D<br />

F<br />

D <strong>DB2</strong> V8<br />

D <strong>for</strong> z/<strong>OS</strong><br />

F<br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.3<br />

D<br />

D<br />

F<br />

<strong>DB2</strong> V8<br />

<strong>for</strong> z/<strong>OS</strong><br />

Figure 7-7 <strong>DB2</strong> Universal Type 2 Driver - Gateway <strong>DB2</strong> vs. <strong>DB2</strong> Universal Type 4 Driver<br />

<strong>DB2</strong> Universal Type 2 Driver vs. <strong>DB2</strong> Universal Type 4 Driver - Local environment<br />

In Figure 7-8 we compare the JCC Type 2 and Type 4 Driver in a local environment. The<br />

intention is to demonstrate the difference in per<strong>for</strong>mance between the Type 2 and Type 4<br />

Driver in a local environment in the same LPAR as <strong>DB2</strong>.<br />

Since the WebSphere Application Server is local to the DBMS (same LPAR), the Type 2<br />

Driver can do “native” calls to <strong>DB2</strong>; this configuration normally provides the best per<strong>for</strong>mance.<br />

Your Java application that is running under the control of WAS can talk to <strong>DB2</strong> through the<br />

Type 2 JDBC Driver, and a local RRS attachment.<br />

Using the Type 4 Driver in this configuration is not a recommended setup <strong>for</strong> a production<br />

environment, since all SQL requests go through DRDA over TCP/IP (so through the TCP/IP<br />

stack) into <strong>DB2</strong>’s DDF address space. Even though DRDA is a very efficient database<br />

communication protocol, it is normally more expensive than going through the local RRS<br />

attachment as will become clear from this test case.<br />

Trans/sec - higher is better<br />

500<br />

400<br />

300<br />

200<br />

100<br />

73 %<br />

14 %<br />

0<br />

WebSphere LPAR<br />

Remote <strong>DB2</strong><br />

JCC type2/<strong>DB2</strong><br />

JCC type 4<br />

Chapter 7. Networking and e-business 295


WebSphere z/<strong>OS</strong> - <strong>DB2</strong> z/<strong>OS</strong> V8 - Servlet workload<br />

JCC type 2 vs. JCC type 4 in local environment<br />

WebSphere<br />

V502<br />

servlet<br />

WebSphere<br />

V502<br />

servlet<br />

z/<strong>OS</strong> 1.3<br />

JCC<br />

T2<br />

1.8.36<br />

z/<strong>OS</strong> 1.3<br />

JCC<br />

T4<br />

1.8.36<br />

<strong>DB2</strong> V8<br />

<strong>for</strong> z/<strong>OS</strong><br />

T<br />

C D<br />

P/ D<br />

I F<br />

P<br />

<strong>DB2</strong> V8<br />

<strong>for</strong> z/<strong>OS</strong><br />

Figure 7-8 <strong>DB2</strong> Universal Type 2 Driver vs. <strong>DB2</strong> Universal Type 4 Driver<br />

Using the setup with the <strong>DB2</strong> Universal Type 4 Driver (DRDA), the throughput is reduced by<br />

51% when compared to the Type 2 Driver RRSAF connection to <strong>DB2</strong>. The Type 2 Driver<br />

communicates with <strong>DB2</strong> via cross-memory calls where the Type 4 Driver uses the TCP/IP<br />

stack.<br />

The setup with the Type 4 Driver is not that unusual. If access to several <strong>DB2</strong> subsystems in<br />

the same LPAR is needed, you will need the Type 4 Driver as this is not supported by the<br />

Type 2 Driver with an RRSAF connection.<br />

This measurement was executed using JDK 1.3.1. The per<strong>for</strong>mance of the setup with the<br />

Type 4 Driver improves with JDK 1.4.2.<br />

JDK 1.4.2 has seen the JIT compiler optimized, and the Java TCP/IP implementation<br />

improved. A separate per<strong>for</strong>mance comparison is shown in Figure 7-9.<br />

Notice that JDK versions go in pairs with WAS versions:<br />

► WAS 5.0.2 and JDK 1.3.1<br />

► WAS 5.1.0 and JDK 1.4.2<br />

296 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Trans/sec - higher is better<br />

350<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

ITR<br />

-51%<br />

JCC type 2<br />

JCC type 4


WebSphere z/<strong>OS</strong> - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 - Servlet workload<br />

WAS 5.0.2/JDK 131 vs. WAS 5.1.0/JDK 142<br />

Figure 7-9 JDK improvements<br />

WebSphere AIX - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

For this configuration tests were run with the Type 4 Driver as the Type 2 Driver is a local<br />

driver. With the Type 2 Driver you need something in the middle and this “thing in the middle”<br />

is <strong>DB2</strong> Connect. With the Type 4 Driver and WAS, we do not need <strong>DB2</strong> Connect with its<br />

characteristics of connection pooling and concentrator because WAS provides the same<br />

functionality.<br />

JDBC .app/<strong>DB2</strong> Connect vs. JCC Type 4 - Servlet workload<br />

As shown in Figure 7-10, JCC Type 4 outper<strong>for</strong>ms the .app/<strong>DB2</strong> Connect with 10% increased<br />

throughput on WebSphere V5 AIX. On <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> the improvement is marginal.<br />

WebSphere<br />

V5 +<br />

servlets<br />

16 % increase in normalized throughput caused by JDK 142 improvement<br />

Universal Driver Type 4 benefits from JDK 142 TCP/IP optimization<br />

z/<strong>OS</strong> 1.6<br />

WebSphere<br />

V5<br />

servlet<br />

JCC<br />

T4<br />

2.3.66<br />

D<br />

<strong>DB2</strong> <strong>for</strong><br />

D z/<strong>OS</strong> V8<br />

F<br />

Figure 7-10 JDBC .app/<strong>DB2</strong> Connect vs. JCC Type 4 - CMP workload<br />

Trans/sec - higher is better<br />

700<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

ITR<br />

16%<br />

WAS V5.0.2/JDK 131<br />

WAS 5.1.0/JDK 142<br />

WebSphere /AIX - <strong>DB2</strong> z/<strong>OS</strong> V7 - Servlet workload<br />

JDBC .app/<strong>DB2</strong> Connect vs. JCC Type 4<br />

AIX<br />

WebSphere<br />

V5 +<br />

servlets<br />

<strong>DB2</strong><br />

V8<br />

JDBC<br />

.app<br />

driver<br />

JCC<br />

T4<br />

FP2<br />

<strong>DB2</strong> V8<br />

Connect<br />

FP2<br />

<strong>DB2</strong> <strong>for</strong><br />

<strong>OS</strong>/390<br />

and z/<strong>OS</strong> V7<br />

D<br />

D<br />

F<br />

Trans/second - higher is better<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

10%<br />

ITR AIX ITR z/<strong>OS</strong><br />

.app/<strong>DB2</strong>Connect<br />

JCC T4 FP2<br />

Chapter 7. Networking and e-business 297


<strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - CMP workload<br />

As shown in Figure 7-11, SQLJ outper<strong>for</strong>ms JDBC with 25% increased throughput on <strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> and 11% on WebSphere V5 AIX. Besides the benefits of static SQL, persistence in<br />

WebSphere with SQLJ requires fewer API calls compared to JDBC.<br />

WebSphere /AIX - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 - CMP workload<br />

JCC FP4 type 4 - JDBC vs. SQLJ<br />

AIX<br />

WebSphere<br />

V5.0.2<br />

CMP<br />

JCC<br />

T4<br />

FP4<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

Figure 7-11 <strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - CMP workload<br />

<strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - Servlet workload<br />

Figure 7-12 shows that the best per<strong>for</strong>mance is achieved using SQLJ when the SQLJ files are<br />

compiled with the option -db2optimize.<br />

Figure 7-12 <strong>DB2</strong> Universal Type 4 Driver - JDBC vs. SQLJ - Servlet workload<br />

298 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

D<br />

D<br />

F<br />

Trans/second - higher is better<br />

200<br />

150<br />

100<br />

50<br />

0<br />

11 %<br />

25 %<br />

ITR AIX ITR z/<strong>OS</strong><br />

WebSphere /AIX - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 - Servlet Workload<br />

JCC FP7 type 4 - JDBC vs. SQLJ<br />

AIX<br />

WebSphere<br />

V6 beta<br />

JCC<br />

T4<br />

FP7<br />

<strong>DB2</strong> <strong>for</strong><br />

z/<strong>OS</strong> V8<br />

D<br />

D<br />

F<br />

Trans/second - higher is better<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

JDBC<br />

SQLJ<br />

-2%<br />

5.5%<br />

6%<br />

ITR AIX ITR z/<strong>OS</strong><br />

SQLJ<br />

-db2optimize<br />

9%<br />

JDBC<br />

SQLJ


SQLJ programs need to use explicitly defined connection contexts as always has been<br />

recommended.<br />

The test cases presented used WebSphere and the universal Type 4 Driver. The difference in<br />

per<strong>for</strong>mance with using the Type 2 Driver and <strong>DB2</strong> Connect instead is negligible as WAS will<br />

per<strong>for</strong>m connection pooling with the Type 4 Driver.<br />

JCC Type 4 vs. JCC Type 4 with <strong>DB2</strong> Connect - IRWW workload<br />

Figure 7-13 illustrates the per<strong>for</strong>mance results of running IRWW workload using JCC Type 4<br />

connection going from distributed plat<strong>for</strong>m to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> in comparison of using JCC Type<br />

4 to connect to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> through <strong>DB2</strong> Connect in gateway mode. The measurements<br />

show a 2.3% [(382.14 – 373.73) / 382.14 * 100%] internal throughput degradation by going<br />

through <strong>DB2</strong> Connect rather than going directly to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>.<br />

In the <strong>DB2</strong> Connect scenario, both JCC driver and <strong>DB2</strong> Connect reside on the same<br />

machine, and <strong>DB2</strong>CONNECT_IN_APP_PROCESS is defined as NO in order to have the<br />

application connect to the <strong>DB2</strong> Connect EE Server and then have the host connection run<br />

within an agent.<br />

400<br />

350<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

JCC Type 4 Direct vs. JCC Type 4 with <strong>DB2</strong> Connect<br />

382.14 373.73<br />

JCC Type 4 Direct JCC Type 4 with<br />

<strong>DB2</strong> Connect<br />

Figure 7-13 JCC Type 4 vs. JCC Type 4 with <strong>DB2</strong> Connect<br />

Normalized z/<strong>OS</strong><br />

Transaction / Second<br />

Conclusion<br />

The new <strong>DB2</strong> Universal Type 2 Driver per<strong>for</strong>ms as well and better than the legacy JDBC App<br />

Driver and the Type 4 Driver per<strong>for</strong>ms better than the Type 3 Net Driver.<br />

Recommendations<br />

We recommend the usage of <strong>DB2</strong> universal Type 2 Driver in a local <strong>DB2</strong> environment. The<br />

Type 4 Driver is preferred when accessing a remote <strong>DB2</strong> server in a distributed environment.<br />

Use the <strong>DB2</strong> Universal Type 4 Driver to access a <strong>DB2</strong> server directly when connections are<br />

already pooled by other application servers, <strong>for</strong> example, WebSphere. FixPak 10 has been<br />

recently made available and it supports connection concentration and sysplex workload<br />

balancing.<br />

Chapter 7. Networking and e-business 299


Use <strong>DB2</strong> Connect when a high amount of client connections is expected, <strong>for</strong> example, from<br />

applets, in its quality as connection pool/connection concentrator. The measured overhead,<br />

shown in Figure 7-13, is about 2%.<br />

Where possible, use SQLJ. Throughput is higher as well on the server as on the requester<br />

with SQLJ. Static SQL is faster than dynamic SQL, because at run time only the authorization<br />

<strong>for</strong> packages and plans must be checked prior to the execution of the program. In contrast to<br />

that, dynamic SQL statements require the SQL statements to be parsed, table and view<br />

authorization to be checked, and the access path to be determined. Besides better<br />

per<strong>for</strong>mance, SQLJ offers availability and usability benefits over JDBC:<br />

► Less and easier code, easier to maintain<br />

► Authorization on package level<br />

► Easier deployment with the fully portable serialized profile when using the Universal Driver<br />

if compared to the old driver.<br />

Balancing features of JCC with WebSphere V5.1.1 AIX - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

Starting from the GA version of <strong>DB2</strong> Universal Driver FixPak 10, <strong>DB2</strong> has introduced<br />

connection concentrator and sysplex workload balancing features <strong>for</strong> all Java type 4<br />

connections to <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> servers. These two new features are built upon the JCC global<br />

object pooling architecture, and are similar in functions to <strong>DB2</strong> Connect's connection<br />

concentrator and sysplex support.<br />

The objective of these measurements is to evaluate the overhead of reusing JCC transports<br />

with connection concentrator and sysplex workload balancing enabled, and compare it to the<br />

overhead of <strong>DB2</strong> Connect and JCC T2 driver.<br />

The IRWW workload was run with the JCC T4 configuration shown in Figure 7-14.<br />

IRWW<br />

Workstation<br />

IRWW<br />

Workload<br />

Driver<br />

Figure 7-14 JCC T4 configuration <strong>for</strong> balancing options<br />

Connection concentrator and sysplex workload balancing are two separate JCC features.<br />

This is different from <strong>DB2</strong> Connect where connection concentrator must be enabled be<strong>for</strong>e<br />

you can exploit sysplex load balancing and failover routing at the transaction boundary. It is<br />

possible to enable connection concentrator or sysplex workload balancing in the JCC data<br />

source custom properties.<br />

300 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

WebShpere<br />

AIX zSeries<br />

J<br />

C<br />

C<br />

T<br />

4<br />

LPAR D7<br />

DB8A<br />

LPAR D8<br />

DB8B


The JCC connection concentrator feature is available only when <strong>DB2</strong> on z/<strong>OS</strong> is the target<br />

server. If you need concentration function <strong>for</strong> connections to <strong>DB2</strong> <strong>UDB</strong> databases <strong>for</strong><br />

distributed plat<strong>for</strong>ms, you need <strong>DB2</strong> Connect today. Also, JCC connection concentrator only<br />

works with T4 direct connection to <strong>DB2</strong> servers. Both JCC connection concentrator and JCC<br />

sysplex workload balancing features are automatically disabled if JCC driver detects that it is<br />

connected to a <strong>DB2</strong> server via a <strong>DB2</strong> Connect gateway. In this case the <strong>DB2</strong> Connect<br />

gateway will be responsible <strong>for</strong> handling connection concentration and workload balancing.<br />

Connection concentrator was designed <strong>for</strong> environments where a large number of clients are<br />

connecting to the host and there is the need to limit the number of connections resources on<br />

the host side. There is some overhead with switching applications to transports connected to<br />

the host at the transaction level, but much of this overhead is incurred on client machines<br />

where CPU and memory are less expensive and less constrained.<br />

The same IRWW workload was run with the <strong>DB2</strong> Connect configuration shown in<br />

Figure 7-15.<br />

Windows<br />

Workstation<br />

IRWW<br />

Workload<br />

Driver<br />

Figure 7-15 JCC T2 and <strong>DB2</strong> Connect configuration<br />

AIX zSeries<br />

WebShpere<br />

JCC T2<br />

<strong>DB2</strong><br />

Connect<br />

LPAR D7<br />

DB8A<br />

LPAR D8<br />

DB8B<br />

The graph shown in Figure 7-16 compares the per<strong>for</strong>mance degradations of JCC T4 and <strong>DB2</strong><br />

Connect be<strong>for</strong>e and after both are configured to concentrate transports or agents with the<br />

same connection-to-transport/agent ratio. This approach gives us a fair comparison of their<br />

respective connection concentration and load balancing efficiency. The per<strong>for</strong>mance impact<br />

on <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> is measured in normalized <strong>DB2</strong> transactions per second (internal<br />

throughput).<br />

Chapter 7. Networking and e-business 301


JCC Type 4 Direct<br />

4:3 Concentration<br />

JCC Type 4 Direct no<br />

Concentration<br />

<strong>DB2</strong> Connect 4:3<br />

Concentration<br />

<strong>DB2</strong> Connect no<br />

Concentration<br />

Figure 7-16 Per<strong>for</strong>mance of JCC T4 vs. <strong>DB2</strong> Connect<br />

We can observe that the <strong>DB2</strong> Connection concentration degradation is 13.5%, versus the<br />

JCC Type 4 concentration degradation of 12%. The value is very similar.<br />

In determining the choice of function to implement concentration and balancing, keep in mind<br />

that the two options have different characteristics and the requirements of the application<br />

must take into account the considerations summarized in Figure 7-4<br />

Table 7-4 Comparing the key points of the two solutions<br />

<strong>DB2</strong> Connect JCC Driver<br />

Wider scope<br />

<strong>DB2</strong> connect is a gateway. It is aware of all <strong>DB2</strong><br />

requests. it is capable of supporting connection<br />

concentration across multiple JVMs on one or<br />

more machines. JCC driver only runs within the<br />

scope of a single JVM, it is not aware of the<br />

connections of another JVM and it can only<br />

concentrate connections originated from its own<br />

JVM<br />

Connection pooling<br />

Connection pooling allows agents and<br />

connections to be reused by other users and<br />

programs. JCC T4, at the time writing, doesn't<br />

have connection pooling, and it must either rely<br />

on external application server such as<br />

WebSphere or extra programming in standalone<br />

Java applications to support connection pooling.<br />

Ease of software upgrade<br />

From a software management perspective, it is<br />

easier to have the software in one place, any<br />

upgrades only have to be done to the <strong>DB2</strong><br />

Connect Enterprise Edition (EE) server (a<br />

centralized gatekeeper <strong>for</strong> <strong>DB2</strong> servers on z/<strong>OS</strong>),<br />

not to every JCC driver spread throughout the<br />

entire enterprise.<br />

302 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

JCC T4 vs. <strong>DB2</strong> Connect<br />

369.34<br />

428.84<br />

422.23<br />

0 100 200 300 400 500<br />

487.03<br />

Normalized z/<strong>OS</strong><br />

Transaction /<br />

Second<br />

Better granularity<br />

<strong>DB2</strong> Connect can only specify the maximum<br />

number of coordinator agents allowed at the<br />

server level. it cannot control connection agents<br />

allocated to each JVM. JCC driver allows users to<br />

specify the maximum number of allowed<br />

transport objects at datasource level and at the<br />

driver level. This gives JCC driver much better<br />

granularity to manage transport resources.<br />

Better Per<strong>for</strong>mance<br />

The per<strong>for</strong>mance measurements show that JCC<br />

T4 has slightly better per<strong>for</strong>mance than <strong>DB2</strong><br />

Connect V8 when running with the same<br />

connection to transport/agent ratio


7.3.2 <strong>DB2</strong> Universal Driver X/Open XA support<br />

One of the key reasons <strong>for</strong> using the Universal Driver in a type 2 architecture is <strong>for</strong> local<br />

application per<strong>for</strong>mance and <strong>for</strong> distributed transaction support (XA). XA support was first<br />

provided in the <strong>DB2</strong> Universal Type 2 Driver and became available in the Type 4 Driver with<br />

<strong>DB2</strong> V8.1 <strong>for</strong> Multiplat<strong>for</strong>ms FP4. MQSeries® classes <strong>for</strong> Java Message Service include the<br />

JMS XA interface. These allow MQ JMS to participate in a two-phase commit that is<br />

coordinated by a transaction manager that complies with the Java Transaction API (JTA).<br />

Description<br />

If the application will be involved in a distributed transaction, the<br />

COM.ibm.db2.jdbc.<strong>DB2</strong>XADataSource class should be used when defining <strong>DB2</strong> data<br />

sources within the WebSphere Application Server.<br />

Per<strong>for</strong>mance<br />

The internal throughput was measured <strong>for</strong> a servlet workload using the Type 2 non-XA versus<br />

the Type 2 XA compliant driver. The environment used in this measurement was z/<strong>OS</strong> V1.3,<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 and WAS V5.0.2. See Figure 7-17.<br />

WebSphere z/<strong>OS</strong> - <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 - Servlet workload ...<br />

JCC type 2 - non-XA vs. XA<br />

WebSphere<br />

V502<br />

servlet<br />

z/<strong>OS</strong> 1.3<br />

JCC<br />

T2<br />

1.8.36<br />

<strong>DB2</strong><br />

<strong>for</strong> z/<strong>OS</strong><br />

V8<br />

Figure 7-17 Servlet workload - Type 2 non-XA vs. Type 2 XA compliant driver<br />

200<br />

150<br />

100<br />

50<br />

0<br />

non-XA driver<br />

The results are less than 1% of internal throughput ratio (ITR= Units of Work/Processor Busy)<br />

reduction when using the type 2 XA compliant driver. This means that there is practically no<br />

extra overhead in choosing the driver with distributed transaction support from WebSphere.<br />

<strong>DB2</strong> client application programs that run under the <strong>DB2</strong> Universal JDBC Driver can use<br />

distributed transaction support in <strong>DB2</strong> V7 and <strong>DB2</strong> V8. <strong>DB2</strong> V8 servers include native XA<br />

mode support. However, <strong>DB2</strong> V7 servers do not have native XA mode support, so the <strong>DB2</strong><br />

Universal JDBC Driver emulates the XA mode support using the existing <strong>DB2</strong> DRDA<br />

two-phase commit protocol. This XA mode emulation uses a <strong>DB2</strong> table named<br />

SYS<strong>IBM</strong>.INDOUBT to store in<strong>for</strong>mation about indoubt transactions. <strong>DB2</strong> uses a package<br />

named T4XAIndbtPkg to per<strong>for</strong>m SQL operations on SYS<strong>IBM</strong>.INDOUBT.<br />

XA driver<br />

Normalized transactions<br />

per second<br />

Chapter 7. Networking and e-business 303


The SYS<strong>IBM</strong>.INDOUBT table and the package can be created by invoking the JCC In-Doubt<br />

utility. It is a prerequisite to manually run this utility as a user having SYSADM privileges<br />

against the <strong>DB2</strong> V7 location in order to accomplish XA (global /distributed) transactions. The<br />

syntax is as follows:<br />

java com.ibm.db2.jcc.<strong>DB2</strong>T4XAIndoubtUtil -url jdbc:db2://:/<br />

-user -password <br />

This has recently changed with PQ95881: Now you can run the "XAindoubt.." and the create<br />

of the indoubt table separately.<br />

7.3.3 Miscellaneous items<br />

Java Data Types<br />

The Java language does not have a fixed length character string data type; every string is<br />

variable length. In <strong>DB2</strong>, on the other hand, in most cases, fixed length character columns<br />

defined as CHAR(n) are used. In <strong>DB2</strong> V8 all predicates comparing string CHAR and<br />

VARCHAR data types with the same CCSID are stage 1 and indexable; even <strong>for</strong> unlike<br />

CCSIDs the predicate will still be stage 1 and indexable if the “column” side of it is in Unicode<br />

since all predicates that compare unlike CCSIDs are evaluated in the Unicode encoding<br />

scheme.<br />

KEEPDYNAMIC YES<br />

KEEPDYNAMIC specifies whether <strong>DB2</strong> keeps already prepared dynamic SQL statements in<br />

the local dynamic statement cache after commit points. Bind a copy of the <strong>DB2</strong> Universal<br />

Driver packages with a different collection id:<br />

► KEEPDYNAMIC=YES<br />

► collection=<br />

The keepDynamic connection and JdbcCollection property values <strong>for</strong> the DataSource<br />

specified must match the values that were specified when the bind was run. These values can<br />

be set using:<br />

► The setXXX methods<br />

► In a java.util.Properties value in the info parameter of a DriverManager.getConnection call<br />

► The java.lang.String value in the url parameter of a DriverManager.getConnection call<br />

The following measurement was executed:<br />

WebSphere V5.0.2 on AIX was used to access <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8. The workload was using<br />

container managed persistence con<strong>for</strong>ming to the SpecjApp2002 benchmark.<br />

The results are presented in Figure 7-18.<br />

304 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Trans/second - higher is better<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

9 %<br />

KeepDynamic YES<br />

20 %<br />

ITR AIX ITR z/<strong>OS</strong><br />

keepdyn no<br />

keepdyn yes<br />

Figure 7-18 <strong>DB2</strong> Universal Driver - KEEPDYNAMIC YES<br />

SpecJApp2002<br />

WebSphere/AIX V502- <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

ITR = tps/cpu%*100<br />

CPU is saved on the client (WebSphere) and in <strong>DB2</strong> on the server. Throughput improved with<br />

9% on the client and 20% on the <strong>DB2</strong> server.<br />

In order to benefit from per<strong>for</strong>mance improvements the following PTFs/APARs should be<br />

applied: PQ86787/UQ87049, PQ87126/UQ88971 and PQ87129/UQ87633.<br />

Conclusion<br />

The statements are saved on thread level and can consume a significant amount of storage.<br />

Type 2 distributed threads cannot turn inactive and <strong>DB2</strong> resources <strong>for</strong> distributed threads are<br />

not freed at commit. There<strong>for</strong>e this is not recommended <strong>for</strong> storage constrained systems.<br />

Recommendation<br />

KEEPDYNAMIC(YES) is recommended <strong>for</strong> applications with a limited amount of SQL<br />

statements that are executed very often. It is not recommended <strong>for</strong> applications with a large<br />

number of SQL statements that are executed infrequently.<br />

LOB streaming<br />

In prior releases, Universal Clients and Linux, UNIX, and Windows servers had to read the<br />

entire LOB to determine its length prior to flowing it to <strong>DB2</strong>.<br />

LOB streaming, activated by the fullyMaterializeLobData property, allows the <strong>DB2</strong> universal<br />

client or a <strong>DB2</strong> <strong>for</strong> Multiplat<strong>for</strong>ms server to not know the total length of a LOB value prior to<br />

sending a LOB value. This improves per<strong>for</strong>mance by eliminating the need to read the entire<br />

LOB to determine its length prior to sending the LOB value. <strong>DB2</strong> continues to provide the total<br />

length of a LOB value, but it is now able to read in the LOB immediately without knowing the<br />

exact length up-front.<br />

The main benefit is per<strong>for</strong>mance. But there is another advantage. It is not always possible to<br />

determine a LOB's attributes (like length and nullness) up-front, <strong>for</strong> example when a client is<br />

acting on behalf of a CLI application that is being supplied with chunks of a LOB value in a<br />

piecemeal fashion using the SQLPutData API. There<strong>for</strong>e this improvement provides a more<br />

flexible mechanism whereby the sender can defer indicating the nullness and/or the length of<br />

a LOB value until a chunk is ready to be sent.<br />

Chapter 7. Networking and e-business 305


Batch updates<br />

A batched update is a set of multiple update statements that are submitted to the database <strong>for</strong><br />

processing as a batch. Sending multiple update statements to the database together as a unit<br />

can, in some situations, be much more efficient than sending each update statement<br />

separately. It reduces the number of times the application has to cross over to the JDBC<br />

Driver. This ability to send updates as a unit, referred to as the batched update facility, is one<br />

of the features of the JDBC 2.0 API, and is now supported with the <strong>DB2</strong> Universal Driver.<br />

7.4 ODBC enhancements<br />

ODBC enhancements are mentioned <strong>for</strong> completeness.<br />

7.4.1 ODBC Unicode support<br />

ODBC now supports Unicode <strong>for</strong>mats UTF-8 and UCS-2. In addition, a new ODBC<br />

initialization keyword, CURRENTAPPENSCH, lets you specify the encoding scheme that you<br />

want the ODBC Driver to use <strong>for</strong> input and output of host variable data, SQL statements, and<br />

all character string arguments of the ODBC application programming interfaces. You can<br />

specify Unicode, EBCDIC, or ASCII encoding scheme.<br />

7.4.2 ODBC long name support<br />

ODBC <strong>for</strong> z/<strong>OS</strong> has been enhanced to be able to support the long names in V8 new-function<br />

mode. This means changes to the following ODBC functions.<br />

Support <strong>for</strong> longer names in the INI file variables<br />

The keyword strings <strong>for</strong> the following initialization keywords will be extended to support longer<br />

names:<br />

► CLISCHEMA<br />

► COLLECTIONID<br />

► CURRENTFUNCTIONPATH<br />

► CURRENTSQLID<br />

► SCHEMALIST<br />

► SYSSCHEMA<br />

ODBC catalog functions<br />

As a result of the name changes in the catalog, the ODBC catalog API needs to change the<br />

lengths of the host variables and data types in the SQLDA when fetching result sets from<br />

catalog tables. However, most of these changes are transparent to the external API. Only the<br />

data type of the REMARKS column returned by SQLColumns() and SQLTables() is changed<br />

to VARCHAR(762).<br />

7.4.3 ODBC connection authentication<br />

With V7, the <strong>DB2</strong> ODBC Driver validates the user ID and password, but their argument values<br />

are not used <strong>for</strong> end user authentication. <strong>DB2</strong> V8 implements the RACF verification support<br />

<strong>for</strong> USER/USING SQL CONNECT statement, and the ODBC Driver makes use of the user ID<br />

and password values provided on the APIs to per<strong>for</strong>m authentication.<br />

306 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


7.4.4 ODBC support <strong>for</strong> 2 MB SQL<br />

7.4.5 SQLcancel<br />

Currently, the maximum size in bytes of an SQL statement string (including white spaces)<br />

allowed on the SQLPrepare, SQLExecDirect and SQLNativeSql APIs is 32765. <strong>DB2</strong> V8<br />

running in NFM supports a maximum statement size of 2MB (2097152). <strong>DB2</strong> V8 ODBC will<br />

now support SQL statements up to 2 MB in size when connected to <strong>DB2</strong> V8 servers running<br />

in NFM.<br />

This enhancement requires APAR PQ88582/PTF UQ91257.<br />

The SQL cancel() statement allows an ODBC/CLI or JDBC application to cancel an SQL<br />

request long running on a <strong>DB2</strong> server. Note that SQL cancel() is at a more granular level than<br />

the <strong>DB2</strong> -CANCEL THREAD command. SQLcancel() only rolls back the currently executing<br />

SQL statement, not the entire unit of work. In addition, the thread is not destroyed in the<br />

process, but is allowed to continue processing.<br />

If the database server is not in an interruptible state, the request completed be<strong>for</strong>e <strong>DB2</strong> can<br />

interrupt, or the request is not interruptible, then <strong>DB2</strong> returns a DRDA reply message back to<br />

the client confirming the attempt. A new SQLCODE -952 is returned if the SQL statement was<br />

interrupted (rollback worked). If the SQL statement just reads data (not write), then we issue<br />

-952 even if rollback did not work.<br />

Currently only dynamic SQL statements are interruptible. Stored procedures cannot be<br />

interrupted. Transaction level SQL statements like CONNECT, COMMIT and ROLLBACK<br />

cannot be interrupted. Even BIND PACKAGE cannot be interrupted.<br />

7.5 XML support in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

7.5.1 XML extender<br />

For the past few years, XML has increasingly become the de facto data <strong>for</strong>mat on the internet,<br />

on corporate intranets, and <strong>for</strong> data exchange.<br />

Up to <strong>DB2</strong> V7, you could use LOB or CLOB columns to store XML documents in relational<br />

tables. It was recommended that character objects be used to enable use of SQL character<br />

functions, such as concatenate, on the XML CLOBs.<br />

If you needed XML data from traditional relational databases, you had to create an application<br />

to convert the <strong>DB2</strong> data to the XML <strong>for</strong>mat or use the XML extender.<br />

<strong>DB2</strong> V8 provides SQL/XML publishing functions to help with XML document composition<br />

directly from <strong>DB2</strong> data.<br />

Up to <strong>DB2</strong> V7, you could use the XML extender feature <strong>for</strong> manipulating XML data into and<br />

out of <strong>DB2</strong>.<br />

Description<br />

The XML extender is a set of external programs which are defined to execute as stored<br />

procedures and user-defined functions, invoked using SQL statements. The functionality<br />

provided by the XML extender is very rich, including intact storage, shredding to relational<br />

tables, indexing and searching. However, this function is still seen as an “add on” and the<br />

external routines do not per<strong>for</strong>m as well as code inside the database engine.<br />

Chapter 7. Networking and e-business 307


Example<br />

In <strong>DB2</strong> V8 SQL/XML publishing functions become available. Storing and shredding or<br />

decomposing XML documents is still only provided in the XML extender. As an example we<br />

present in Figure 7-19 the results of shredding an XML document as a function of the<br />

document size with the XML extender.<br />

Time in second<br />

Figure 7-19 XML extender decomposition<br />

Decomposing an XML document into 3 tables of 20 columns on a z990 system takes 10 to 40<br />

seconds <strong>for</strong> document sizes ranging from 1 to 6 MB.<br />

7.5.2 XML publishing functions<br />

<strong>DB2</strong> V8 now provides seven new built-in XML publishing functions to help with XML<br />

document composition from <strong>DB2</strong> data.<br />

Description<br />

The XML publishing functions are built-in <strong>DB2</strong> functions. They run inside the <strong>DB2</strong> address<br />

spaces, unlike external User Defined Functions (UDFs), <strong>for</strong> example from the XML extender,<br />

that run in a WLM managed address space outside of <strong>DB2</strong>. The fact that the XML publishing<br />

functions are built into the <strong>DB2</strong> engine gives them better per<strong>for</strong>mance.<br />

XML data type<br />

An XML data type is an internal representation of XML, and can be used only as input to<br />

built-in functions that accept this data type as input. XML is a transient data type that cannot<br />

be stored in the database or returned to an application. Transient means that this data type<br />

only exists during query processing. There is no persistent data of this type and it is not an<br />

external data type that can be declared in application programs. In other words, the XML data<br />

type cannot be stored in a database or returned to an application.<br />

Valid values <strong>for</strong> the XML data type include the following:<br />

► An element<br />

► A <strong>for</strong>est of elements<br />

► The textual content of an element<br />

► An empty XML value<br />

308 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

XML Extender - Decomposition<br />

Decomposition by doc size<br />

z/<strong>OS</strong><br />

0 1 2 3 4 5 6 7<br />

Doc size (MBytes)


There are restrictions <strong>for</strong> the use of the XML data type:<br />

► A query result cannot contain this data type<br />

► Columns of a view cannot contain this data type<br />

► XML data cannot be used in SORT, that is GROUP BY or ORDER BY and predicates<br />

► The XML data type is not compatible with any other data type<br />

The only supported operation is to serialize (by using the XML2CLOB function) the XML value<br />

into a string that is stored as a CLOB value.<br />

XML publishing functions<br />

The new publishing functions are:<br />

► XML2CLOB<br />

The XLM2CLOB function returns a CLOB representation of an XML value.<br />

► XMLELEMENT<br />

The XMLELEMENT function returns an XML element from one or more arguments.<br />

► XMLATTRIBUTES<br />

This function constructs XML attributes from the arguments.<br />

► XMLFOREST<br />

The XMLFOREST function returns a bunch of XML elements that all share a specific<br />

pattern from a list of expressions.<br />

► XMLCONCAT<br />

The XMLCONCAT function returns a concatenation of XML elements that are generated<br />

from a concatenation of two or more arguments.<br />

► XMLAGG<br />

The XMLAGG function returns an aggregation of XML elements from a collection of XML<br />

elements.<br />

► XMLNAMESPACES<br />

The function XMLNAMESPACES returns the declaration of XML namespaces.<br />

For a detailed description of the new XML publishing functions, see XML <strong>for</strong> <strong>DB2</strong> In<strong>for</strong>mation<br />

Integration, SG24-6994.<br />

Per<strong>for</strong>mance<br />

In this section we present the XML per<strong>for</strong>mance measurements.<br />

Per<strong>for</strong>mance measurement description<br />

In this measurement we used:<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

► z/<strong>OS</strong> Release 1.4<br />

► XML extender V8<br />

► z990<br />

► ESS 800 DASD (with FICON channel)<br />

This measurement compares the per<strong>for</strong>mance of the XML built-in publishing functions to the<br />

equivalent RDB_NODE composition with the XML extender user defined functions. See<br />

Example 7-1 <strong>for</strong> the SQL used in this measurement.<br />

Example 7-1 XML publishing example<br />

Chapter 7. Networking and e-business 309


INSERT INTO PUB_TAB(DOC)<br />

SELECT XML2CLOB(<br />

XMLELEMENT(NAME "AUCT_DB",<br />

XMLAGG(<br />

XMLELEMENT(NAME "CATEGORIE",<br />

XMLATTRIBUTES(C.CATEGORY_ID AS "NO" ),<br />

XMLCONCAT (<br />

XMLELEMENT(NAME "INFORMATIONS",<br />

XMLATTRIBUTES(P.NAME AS "PERSON_NAME" ),<br />

XMLCONCAT(<br />

XMLELEMENT(NAME "STATISTIQUES",<br />

XMLFOREST(P.GENDER AS "SEXE",<br />

P.AGE AS "AGE",<br />

P.EDUCATION AS "EDUCATION",<br />

P.INCOME AS "REVENUE")<br />

),<br />

XMLELEMENT(NAME "COORDONEES",<br />

XMLFOREST(P.AD_STREET AS "RUE",<br />

P.AD_CITY AS "VILLE",<br />

P.AD_COUNTRY AS "PAYS")<br />

),<br />

XMLELEMENT(NAME "RESEAU",<br />

XMLFOREST(P.EMAILADDRESS AS "COURRIER",<br />

P.HOMEPAGE AS "PAGEPERSO")<br />

)<br />

)<br />

),<br />

XMLELEMENT(NAME "CARTEPAIEMENT", P.CREDITCARD )<br />

)<br />

)<br />

ORDER BY C.CATEGORY_ID)<br />

)<br />

)<br />

AS "result" FROM PERSON P, CATEGORY C, INTEREST I<br />

WHERE P.PERSON_ID = I.PERSON_ID<br />

AND C.CATEGORY_ID = I.CATEGORY<br />

GROUP BY C.CATEGORY_ID ;<br />

Per<strong>for</strong>mance measurement result<br />

In Figure 7-20 the results of the measurement are presented in seconds.<br />

310 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Composition - Extender and Publishing<br />

30<br />

25<br />

20<br />

15<br />

10<br />

5<br />

0<br />

Figure 7-20 XML extender vs. SQL publishing functions<br />

The XML publishing functions outper<strong>for</strong>m the XML composition by a factor 20 and more<br />

mostly due to the fact that the XML publishing functions are built into the <strong>DB2</strong> engine. The<br />

measurement was done <strong>for</strong> documents up to 5.8 MB as the limit of 10240 rows was reached.<br />

The XML Extender cannot insert more than 10240 rows into any table when composing an<br />

XML document.<br />

In Figure 7-21 the results <strong>for</strong> document composition <strong>for</strong> CLOBs up to 6 MB are presented.<br />

sec.<br />

0.8<br />

0.7<br />

0.6<br />

0.5<br />

0.4<br />

0.3<br />

0.2<br />

0.1<br />

0<br />

1M doc 2M doc 3M doc 4M doc 5.8M<br />

doc<br />

COMP Elapsed SQL/XML Elapsed<br />

Composition by XML Publishing<br />

1M 2M 3M 4M 6M<br />

Figure 7-21 Composition by XML publishing functions<br />

Elapsed<br />

CPU<br />

The elapsed and CPU time used by the XML publishing functions to compose XML<br />

documents scales nearly linear.<br />

Chapter 7. Networking and e-business 311


7.5.3 Conclusion<br />

The new XML publishing functions outper<strong>for</strong>m significantly the corresponding UDFs from the<br />

XML extender.<br />

7.5.4 Recommendation<br />

For the purpose of composing XML documents from <strong>DB2</strong> data the use of the XML publishing<br />

function is preferred over the corresponding <strong>DB2</strong> XML extender UDFs. They are generally<br />

more efficient, flexible and versatile than the <strong>DB2</strong> XML Extender publishing functions.<br />

7.6 Enterprise Workload Manager<br />

7.6.1 Introduction<br />

Look at Enterprise Workload Manager (EWLM) as z/<strong>OS</strong> WLM applied to a heterogeneous<br />

environment. EWLM introduces the goal-oriented z/<strong>OS</strong> WLM philosophy to all plat<strong>for</strong>ms.<br />

See the book <strong>IBM</strong> Enterprise Workload Manager, SG24-6350, <strong>for</strong> a detailed description of<br />

EWLM.<br />

Enterprise Workload Manager enables you to automatically monitor and manage multi-tiered,<br />

distributed, heterogeneous or homogeneous workloads across an IT infrastructure to better<br />

achieve defined business goals <strong>for</strong> end-user services. These capabilities allow you to identify<br />

work requests based on service class definitions, track per<strong>for</strong>mance of those requests across<br />

server and subsystem boundaries, and manage the underlying physical and network<br />

resources to set specified per<strong>for</strong>mance goals <strong>for</strong> each service class. By bringing this<br />

self-tuning technology to the set of servers, routers, and other devices enabled with Java<br />

virtual machine support, Enterprise Workload Manager can help enable greater levels of<br />

per<strong>for</strong>mance management <strong>for</strong> distributed systems.<br />

In the first release, the Enterprise Workload Manager provides goal-based end to end<br />

per<strong>for</strong>mance monitoring of an application and influences network traffic routing decisions by<br />

network load balancers <strong>for</strong> improved application per<strong>for</strong>mance and server effectiveness. A<br />

systems administrator will be able to monitor multiple servers, answering such questions as:<br />

► How well is the work progressing?<br />

► Are the business commitments <strong>for</strong> end-user service being met?<br />

► If the per<strong>for</strong>mance goals are not being met, which components of which servers are<br />

causing the problem?<br />

► Which type of user is being affected by the problem?<br />

And per<strong>for</strong>ming such tasks as:<br />

► Easily identifying where time is being spent in a distributed application that spans different<br />

operating systems, applications, networks and routers.<br />

► Specifying a per<strong>for</strong>mance goal that applies to each class of user of a distributed<br />

application.<br />

► Identifying which servers are actively supporting a given application and what applications<br />

are running on a given server.<br />

312 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


7.6.2 Description<br />

EWLM is an implementation of policy-based per<strong>for</strong>mance management. EWLM Correlator<br />

Support is <strong>for</strong> server side only and it is only <strong>for</strong> TCP/IP. It is implemented with PTF UK03835<br />

<strong>for</strong> APAR PQ91509 <strong>for</strong> <strong>DB2</strong> V8, and it allows you to do per<strong>for</strong>mance measurement using<br />

ARM instrumentation. PTF UK03058 <strong>for</strong> APAR PQ99707 is also recommended <strong>for</strong><br />

per<strong>for</strong>mance improvement <strong>for</strong> JCC clients. PTF UA15189 <strong>for</strong> APARs OA07196 and PTF<br />

UA15456 <strong>for</strong> APAR OA07356 implement this function from the z/<strong>OS</strong> side. APAR OA12005<br />

(currently open) <strong>for</strong> z/<strong>OS</strong> 1.6 and z/<strong>OS</strong> 1.7 is also recommended <strong>for</strong> per<strong>for</strong>mance<br />

improvements.<br />

The scope of management is a set of servers that you logically group into what is called an<br />

EWLM management domain. The set of servers included in the management domain have<br />

some type of relationship; <strong>for</strong> example, z/<strong>OS</strong> server with <strong>DB2</strong> V8, AIX server with WAS. See<br />

Figure 7-22.<br />

EWLM Support in WebSphere/<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

GUI<br />

User signon<br />

via WEB<br />

Browser<br />

Management<br />

Server Host<br />

EWLM Domain Manager<br />

Domain Policy<br />

and Topology<br />

EWLM Control Center<br />

style sheets<br />

Websphere Express<br />

as servlet engine<br />

Windows XP<br />

IRWW w orkload<br />

client driver<br />

AIX<br />

EWLM Agent <strong>for</strong> AIX<br />

EWLM Plat<strong>for</strong>m interfaces<br />

Server Operating System<br />

Application Instrumentation<br />

Interfaces<br />

WAS<br />

JCC Driver<br />

Figure 7-22 EWLM support with WAS/AIX and <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8<br />

EWLM Domain<br />

There is a management focal point <strong>for</strong> each EWLM management domain, called the EWLM<br />

domain manager. The domain manager coordinates policy actions across the servers, tracks<br />

the state of those servers, and accumulates per<strong>for</strong>mance statistics on behalf of the domain.<br />

On each server (operating system) instance in the management domain there is a thin layer<br />

of EWLM logic installed called the EWLM managed server. The managed server layer<br />

understands each of the supported operating systems, gathering resource usage and delay<br />

statistics known to the operating system.<br />

z/<strong>OS</strong><br />

EWLM Managed Server <strong>for</strong> z/<strong>OS</strong><br />

FMID HVE1110<br />

Control Blocks<br />

JNI Layer<br />

EWLM Plat<strong>for</strong>m interfaces<br />

Application Instrumentation Interfaces<br />

ARM (Enclaves)<br />

<strong>DB2</strong><br />

Server Operating System<br />

ARM (C, Java)<br />

Chapter 7. Networking and e-business 313


A second role of the managed server layer is to gather relevant transaction-related statistics<br />

from middleware applications and route these statistics to the EWLM domain manager. The<br />

application middleware implementations, such as WebSphere Application Server, understand<br />

when a piece of work starts and stops, and the middleware understands when a piece of work<br />

has been routed to another server <strong>for</strong> processing, <strong>for</strong> example, when a WAS server routes a<br />

request to a <strong>DB2</strong> database server.<br />

An important aspect of the EWLM approach is that all data collection and aggregation<br />

activities are driven by a common service level policy, called the EWLM Domain Policy.<br />

The final link is the EWLM Control Center. This is where all the EWLM concepts come<br />

together; where you can create an EWLM domain policy and activate that policy on all<br />

servers of the domain with a single click. See the following screen shots in order to get a look<br />

and feel of the EWLM Control Center.<br />

Figure 7-23 shows the Managed Server view of your EWLM Control Center. It provides an<br />

overview of the status of all the managed servers in the EWLM management domain. In this<br />

example, there is a Communication error between domain manager and managed servers on<br />

AIX and z/<strong>OS</strong> that requires attention. The managed server on Windows appears to be<br />

running fine as indicated by the “Active” state.<br />

Figure 7-23 Enterprise Workload Manager Control Center - Managed servers<br />

Figure 7-24 is an example of a server topology report. Note the location name (STLABD7) is<br />

displayed in the diagram when <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> is EWLM enabled.<br />

314 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 7-24 Enterprise Workload Manager Control Center - Server topology<br />

When you click on the table view button from Server Topology, you will see a table<br />

representation of the topology like the above along with transaction statistics. See<br />

Figure 7-25.<br />

Figure 7-25 EWLM control center - Service class statistics<br />

Chapter 7. Networking and e-business 315


7.6.3 Per<strong>for</strong>mance<br />

The following in<strong>for</strong>mation can be seen in the table view by scrolling to the right:<br />

► Average response time<br />

► Active time (milliseconds)<br />

► Processor time (microseconds)<br />

► Processor delay%<br />

► Processor using%<br />

► Stopped transaction<br />

► Failed transactions<br />

► Successful transactions<br />

► I/O delay%<br />

► Page delay%<br />

► Idle%<br />

► Other%<br />

► Topology uncertainty count<br />

► Reporting gap count<br />

► Hard page faults<br />

► Queue time (milliseconds)<br />

► Standard deviation<br />

Companies implementing EWLM will be able to reduce the amount of time their<br />

administrators spend to locate per<strong>for</strong>mance bottlenecks and optimize workloads. Their<br />

current hardware utilization will increase as EWLM instrumentation will provide data collection<br />

and aggregation <strong>for</strong> optimally changing resource settings across the existing plat<strong>for</strong>ms.<br />

Preliminary tests to evaluate the impact on throughput of an EWLM implementation on a<br />

server combination WebSphere/AIX with <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 are shown in Figure 7-26.<br />

450<br />

400<br />

350<br />

300<br />

250<br />

200<br />

150<br />

100<br />

50<br />

431.66<br />

Figure 7-26 EWLM implementation cost<br />

The diagram reflects the latest EWLM <strong>for</strong> <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 per<strong>for</strong>mance numbers. With the<br />

implementation of an improved EWLM interface, EWLM correlator processing cost in<br />

normalized transactions per seconds is 8.33% measured with IRWW servlet workload. Since<br />

part of the overhead is due to CPU utilization by the EWLM Client, this utilization could be<br />

316 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

EWLM Correlator Processing in <strong>DB2</strong><br />

Not Flowing<br />

EWLM<br />

Correlator<br />

395.74<br />

Flowing EWLM<br />

Correlator<br />

Normalized z/<strong>OS</strong><br />

Transaction / Second


offloaded to a zSeries Application Assist Processor (zAAP), if available. The zAAP processor<br />

delivers a dedicated zSeries processor <strong>for</strong> Java workloads, free from ISV and <strong>OS</strong> costs.<br />

Chapter 7. Networking and e-business 317


318 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 8. Data sharing enhancements<br />

8<br />

<strong>DB2</strong> data sharing allows you the highest level of scalability, per<strong>for</strong>mance, and continuous<br />

availability by taking advantage of the z Parallel Sysplex technology to provide applications<br />

with full concurrent read and write access to shared <strong>DB2</strong> data. For an introduction, refer to<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>: Data Sharing in a Nutshell, SG24-7322.<br />

<strong>DB2</strong> data sharing was introduced in 1994 with <strong>DB2</strong> V4, and continues to evolve exploiting key<br />

functions of the <strong>IBM</strong> System z servers.<br />

Data sharing <strong>DB2</strong> V8 provides a number of significant enhancements to improve availability,<br />

per<strong>for</strong>mance and usability of <strong>DB2</strong> data sharing:<br />

► CF request batching: This enhancement utilizes new functionality in z/<strong>OS</strong> 1.4 and CF<br />

level 12 to enable <strong>DB2</strong> to:<br />

– Register and write multiple pages to a group buffer pool in a single request<br />

– Read multiple pages from a group buffer pool <strong>for</strong> castout processing<br />

This reduces the amount of traffic to and from the coupling facility <strong>for</strong> writes to group buffer<br />

pools and reads <strong>for</strong> castout processing, thus reducing the data sharing overhead insert,<br />

update and delete-intensive workloads.<br />

► Locking protocol level 2: Protocol Level 2 remaps IX parent L-locks from XES-X to<br />

XES-S locks. Data sharing locking per<strong>for</strong>mance benefits because this allows IX and IS<br />

parent global L-locks to be granted without invoking global lock contention processing to<br />

determine that the new IX or IS lock is compatible with existing IX or IS locks.<br />

► Change to IMMEDWRITE default BIND option: In prior releases of <strong>DB2</strong>, any remaining<br />

changed pages in a data sharing environment are written to the group buffer pool during<br />

phase 2 of commit, unless otherwise specified by the IMMEDWRITE BIND parameter.<br />

This enhancement changes the default processing to write changed pages during commit<br />

phase 1. <strong>DB2</strong> will no longer write changed pages during phase 2 of commit processing.<br />

► <strong>DB2</strong> I/O CI limit removed: Prior to <strong>DB2</strong> V8, <strong>DB2</strong> did not schedule a single I/O <strong>for</strong> a data<br />

set with CIs that span a range of more than 180 CIs. V8 removes this limit <strong>for</strong> list prefetch<br />

and castout I/O requests. This is true in CM and NFM.<br />

► Miscellaneous items:<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 319


Impact on coupling facility: You do not need to resize the group buffer pools, lock<br />

structure or SCA in the coupling facility as a result of moving to <strong>DB2</strong> V8, even though the<br />

virtual buffer pools have now moved above the bar and have a longer memory address.<br />

Improved LPL recovery: Currently LPL recovery requires exclusive access to the table<br />

space. <strong>DB2</strong> V8 introduces a new serialization mechanism whereby LPL recovery is much<br />

less disruptive. In addition, <strong>DB2</strong> V8 automatically attempts to recover LPL pages as they<br />

go into LPL, when it determines the recovery will probably succeed. Instrumentation has<br />

also improved whereby <strong>DB2</strong> now attempts to indicate the reason pages are added to the<br />

LPL.<br />

Restart LIGHT enhancements: If indoubt units of recovery (UR) exist at the end of restart<br />

recovery, <strong>DB2</strong> will now remain running so that the indoubt URs can be resolved. After all<br />

the indoubt URs have been resolved, the <strong>DB2</strong> member that is running in LIGHT(YES)<br />

mode will shut down and can be restarted normally.<br />

Change to close processing <strong>for</strong> pseudo close: Table spaces defined as CL<strong>OS</strong>E NO are still<br />

closed during pseudo close processing at the end of the PCL<strong>OS</strong>ET interval. This caused<br />

degraded per<strong>for</strong>mance because the data sets must be physically opened again on the<br />

next access. <strong>DB2</strong> V8 now really honors the CL<strong>OS</strong>E NO attribute during pseudo close<br />

processing. See PTF UQ74866 <strong>for</strong> APAR PQ69741 <strong>for</strong> <strong>DB2</strong> V7.<br />

Buffer pool long term page fix: <strong>DB2</strong> V8 allows you to fix the buffer pool pages once in<br />

memory and keep them fixed in real storage. This avoids the processing time that <strong>DB2</strong><br />

needs to fix and free pages each time there is an I/O.<br />

Batched index page splits: Prior to V8, index page splits <strong>for</strong> indexes with inter-<strong>DB2</strong><br />

read/write interest required multiple synchronous log writes and multiple separate writes to<br />

the group buffer pool. This was required to ensure the integrity of the index <strong>for</strong> other <strong>DB2</strong><br />

members during the actual page split. <strong>DB2</strong> V8 is able to accumulate the index page split<br />

updates and process them as a single entity, thereby reducing log writes and coupling<br />

facility traffic.<br />

320 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


8.1 CF request batching<br />

8.1.1 Per<strong>for</strong>mance<br />

z/<strong>OS</strong> 1.4 and CF Level 12 bring two new coupling facility “commands”, Write And Register<br />

Multiple (WARM) and Read For Castout Multiple (RFCOM).<br />

<strong>DB2</strong> V8 data sharing will use these new coupling facility commands, if available, to reduce the<br />

amount of traffic to and from the coupling facility <strong>for</strong> writes to group buffer pools and reads <strong>for</strong><br />

castout processing, thus reducing the data sharing overhead <strong>for</strong> insert, update and<br />

delete-intensive workloads.<br />

When the group buffer pool is allocated in a coupling facility with CFLEVEL= 12 or higher,<br />

<strong>DB2</strong> can register a list of pages that are being prefetched with one request to the coupling<br />

facility. This can be used <strong>for</strong> sequential prefetch (including sequential detection) and list<br />

prefetch.<br />

For those pages that are cached as “changed” in the group buffer pool, or those that are<br />

locked <strong>for</strong> castout, <strong>DB2</strong> still retrieves the changed page from the group buffer pool one at a<br />

time. For pages that are cached as “clean” in the group buffer pool, <strong>DB2</strong> can get the pages<br />

from the group buffer pool (one page at a time), or can include the pages in the DASD read<br />

I/O request, depending on which is most efficient.<br />

z/<strong>OS</strong> 1.4 and CF level 12 introduce two new CF “commands” to:<br />

► Write And Register Multiple (WARM) pages to a group buffer pool with a single command.<br />

► Read multiple pages from a group buffer pool <strong>for</strong> castout processing with a single CF read<br />

request. The actual command is called Read For Castout Multiple (RFCOM).<br />

CF level 13 also introduces per<strong>for</strong>mance improvements related to <strong>DB2</strong> castout processing.<br />

See the Web page:<br />

http://www.ibm.com/servers/eserver/zseries/pso/coupling.html<br />

<strong>DB2</strong> V8 uses the CF request batching commands to read and write pages to and from the<br />

group buffer pool if more than one page needs to be read or written.<br />

<strong>DB2</strong> instrumentation (statistics IFCID 2 and accounting 3 and 148) records are enhanced to<br />

reflect the usage of these new commands. The <strong>DB2</strong> PE accounting and statistics reports are<br />

enhanced to externalize the new counters that indicate the number of WARM and RFCOM<br />

requests in the GBP section:<br />

► WRITE AND REGISTER MULTI<br />

The number of Write and Register Multiple (WARM) requests.<br />

► PAGES WRITE & REG MULTI<br />

The number of pages written using Write and Register Multiple (WARM) requests.<br />

► READ FOR CASTOUT MULTI<br />

The number of Read For Castout Multiple (RFCOM) requests.<br />

A number of per<strong>for</strong>mance studies have been done to understand the impact of using CF<br />

request batching. For these studies, a two member data sharing group was used, running the<br />

IRWW workload. z/<strong>OS</strong> 1.3 was compared to z/<strong>OS</strong> 1.4, to isolate the impact of CF request<br />

batching. CF request batching is not available in z/<strong>OS</strong> 1.3.<br />

Chapter 8. Data sharing enhancements 321


Table 8-1 shows extracts from <strong>DB2</strong> PE statistics reports <strong>for</strong> an Online Transaction Processing<br />

workload (OLTP). The two columns of numbers within each z/<strong>OS</strong> represent values per<br />

transaction <strong>for</strong> data sharing member 1 and member 2.<br />

Table 8-1 CF Request Batching - <strong>DB2</strong> PE extract (OLTP)<br />

It can be clearly seen from Table 8-1 that CF request batching was not used in z/<strong>OS</strong> 1.3. The<br />

counters <strong>for</strong> “Write & Register Multi”, “Pages Write & Reg Multi” and “Read <strong>for</strong> Castout Multi”<br />

are all zero in z/<strong>OS</strong> 1.3.<br />

CF request batching was used under z/<strong>OS</strong> 1.4:<br />

► An average 0f 6.9 pages were written per WARM command<br />

“Pages Write & Reg Multi” / “Write & Register Multi”=4.09 / 0.59<br />

= 6.9<br />

► An average of 7.7 pages were read per RFCOM command.<br />

(“Pages Castout” - “Read <strong>for</strong> Castout”) / Read <strong>for</strong> Castout Multi”<br />

= (4.61 - 0.01) / 0.60<br />

= 7.7<br />

Table 8-2 shows extracts from RMF reports <strong>for</strong> the same OLTP workload.<br />

Table 8-2 CF Request Batching - RMF extract (OLTP)<br />

As we can see from Table 8-2, the test using z/<strong>OS</strong> 1.4 results in significantly fewer requests to<br />

the coupling facility (9,880 compared to 14,082 <strong>for</strong> this workload). This is the direct result of<br />

CF request batching. We can also see the service times <strong>for</strong> both synchronous requests and<br />

asynchronous requests to the coupling facility have increased slightly. On average, the<br />

coupling facility is doing more work per each request, as a number of page movements may<br />

need to be processed with each request. We also notice the coupling facility utilization has<br />

322 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.4<br />

Member 1 Member 2 Member 1 Member 2<br />

Pages Castout 3.91 4.35 3.71 4.61<br />

Write & Register 6.28 6.29 2.22 2.22<br />

Write & Register Multi 0.00 0.00 0.59 0.59<br />

Pages Write & Reg Multi 0.00 0.00 4.09 4.09<br />

Read <strong>for</strong> Castout 3.91 4.35 0.00 0.01<br />

Read <strong>for</strong> Castout Multi 0.00 0.00 0.48 0.60<br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.4<br />

Requests / sec 14,082 9,880<br />

Sync requests<br />

Serv time<br />

(usec)<br />

Async requests<br />

Serv time<br />

(usec)<br />

% of all req 17.7 95.5 19.5 86.6<br />

% of all req 173.9 4.4 192.8 13.3<br />

CF utilization (%) 21.7 21.0


decreased slightly. The CF Link utilization also decreased slightly, as fewer messages are<br />

passed to the coupling facility.<br />

The table also shows a jump in asynchronous requests when CF request batching was used.<br />

The actual number of asynchronous requests doubled from 620 to 1314 requests. This<br />

increase can be attributed to the heuristic conversion by the CFCC of synchronous requests<br />

to asynchronous requests due to more work being processed in each batch request.<br />

The next series of studies investigate the impact of CF request batching <strong>for</strong> a batch workload.<br />

For these tests, one batch program per<strong>for</strong>ms a fetch-update of a single row <strong>for</strong> the first 2.5<br />

million rows of a 5 million row table. A second batch program, running on the other <strong>DB2</strong><br />

member, per<strong>for</strong>ms a fetch-update of the other half of the 5 million row table. During the<br />

execution of these two batch programs, the table space is GBP dependent but with minimal<br />

global contention.<br />

Table 8-3 shows extracts from <strong>DB2</strong> PE statistics reports, revealing the impact of CF request<br />

batching on a batch workload.<br />

Table 8-3 CF Request Batching - <strong>DB2</strong> PE extract (batch)<br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.4<br />

Pages Castout 2,121.8K 2,253.4K 2,583.4K 2,749.8K<br />

Write & Register 2,206,1K 2,206.1K 205 163<br />

Write & Register Multi 0 0 209.5K 210.2K<br />

Pages Write & Reg Multi 0 0 2,202.7K 2,203.0K<br />

Read <strong>for</strong> Castout 2,121.8K 2,253.4K 363.5K 364.1K<br />

Read <strong>for</strong> Castout Multi 0 0. 750.2K 790.7K<br />

The impact of CF request batching appears to be much more pronounced. In this test, every<br />

page must be updated.<br />

Without CF request batching, <strong>DB2</strong> must write and register every page individually to the<br />

coupling facility. This results in over 2.2 million individual requests <strong>for</strong> each <strong>DB2</strong> member.<br />

With CF request batching, each <strong>DB2</strong> member only needs a little over 200,000 requests to the<br />

coupling facility to support the same workload.<br />

In addition, castout processing is dramatically improved. Rather than requiring over 4.3 million<br />

individual reads <strong>for</strong> castout processing without CF request batching, <strong>DB2</strong> is able to reduce<br />

the number of requests to the coupling facility <strong>for</strong> castout processing, to a little over 2 million<br />

requests.<br />

Rather than seeing only one <strong>DB2</strong> member per<strong>for</strong>ming all the castout processing <strong>for</strong> the single<br />

page set we used during the tests, we can see both <strong>DB2</strong> members per<strong>for</strong>ming castout<br />

processing <strong>for</strong> the same page set, both with and without CF request batching. This is normal.<br />

In the normal case, when <strong>DB2</strong> decides that castout needs to be done <strong>for</strong> an object, the<br />

castout request is sent to the castout owner. However in times of high activity, the <strong>DB2</strong><br />

member that detected castout must be done can decide to per<strong>for</strong>m the castout locally.<br />

It is also normal to see a mixture of CF request batching and non-batching castout reads.<br />

Recall that <strong>DB2</strong> uses CF request batching when only multiple pages are to be castout.<br />

CF request batching is also used when <strong>DB2</strong> writes pages to the secondary GBP when BP<br />

Duplexing is used. However, <strong>DB2</strong> will only use CF request batching when both the primary<br />

Chapter 8. Data sharing enhancements 323


and secondary GBP structures have the CF request batching capability. Since CF request<br />

batching will only be used <strong>for</strong> reading castout pages from the primary GBP, there is no<br />

additional CPU saving <strong>for</strong> castout with or without GBP Duplexing. However, if you do not<br />

consider prefetch, then the additional CPU saving with CF request batching in a duplexed<br />

GBP environment will be half of the CPU saving without GBP duplexing.<br />

Table 8-4 shows extracts from RMF reports <strong>for</strong> the same batch workload.<br />

Table 8-4 CF Request Batching - RMF extract (batch)<br />

Once again, we can see z/<strong>OS</strong> 1.4 results in significantly fewer requests to the coupling facility<br />

(6,715 compared to 14,627). We can also see the service times <strong>for</strong> both synchronous<br />

requests and asynchronous requests to the coupling facility have increased slightly, as well as<br />

notice the coupling facility utilization has decreased slightly.<br />

The table also shows quite a jump in asynchronous requests when CF request batching was<br />

used, over 12% of all requests, compared with only 2% when CF request batching was not<br />

used. This trend is similar to what we noticed when we earlier reviewed the RMF extracts <strong>for</strong><br />

the OLTP workload. The increase can be attributed to the heuristic conversion by the CFCC<br />

of synchronous requests to asynchronous requests due to more work being processed in<br />

each batch request.<br />

Table 8-5 compares the CPU used by the DBM1 address space <strong>for</strong> the OLTP workload<br />

compared with the batch workload.<br />

Table 8-5 CF Request Batching - <strong>DB2</strong> CPU<br />

This table shows CF request batching has potential <strong>for</strong> significant saving in CPU charged to<br />

DBM1 address space, in both OLTP and batch workloads, but particularly batch.<br />

The overall CPU times in this table include the transaction class 2 CPU times, the MSTR,<br />

DBM1 and IRLM CPU times. So, we can see the overall impact of CF request batching was<br />

324 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.4<br />

Requests / sec 14,627 6,715<br />

Sync Requests<br />

Serv time<br />

(usec)<br />

Async Requests<br />

Serv time<br />

(usec)<br />

% of all req 10.5 98.0 12.0 87.7<br />

% of all req 209.8 2.0 241.4 12.3<br />

CF Utilization (%) 15.7 14.4<br />

DBM1 - (OLTP)<br />

(msec / commit)<br />

z/<strong>OS</strong> 1.3 z/<strong>OS</strong> 1.4 Delta<br />

(1.4 / 1.3)<br />

0.536 0.545 0.427 0.473 -17%<br />

Overall CPU time 3.229 3.224 3.111 3.368 +0%<br />

DBM1 - (Batch)<br />

(msec / commit)<br />

119.88 130.11 81.5 89.68 -32%<br />

Overall CPU time 656.40 709.74 618.98 680.89 -5%


8.1.2 Conclusion<br />

not all that significant <strong>for</strong> our OLTP workload, while the overall impact on our batch workload<br />

was indeed significant.<br />

CF request batching also benefits <strong>DB2</strong> per<strong>for</strong>mance in other ways. <strong>DB2</strong> commit processing<br />

per<strong>for</strong>mance is improved, where any remaining changed pages must be synchronously<br />

written to the group buffer pool during commit processing. For GPBCACHE(ALL) page sets,<br />

<strong>DB2</strong> is able to more efficiently write prefetched pages into the group buffer pool as it reads<br />

them from DASD.<br />

CF request batching allows <strong>DB2</strong> V8 to reduce the amount of traffic to and from the coupling<br />

facility <strong>for</strong> both writes to and reads from the group buffer pool <strong>for</strong> castout processing, thus<br />

reducing the data sharing overhead <strong>for</strong> most workloads.<br />

The most benefit is anticipated <strong>for</strong> workloads which update large numbers of pages belonging<br />

to GBP-dependent objects, <strong>for</strong> example, batch workloads.<br />

This enhancement also has potential to reduce the CPU used by the DBM1 address space,<br />

as fewer messages are passed to and from the coupling facility. Coupling facility link<br />

utilization may also decrease slightly. As a consequence, coupling facility utilization may be<br />

slightly higher as message service times increase. This is a direct result of the coupling<br />

facility having to per<strong>for</strong>m more work to service each batched request. The data sharing<br />

overhead caused by castout processing is also reduced.<br />

8.1.3 Recommendations<br />

There is nothing you need to do in <strong>DB2</strong> to enable <strong>DB2</strong> to use CF request batching. However,<br />

you need to have the prerequisite software in place, z/<strong>OS</strong> 1.4 and CFCC Level 12.<br />

We recommend you implement a strategy to keep reasonably current with software<br />

maintenance and coupling facility microcode levels, in order to take early advantage of<br />

enhancements such as CF request batching. This is particularly important in a data sharing<br />

environment.<br />

8.2 Locking protocol level 2<br />

Protocol Level 2 remaps parent IX L-locks from XES-X to XES-S locks. Data sharing locking<br />

per<strong>for</strong>mance benefits because this allows IX and IS parent global L-locks to be granted<br />

without invoking global lock contention processing to determine that the new IX or IS lock is<br />

compatible with existing IX or IS locks.<br />

The purpose of this enhancement is to avoid the cost of global contention processing<br />

whenever possible. It will also improve availability due to a reduction in retained locks<br />

following a <strong>DB2</strong> subsystem or MVS system failure.<br />

Refer to section 11.1 of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever Wanted to Know,<br />

... and More, SG24-6079, <strong>for</strong> a general review of locking in a data sharing environment.<br />

XES contention caused by parent L-Locks is reasonably common in a data sharing<br />

environment. On page set open (an initial open or open after a pseudo close) <strong>DB2</strong> normally<br />

tries to open the table space in RW. (<strong>DB2</strong> rarely opens a table space in RO.) To do this, <strong>DB2</strong><br />

must ask <strong>for</strong> an L-Lock. This L-lock is normally an IS or IX L-lock, depending on whether or<br />

not a SELECT or UPDATEable SQL statement caused the table space to open. If any other<br />

Chapter 8. Data sharing enhancements 325


<strong>DB2</strong> member already has the table space open <strong>for</strong> RW, global lock contention generally<br />

occurs.<br />

<strong>DB2</strong> V8 attempts to reduce this global contention by remapping parent IX L-locks from XES-X<br />

to XES-S locks. Data sharing locking per<strong>for</strong>mance benefits because parent IX and IS L-locks<br />

are now both mapped to XES-S locks and are there<strong>for</strong>e compatible and can now be granted<br />

locally by XES. <strong>DB2</strong> no longer needs to wait <strong>for</strong> global lock contention processing to<br />

determine that a new parent IX or IS L-lock is compatible with existing parent IX or IS L-locks.<br />

The majority of parent L-lock contention occurs when the table space is opened by at least<br />

one <strong>DB2</strong> member in RW:<br />

► IS-IS: We want to execute some read-only SQL against a table space and there are some<br />

other members who currently have some read-only SQL active against the same table<br />

space.<br />

► IS-IX: We want to execute some read-only SQL against a table space and there are some<br />

other members who currently have some update SQL active against the same table<br />

space.<br />

► IX-IS: We want to execute some update SQL against a table space and there are some<br />

other members who currently have some read-only SQL active against the same table<br />

space.<br />

► IX- IX: We want to execute some update SQL against a table space and there are some<br />

other members who currently have some update SQL active against the same table<br />

space.<br />

Parent lock contention with parent S L-locks is less frequent than checking <strong>for</strong> contention with<br />

parent IS and IX L-locks. Parent S L-locks are only acquired when <strong>DB2</strong> is about to issue<br />

read-only SQL against a table space opened <strong>for</strong> RO.<br />

To ensure that parent IX L-locks remain incompatible with parent S L-locks, S table and table<br />

space L-locks are remapped to XES-X locks. This means that additional global contention<br />

processing will now be done to verify that an S L-lock is compatible with another S L-lock, but<br />

this is a relatively rare case (executing read-only SQL against a table space, where at least<br />

one other <strong>DB2</strong> member has the table space open in RO and currently has some read-only<br />

SQL active against the same table space).<br />

Another impact of this change is that child L-locks are no longer propagated based on the<br />

parent L-lock. Instead, child L-locks are propagated based on the held state of the table<br />

space P-lock. If the table space P-lock is negotiated from X to SIX or IX, then child L-locks<br />

must be propagated.<br />

It may be that some child L-locks are acquired be<strong>for</strong>e the page set P-lock is obtained. In this<br />

case child L-locks will automatically be propagated. This situation occurs because <strong>DB2</strong><br />

always acquires locks be<strong>for</strong>e accessing the data. In this case, <strong>DB2</strong> acquires that L-lock be<strong>for</strong>e<br />

opening the table space to read the data. It can also happen during <strong>DB2</strong> restart.<br />

An implication of this change is that child L-locks will be propagated <strong>for</strong> longer than they are<br />

needed, however this should not be a concern. There will be a short period from the time<br />

where there is no intersystem read/write interest until the table space becomes<br />

non-GBP-dependent, that is, be<strong>for</strong>e the page set P-lock reverts to X. During this time, child<br />

L-locks will be propagated unnecessarily.<br />

It is now important that L-locks and P-locks are maintained at the same level of granularity.<br />

Remember now that page set P-locks now determine when child L-locks must be propagated<br />

to XES.<br />

326 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


For partitioned table spaces defined with LOCKPART NO, prior versions of <strong>DB2</strong> lock only the<br />

last partition to indicate we have a lock on the whole table space. There are no L-locks held<br />

on each of the partition page sets. So, when should we propagate the child L-locks <strong>for</strong> the<br />

various partitions that are being used? We cannot tell by looking at the table space parent<br />

L-locks that we need to propagate the child locks since there no longer is a lock contention<br />

conflict that can trigger child lock propagation, and we cannot determine how each partition<br />

page set is being used by looking at the page set P-locks that are held at the partition level,<br />

while the parent L-lock is at the table space level with LOCKPART NO.<br />

To overcome this problem, <strong>DB2</strong> V8 obtains locks at the part level. LOCKPART NO behaves<br />

the same as LOCKPART YES.<br />

In addition, LOCKPART YES is not compatible with LOCKSIZE TABLESPACE. However, if<br />

LOCKPART NO and LOCKSIZE TABLESPACE are specified then we will lock every partition,<br />

just as every partition is locked today when LOCKPART YES is used with<br />

ACQUIRE(ALLOCATE). With this change you may see additional locks being acquired on<br />

individual partitions even though LOCKPART(NO) is specified.<br />

This change to the LOCKPART parameter behavior applies to both data sharing and non-data<br />

sharing environments.<br />

Since the new locking protocol cannot co-exist with the old, the new protocol will only take<br />

effect after the first group-wide shutdown and restart after the data sharing group is in<br />

new-function mode (NFM). You do not have to delete the lock structure from the coupling<br />

facility prior to restarting <strong>DB2</strong>, to trigger <strong>DB2</strong> on group restart to build a new lock structure. In<br />

addition, Protocol Level 2 will not be enabled if you merely ask <strong>DB2</strong> to rebuild the lock<br />

structure while any <strong>DB2</strong> member remains active.<br />

The new mapping takes effect after the restart of the first member, after successful quiesce of<br />

all members in the <strong>DB2</strong> data sharing group. So, to enable this feature, a group-wide outage is<br />

required.<br />

No other changes are required to take advantage of this enhancement.<br />

You can use the -DISPLAY GROUP command to check whether the new locking protocol is<br />

used (mapping IX IRLM L-locks to an S XES lock). Example 8-1 shows the output from a<br />

-DISPLAY GROUP command which shows Protocol Level 2 is active.<br />

Example 8-1 Sample -DISPLAY GROUP output<br />

DSN7100I -DT21 DSN7GCMD<br />

*** BEGIN DISPLAY OF GROUP(DSNT2 ) GROUP LEVEL(810) MODE(N)<br />

PROTOCOL LEVEL(2) GROUP ATTACH NAME(DT2G)<br />

--------------------------------------------------------------------<br />

<strong>DB2</strong> <strong>DB2</strong> SYSTEM IRLM<br />

MEMBER ID SUBSYS CMDPREF STATUS LVL NAME SUBSYS IRLMPROC<br />

-------- --- ---- -------- -------- --- -------- ---- --------<br />

DT21 1 DT21 -DT21 ACTIVE 810 STLABB9 IT21 DT21IRLM<br />

DT22 3 DT22 -DT22 FAILED 810 STLABB6 IT22 DT22IRLM<br />

The use of locking Protocol Level 2 requires that the PTFs <strong>for</strong> the following APARs are<br />

applied: PQ87756, PQ87168, and PQ86904 (IRLM).<br />

Chapter 8. Data sharing enhancements 327


8.2.1 Per<strong>for</strong>mance<br />

We ran a number of benchmarks to try to understand the impact of the new locking protocol.<br />

Each test was per<strong>for</strong>med using an IRWW benchmark executing against a two member data<br />

sharing group.<br />

The tests were per<strong>for</strong>med with <strong>DB2</strong> V7 defaults and <strong>DB2</strong> V8 defaults. V7 uses LOCKPART<br />

NO as the default, while V8 behaves as if the table spaces are defined with LOCKPART YES.<br />

So, <strong>for</strong> some workloads <strong>DB2</strong> V8 would need to propagate more locks to the coupling facility<br />

than the same workload running in <strong>DB2</strong> V7. This is true if the workload running does not<br />

require all of the partitions to be GBP dependent. For these tests, all partitions were GBP<br />

dependent. So, the impact of LOCKPART(NO) in V7 compared with V8 should be minimal.<br />

We first review the impact on lock suspensions. Table 8-6 shows extracts from the Data<br />

Sharing Locking section of <strong>DB2</strong> PE statistics reports. The two columns under <strong>DB2</strong> V7 and V8<br />

represent each <strong>DB2</strong> member.<br />

Table 8-6 Protocol Level 2 - Statistics Report extract<br />

Suspends per commit <strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

IRLM Global Contention 0.01 0.01 0.01 0.01<br />

XES Contention 0.54 0.52 0.00 0.00<br />

False Contention 0.13 0.11 0.00 0.00<br />

You can see from Table 8-6 that the benchmark produced significantly less XES contention as<br />

well as less false contention. This is because IX-L locks are now mapped to S XES locks<br />

which are compatible locks. The lock requests do not need to be suspended while XES<br />

communicates with the IRLMs to determine the IX-L locks are in fact compatible and can be<br />

granted. False contention is reduced because fewer lock table entries are occupied by X-XES<br />

locks. This is explained in more detail later in this section.<br />

Table 8-7 shows extracts from <strong>DB2</strong> PE accounting reports <strong>for</strong> the same test.<br />

Table 8-7 Protocol Level 2 - Accounting Report extract<br />

Class 3 suspend time<br />

(msec / commit)<br />

Lock / Latch<br />

(<strong>DB2</strong> + IRLM)<br />

This table reveals that, on average, each transaction enjoyed significantly fewer suspensions<br />

<strong>for</strong> lock and global contention. This is due to less XES contention, as a result of the new<br />

locking protocol.<br />

Now, we have a look at the impact on the coupling facility and XCF links. Table 8-8 shows<br />

extracts from RMF XCF reports.<br />

Table 8-8 Protocol Level 2 - RMF XCF Report extract<br />

328 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

6.219 5.708 0.080 0.109<br />

Global Contention 8.442 7.878 0.180 0.197<br />

Req In<br />

(req / sec)<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

2,300 2,200 17 18


Req Out<br />

(req / sec)<br />

CHPID Busy<br />

(%)<br />

We can see from Table 8-8 that Protocol Level 2 generates a lot less XCF messaging traffic to<br />

and from the coupling facility.<br />

Table 8-9 shows extracts from RMF CF activity reports <strong>for</strong> the test workload.<br />

Table 8-9 Protocol Level 2 - RMF CF Activity Report extract<br />

Lock Structure<br />

Activity<br />

Total Requests<br />

(/ sec)<br />

Deferred Requests<br />

(/ sec)<br />

Contention<br />

(/ sec)<br />

False Contention<br />

(/ sec)<br />

CF Utilization<br />

(%)<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

2,300 2,200 17 18<br />

97.43 86.53 22.27 12.74<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

8,418.33 13,541.67<br />

790.00 6.92<br />

790.00 6.89<br />

115.00 2.58<br />

5.4 6.9<br />

This table is rather interesting. It shows many more requests to the lock structure as a result<br />

of using Protocol Level 2. This increase is in synchronous requests, as the number of<br />

deferred or asynchronous requests have decreased.<br />

Under <strong>DB2</strong> V7, the IX L-locks are mapped to X-XES locks and there<strong>for</strong>e would occupy a lock<br />

table entry in the lock structure. Once an XES essentially “owns” a lock table entry, by owning<br />

the X-XES lock, that XES becomes the global lock manager <strong>for</strong> the lock table entry and has<br />

the responsibility to resolve any contention that exists, (false, XES or real contention), <strong>for</strong> that<br />

entry.<br />

Once potential contention has been identified by two lock requests hashing to the same lock<br />

table entry, the global lock manager XES must resolve the contention. The other XESs in the<br />

group are instructed to send the lock in<strong>for</strong>mation they have that pertains to the lock table<br />

entry to the global lock manager XES so it can determine whether the contention is real or<br />

false. Resolution is possible as each XES holds in<strong>for</strong>mation about locks that its IRLM has<br />

passed to it. Some optimization is in place so that once an XES “owns” a lock table entry,<br />

other XESs in the group do not have to interact with the lock structure in the coupling facility.<br />

Under <strong>DB2</strong> V8 the IX L-locks are mapped to S-XES locks and do not occupy a lock table<br />

entry. The end result is there will be fewer lock table entries “owned” by X-XES locks. The<br />

good side is that this reduces XES contention (IX-L locks are now mapped to S-XES locks<br />

which are compatible) and reduce false contention (S-XES locks do not “own” lock table<br />

entries, so fewer lock table entries are occupied). The down side is that more lock requests<br />

must be propagated to the coupling facility to determine if any contention may exist. The<br />

majority of these requests are synchronous requests as contention does not exist (the<br />

hashed lock table entry is not in use) and the request does not need to be suspended to<br />

Chapter 8. Data sharing enhancements 329


esolve any contention. This extra activity to the lock structure also increases the coupling<br />

facility CPU utilization.<br />

However these tests show that the increase in synchronous requests to the lock structure and<br />

the resulting increase in coupling facility CPU utilization do not appear to be excessive <strong>for</strong> our<br />

workload. Nothing comes <strong>for</strong> free!<br />

Now we have a look at the impact on the CPU consumed by <strong>DB2</strong>. Table 8-10 shows extracts<br />

from <strong>DB2</strong> PE statistics reports <strong>for</strong> the same test.<br />

Table 8-10 Protocol Level 2 - <strong>DB2</strong> PE Statistics Report extract<br />

IRLM<br />

(msec / commit)<br />

Total <strong>DB2</strong> CPU time<br />

(msec / commit)<br />

For our IRWW workload, we see a dramatic reduction in IRLM SRB time. This is because<br />

there is less XES contention to resolve. Remember that XES must defer to the IRLMs to<br />

resolve any XES contention and this activity drives IRLM CPU.<br />

Our workload also achieved a significant increase in transaction throughput. This is a result of<br />

the workload suffering fewer class 3 suspensions, waiting <strong>for</strong> XES contention to be resolved.<br />

In the past, a number of customers have opted to BIND their high use plans and packages<br />

using RELEASE(DEALLOCATE) rather than RELEASE(COMMIT).<br />

RELEASE(DEALLOCATE) has a number of per<strong>for</strong>mance advantages. <strong>DB2</strong> does not have to<br />

release and re-acquire table space level locks after a commit. Some customers have also<br />

used RELEASE(DEALLOCATE) to reduce the amount of XES contention in their data sharing<br />

environments. However there is a cost in availability. It may be more difficult to execute DDL<br />

as the <strong>DB2</strong> objects are allocated longer to the plans and packages.<br />

So, let us have a look at the impact the new locking protocol has on the BIND RELEASE<br />

parameter. Table 8-11 compares the impact on per<strong>for</strong>mance of RELEASE(COMMIT)<br />

compared to RELEASE(DEALLOCATE) in both <strong>DB2</strong> V7 and <strong>DB2</strong> V8.<br />

Table 8-11 Protocol Level 2 - RELEASE(DEALLOCATE) vs. RELEASE(COMMIT)<br />

We can see that <strong>for</strong> <strong>DB2</strong> V7, RELEASE(DEALLOCATE) has on average an 18% reduction in<br />

CPU time per transaction, compared to RELEASE(COMMIT). There is less reduction, 7%, in<br />

<strong>DB2</strong> V8 when the new locking protocol is use. RELEASE(DEALLOCATE) still uses less CPU<br />

time, but the delta is much smaller with V8 and protocol 2.<br />

The table also shows an 18% improvement in transaction throughput by using<br />

RELEASE(DEALLOCATE) in <strong>DB2</strong> V7. This gain is reduced to only a 5% improvement in<br />

transaction throughput when the new locking protocol is used.<br />

330 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8 Delta<br />

(V8 / V7)<br />

0.330 0.317 0.012 0.015 -96%<br />

3.447 3.708 3.109 3.357 -10%<br />

Group ITR 823.56 897.00 +9%<br />

<strong>DB2</strong> V7 <strong>DB2</strong> V8<br />

Transaction CPU time -18% -7%<br />

Global ITR +18% +5%


8.2.2 Conclusion<br />

The purpose of the locking Protocol Level 2 enhancement is to avoid the cost of global<br />

contention processing whenever possible. <strong>DB2</strong> no longer needs to wait <strong>for</strong> global lock<br />

contention processing to determine that a new parent IX or IS L-lock is compatible with<br />

existing parent IX or IS L-locks which is reasonably common in a data sharing environment.<br />

For our workload, our testing has shown that the new locking protocol dramatically reduces<br />

both XES and false contention. This results in shorter lock and global contention suspension<br />

times. We also observed less IRLM SRB time with an improved overall transaction<br />

throughput. However, we see more synchronous XES requests to the coupling facility and<br />

more lock structure traffic with slightly higher coupling facility utilization. These increases do<br />

not appear to be excessive and should not impact overall per<strong>for</strong>mance.<br />

The new locking protocol also reduces the per<strong>for</strong>mance gap between RELEASE(COMMIT)<br />

and RELEASE(DEALLOCATE) <strong>for</strong> data sharing workloads.<br />

Another consequence of this enhancement is that, since child L-lock propagation is no longer<br />

dependent upon the parent L-lock, parent L-locks will no longer be held in retained state<br />

following a system failure. This means, <strong>for</strong> example, that an IX L-lock will no longer be held as<br />

a retained X-lock after a system failure. This can provide an important availability benefit in a<br />

data sharing environment. Because there is no longer a retained X-lock on the page set most<br />

of the data in the page set remains available to applications running on other members. Only<br />

the pages (assuming page locking is used) with a retained X-lock will be unavailable.<br />

With the change to the LOCKPART parameter behavior, you may see additional locks<br />

acquired on individual partitions even though LOCKPART NO is specified.<br />

When <strong>DB2</strong> decides it must propagate its locks to the coupling facility <strong>for</strong> a given page set,<br />

<strong>DB2</strong> must collect and propagate all the locks it currently owns <strong>for</strong> that page set to the coupling<br />

facility. This can cause some overhead, particularly when a page set is not used often enough<br />

<strong>for</strong> lock propagation to occur all the time. Page set P-locks are long duration locks and tend to<br />

be more static than L-locks, so the chances are higher that lock propagation will continue <strong>for</strong><br />

longer.<br />

8.2.3 Recommendations<br />

The new mapping in the coupling facility lock structure to support the Protocol 2 Level locking,<br />

takes effect after the restart of the first member, after successful quiesce of all members in<br />

the <strong>DB2</strong> data sharing group. To enable this feature, a group-wide outage is required after you<br />

have entered NFM. This obviously has some impact on availability.<br />

However, we recommend you plan to schedule a group-wide restart of <strong>DB2</strong> soon after you<br />

enter NFM to enable the new locking protocol as soon as possible.<br />

If you currently are in the practice of starting table spaces in RO to avoid locking contention in<br />

a data sharing environment, you may wish to revise this strategy.<br />

In data sharing, the recommendation <strong>for</strong> RELEASE(DEALLOCATE) (and thread reuse) to<br />

reduce XES messaging <strong>for</strong> L-locks is no longer required. This is good news because using<br />

RELEASE(DEALLOCATE):<br />

► Can cause increased EDM pool consumption, because plans and packages stay allocated<br />

longer in the EDM pool.<br />

► May also cause availability concerns due to parent L-locks being held <strong>for</strong> longer. This can<br />

potentially prevent DDL from running, or cause applications using the LOCK TABLE<br />

statement and some utilities to fail.<br />

Chapter 8. Data sharing enhancements 331


There is also no need to use RELEASE(DEALLOCATE) if you currently use this BIND<br />

parameter to reduce XES contention.<br />

8.3 Change to IMMEDWRITE default BIND option<br />

8.3.1 Per<strong>for</strong>mance<br />

Prior to V8, any remaining changed pages in a data sharing environment are written to the<br />

group buffer pool during phase 2 of commit, unless otherwise specified by the IMMEDWRITE<br />

BIND parameter. This enhancement changes the default processing to write changed pages<br />

during commit phase 1. <strong>DB2</strong> no longer writes changed pages to the coupling facility during<br />

phase 2 of commit processing.<br />

An implication of this change to commit processing is that <strong>DB2</strong> V8 now charges all writes of<br />

changed pages to the allied TCB, not the MSTR address space.<br />

Consider the situation where one transaction updates <strong>DB2</strong> data using INSERT, UPDATE, or<br />

DELETE, and then, be<strong>for</strong>e completing phase 2 of commit, spawns a second transaction that<br />

is executed on another <strong>DB2</strong> member and is dependent on the updates that were made by the<br />

first transaction. This type of relationship is referred to as “ordered dependency” between<br />

transactions. In this case, the second transaction may not see the updates made by the first<br />

transaction.<br />

<strong>DB2</strong> V5 introduced a new BIND parameter to overcome this problem. IMMEDWRITE(YES)<br />

allows the user to specify that <strong>DB2</strong> should immediately write updated GBP dependent buffers<br />

to the coupling facility instead of waiting until commit or rollback. This option solves the<br />

application issue at the expense of per<strong>for</strong>mance since it <strong>for</strong>ces each individual changed page<br />

immediately to the CF, ahead of commit, with each immediate write implying also a write to<br />

the <strong>DB2</strong> log, <strong>for</strong> as many changes are made to same page.<br />

<strong>DB2</strong> V6 extended this functionality. IMMEDWRITE(PH1) allows the user to specify that <strong>for</strong> a<br />

given plan or package updated group buffer pool dependent pages should be written to the<br />

coupling facility at or be<strong>for</strong>e phase 1 of commit. This option does not cause a per<strong>for</strong>mance<br />

penalty. If the transaction subsequently rolls back, the pages will be updated again during the<br />

rollback process and will be written again to the coupling facility at the end of abort.<br />

In prior versions of <strong>DB2</strong>, changed pages in a data sharing environment are normally written<br />

during phase 2 of the commit process, unless otherwise specified by the IMMEDWRITE BIND<br />

parameter, or IMMEDWRI DSNZPARM parameter.<br />

<strong>DB2</strong> V8 changes the default processing to write changed pages during phase 1 of commit<br />

processing. The options you can specify <strong>for</strong> the IMMEDWRITE BIND parameter remain<br />

unchanged. However, whether you specify “NO”' or “PH1”, the behavior will be identical,<br />

changed pages are written during phase 1 of commit processing.<br />

In <strong>DB2</strong> V8, changed pages are only written at or be<strong>for</strong>e phase 1, never at phase 2 of the<br />

commit processing.<br />

The book <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 <strong>Version</strong> 7 Per<strong>for</strong>mance <strong>Topics</strong>, SG24-6129, documents a<br />

study of the impact of writing pages to the group buffer pool during phase 2 of commit,<br />

IMMEDWRITE(NO), compared to writing pages to the group buffer pool during phase 1 of<br />

commit, IMMEDWRITE(PH1). The testing revealed the Internal Throughput Rates are very<br />

close to each other; meaning writing pages to the group buffer pool during phase 1 of commit<br />

has little or no per<strong>for</strong>mance impact.<br />

332 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


8.3.2 Conclusion<br />

The impact of IMMEDWRITE YES remains unchanged. Changed pages are written to the<br />

group buffer pool as soon as the buffer updates are complete, be<strong>for</strong>e committing.<br />

With IMMEDWRITE NO (or PH1) and YES options, the CPU cost of writing the changed<br />

pages to the group buffer pool is charged to the allied TCB. Prior to <strong>DB2</strong> V8, this was true<br />

only <strong>for</strong> PH1 and YES options. For the NO option, the CPU cost of writing the changed pages<br />

to the group buffer pool was charged to the MSTR SRB, since the pages were written as part<br />

of phase 2 commit processing under the MSTR SRB.<br />

<strong>DB2</strong> V8 now charges all writes of changed pages to the allied TCB, not the MSTR address<br />

space. This enhancement provides a more accurate accounting <strong>for</strong> all <strong>DB2</strong> workloads. <strong>DB2</strong> is<br />

now able to charge more work back to the user who initiated the work in the first place.<br />

The impact of changing the default IMMEDWRITE BIND option means that with V8 <strong>DB2</strong> no<br />

longer writes any page to the group buffer pool during phase 2 of commit processing. This<br />

change has very little impact on Internal Throughput Rates of a transaction workload and<br />

there<strong>for</strong>e has little or no per<strong>for</strong>mance impact.<br />

However, you may see some increase in CPU used by each allied address space, as the cost<br />

of writing any remaining changed pages to the group buffer pool has shifted from the MSTR<br />

address space to the allied address space.<br />

8.3.3 Recommendations<br />

The IMMEDWRITE enhancements are immediately available when you migrate to <strong>DB2</strong> V8.<br />

You do not have to wait until new-function mode.<br />

Customers who use the allied TCB time <strong>for</strong> end-user charge back may see additional CPU<br />

cost with this change.<br />

8.4 <strong>DB2</strong> I/O CI limit removed<br />

8.4.1 Per<strong>for</strong>mance<br />

Prior to <strong>DB2</strong> V8, <strong>DB2</strong> did not schedule a single I/O <strong>for</strong> a page set with CIs that span a range<br />

of more than 180 CIs. This restriction was in place to avoid long I/O response times.<br />

With advances in DASD technology, especially Parallel Access Volume (PAV) support, this<br />

restriction can now be lifted.<br />

<strong>DB2</strong> V8 removes the CIs per I/O limit <strong>for</strong> list prefetch and castout I/O requests. The limit still<br />

remains <strong>for</strong> deferred write requests, to avoid any potential per<strong>for</strong>mance degradation during<br />

transaction processing. Recall that a page is not available <strong>for</strong> update while it is being written<br />

to DASD. So, we do not want an online transaction to have to wait <strong>for</strong> a potentially longer<br />

deferred write I/O request to complete.<br />

A number of per<strong>for</strong>mance studies have been done to understand the benefit of removing the<br />

CI limit <strong>for</strong> <strong>DB2</strong> I/O requests. For these studies, the IRWW workload was used in both a data<br />

sharing environment and a non-data sharing environment.<br />

Table 8-12 shows extracts from <strong>DB2</strong> PE statistics reports <strong>for</strong> a non-data sharing environment<br />

running the IRWW workload.<br />

Chapter 8. Data sharing enhancements 333


Table 8-12 <strong>DB2</strong> I/O CI Limit Removal - Non-data sharing<br />

Activity With I/O CI Limit I/O CI Limit<br />

Removed<br />

List Prefetch Requests 57,889 58,165<br />

List Prefetch Reads 317,000 56,122<br />

List Prefetch Pages Read /<br />

List Prefetch Reads<br />

The values listed verify that the limit on CIs per <strong>DB2</strong> I/O has been removed. The number of<br />

List Prefetch Reads has reduced dramatically, with a corresponding increase in the number of<br />

pages read per List Prefetch request.<br />

Table 8-13 shows extracts from <strong>DB2</strong> PE statistics reports <strong>for</strong> a data sharing environment with<br />

two members running the same IRWW workload.<br />

Table 8-13 <strong>DB2</strong> I/O CI limit removal - Data sharing<br />

You can see the positive impact of removing the <strong>DB2</strong> CI I/O limits. The number of List<br />

Prefetch Reads has reduced, with a corresponding increase in the number of pages read per<br />

List Prefetch request.<br />

Note also that the number of pages written per write I/O has also increased significantly. This<br />

is unique to data sharing and shows the extra benefits of removing this limitation in a data<br />

sharing environment. The <strong>DB2</strong> CI I/O limits is also removed <strong>for</strong> castout processing in data<br />

sharing environments. The number of pages written per write I/O increased significantly<br />

because more pages can now be written in castout. We would also see a corresponding<br />

decrease in Unlock Castout requests as reported in the Group Buffer pool Activity section of a<br />

<strong>DB2</strong> PE Statistics report.<br />

Now we have a look at the impact on CPU. Table 8-14 shows CPU times from <strong>DB2</strong> PE<br />

statistics reports <strong>for</strong> a non-data sharing environment, running the IRWW workload.<br />

Table 8-14 <strong>DB2</strong> I/O CI limit removal - Non-data sharing CPU<br />

334 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

4.76 26.85<br />

Pages Written per Write I/O 1.84 1.83<br />

Activity With I/O CI Limit I/O CI Limit Removed<br />

List Prefetch Requests 42,876 42,783 43,186 43,187<br />

List Prefetch Reads 209,600 208,200 40,894 40,711<br />

List Prefetch Pages Read /<br />

List Prefetch Reads<br />

3.58 3.56 18.44 18.39<br />

Pages Written per Write I/O 6.20 4.37 27.11 26.49<br />

DBM1<br />

(msec/commit)<br />

Total <strong>DB2</strong> CPU time<br />

(msec/commit)<br />

ITR<br />

(commits/sec)<br />

With I/O CI LImit I/O CI Limit<br />

Removed<br />

0.342 0.322 -6%<br />

2.281 2.238 -2%<br />

592.47 601.42 +2%<br />

Delta<br />

(Removed / With)


8.4.2 Conclusion<br />

The values listed show a significant reduction in overall CPU used by the DBM1 address<br />

space, (-6%), with a modest increase in transaction throughput, (+2%). This is a result of <strong>DB2</strong><br />

per<strong>for</strong>ming fewer list prefetch requests <strong>for</strong> the given workload, as more pages are eligible to<br />

be retrieved by each prefetch I/O request.<br />

Table 8-15 summarizes CPU times from <strong>DB2</strong> PE statistics reports <strong>for</strong> a data sharing<br />

environment, running the same IRWW workload.<br />

Table 8-15 <strong>DB2</strong> I/O CI limit removal - Data sharing CPU<br />

DBM1<br />

(msec / commit)<br />

This table combines the effect of both the Locking Protocol changes as well as the removal of<br />

the <strong>DB2</strong> CI I/O limits on the CPU consumed by the DBM1 address space. Refer to 8.2,<br />

“Locking protocol level 2” on page 325, <strong>for</strong> a discussion on data sharing locking protocol<br />

changes in <strong>DB2</strong> V8.<br />

From Table 8-10 on page 330 we can see the locking protocol changes can account <strong>for</strong> about<br />

a 10% improvement in CPU used by the DBM1 address space. So, by removing the <strong>DB2</strong> CI<br />

I/O limits in <strong>DB2</strong> V8 you can see another modest reduction in CPU used by the DBM1<br />

address space. This is due to fewer list prefetch requests and more efficient castout<br />

processing.<br />

The removal of the <strong>DB2</strong> CI I/O limits <strong>for</strong> list prefetch requests and castout I/O has the potential<br />

to significantly reduce the CPU used by the DBM1 address space.<br />

Further benefits can be realized in a data sharing environment through more efficient castout<br />

processing. In the past castout processing generally only was able to castout a few pages on<br />

each request as pages to be castout can be quite random. With this enhancement castout<br />

processing can process more pages <strong>for</strong> a table space with each request and not be restricted<br />

to only pages that are within the 180 CIs within the table space.<br />

The extent of CPU gains from this enhancement will vary significantly, depending on<br />

application processing, access paths used, data organization and placement. Applications<br />

which per<strong>for</strong>m a lot of list prefetch with a large distance between pages will benefit the most<br />

from this enhancement.<br />

In data sharing, applications which generate a lot of castout processing <strong>for</strong> not contiguous<br />

pages, should also benefit from this enhancement. OLTP per<strong>for</strong>mance can definitely<br />

experience a positive per<strong>for</strong>mance impact from 180 CI limit removal. One customer reported<br />

a significant CPU spike every 15 seconds caused by excessive unlock castout and delete<br />

namelist requests. This problem was eliminated after the 180 CI limit removal in castout.<br />

8.4.3 Recommendations<br />

With I/O CI Limit I/O CI Limit<br />

Removed<br />

0.518 0.590 0.456 0.457 -18%<br />

Delta<br />

(Removed / With)<br />

This enhancement is transparent and is available in CM as soon as the PTFs <strong>for</strong> APARs<br />

PQ86071 and PQ89919 have been applied.<br />

Chapter 8. Data sharing enhancements 335


8.5 Miscellaneous items<br />

In this section we describe some miscellaneous enhancements that impact <strong>DB2</strong> data sharing.<br />

8.5.1 Impact on coupling facility<br />

You do not need to resize the group buffer pools, lock structure or SCA in the coupling facility<br />

as a result of moving to <strong>DB2</strong> V8, even though the virtual buffer pools have now moved above<br />

the bar and have a longer memory address. This is true provided of course, you have not<br />

made any significant changes when you migrate to <strong>DB2</strong> V8.<br />

However, you may wish to review your coupling facility structure sizes after you have migrated<br />

to <strong>DB2</strong> V8. For example, you may like to revise your virtual buffer pool sizes now that there<br />

are no hiperpools or buffer pools in data spaces.<br />

We do recommend you review your coupling facility structure sizes as you prepare to<br />

implement CFLEVEL 12. This is required to take advantage of the CF Request Batch<br />

per<strong>for</strong>mance enhancements, described earlier. When migrating CFLEVELs, coupling facility<br />

structure sizes might need to be increased to support the new function. For example, when<br />

you upgrade from CFLEVEL 9 to CFLEVEL 11 or from CFLEVEL 10 to CFLEVEL 12, the<br />

required size of the structures might increase by up to 768 KB.<br />

The following “Rule of Thumb” <strong>for</strong>mulas may be used to estimate the required coupling facility<br />

structure sizes, based on migrating from CFLEVEL 10 or 11 to CFLEVEL 12. The thumb rules<br />

are only rough approximations.<br />

CFLEVEL 12 structure size = CF level 10 (or 11) structure size PLUS the following based<br />

on type of structure and entry:element ratio:<br />

Lock structure:<br />

Without record data: 0<br />

With record data: 20% of level 10 or 11<br />

List or cache structure:<br />

No data (no elements): 0<br />

Entry:element ratio = 1:1: 2MB + 10%<br />

Entry:element ratio >= 100:1(scale % factor <strong>for</strong> ratios in between): 2MB + 50%<br />

and should only be used if methods 2 and 3 are not applicable.<br />

For example, given a <strong>DB2</strong> group buffer pool structure of 100 Mb, and an entry:element ratio of<br />

5:1 and you are at CFLEVEL 10, then CFLEVEL 12 will require an extra:<br />

100 + 2 + 12% x 100 = 114 MB<br />

If the higher CFLEVEL is accessible in your configuration and is defined in the CFRM policy,<br />

and OW54685 is applied, then structure rebuilds from lower CFLEVELs to higher CFLEVELs<br />

will resize the structure automatically based on its current structure object counts.<br />

Alternatively, we suggest you use the CFSIZER to check your coupling facility structure sizes.<br />

The CFSIZER can be found at:<br />

http://www.ibm.com/servers/eserver/zseries/cfsizer/<br />

8.5.2 Improved LPL recovery<br />

Prior to <strong>DB2</strong> V8, when you issue the -START DATABASE command to recover LPL pages, the<br />

command must drain the entire table space or partition. The "drain" means that the command<br />

must wait until all current users of the table space or partition reach their next commit point.<br />

336 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


All users requesting new access to the table space or partition are also suspended and must<br />

wait until the recovery completes (or until the user times out). There<strong>for</strong>e, the drain operation<br />

can be very disruptive to other work that is running in the system, especially in the case<br />

where only one or a few pages are in LPL.<br />

In <strong>DB2</strong> V8, the locking and serialization schemes in the -START DATABASE command have<br />

changed when doing the LPL recovery. In prior versions of <strong>DB2</strong>, the -START DATABASE<br />

command acquires a DRAIN ALL lock on the table space or partition when doing the LPL<br />

recovery. <strong>DB2</strong> V8 makes a WRITE CLAIM on the table space or partition. By acquiring a<br />

WRITE CLAIM instead of a DRAIN ALL, the “good” pages can still be accessed by SQL while<br />

the -START DATABASE is recovering the LPL pages. A new "LPL recovery” lock type is also<br />

introduced to en<strong>for</strong>ce that only one LPL recovery process is running at a time <strong>for</strong> a given table<br />

space or partition.<br />

This less disruptive locking strategy potentially enhances both the per<strong>for</strong>mance and<br />

availability of your applications, as more data can potentially be available to the application<br />

while the pages in the LPL are being recovered.<br />

<strong>DB2</strong> V8 also automatically attempts to recover pages that are added to the LPL at the time<br />

they are added to the LPL, if <strong>DB2</strong> determines that automatic recovery has a reasonable<br />

chance of success. Automatic LPL recovery is not initiated by <strong>DB2</strong> in the following situations:<br />

► DASD I/O error<br />

► During <strong>DB2</strong> restart or end_restart time<br />

► GBP structure failure<br />

► GBP 100% loss of connectivity<br />

Automatic LPL recovery improves the availability of your applications, as the pages in the LPL<br />

can be recovered sooner. In many cases you do not have to issue the -START DATABASE<br />

commands yourself to recover LPL pages.<br />

In addition, <strong>DB2</strong> V8 provides more detailed in<strong>for</strong>mation in message DSNB250E why a page<br />

has been added to the LPL. The different reason types are:<br />

► DASD: <strong>DB2</strong> encountered a DASD I/O error when trying to read or write pages on DASD.<br />

► LOGAPPLY: <strong>DB2</strong> cannot apply log records to the pages.<br />

► GBP: <strong>DB2</strong> cannot successfully read or write the pages from or to the group buffer pool due<br />

to link or structure failure, GBP in rebuild, or GBP was disconnected.<br />

► LOCK: <strong>DB2</strong> cannot get the required page latch or page P-lock on the pages.<br />

► CASTOUT: The <strong>DB2</strong> Castout processor cannot successfully cast out the pages.<br />

► MASSDEL: <strong>DB2</strong> encountered an error in the mass delete processor during the phase 2 of<br />

commit.<br />

These extra diagnostics help you to quickly identify and hopefully resolve why pages are<br />

being placed into the LPL thereby increasing the availability of your applications.<br />

8.5.3 Restart Light enhancements<br />

<strong>DB2</strong> V7 introduced the concept of <strong>DB2</strong> Restart Light which is intended to remove retained<br />

locks with minimal disruption in the event of an MVS system failure. When a <strong>DB2</strong> member is<br />

started in restart light mode (LIGHT(YES)), <strong>DB2</strong> comes up with a small storage footprint,<br />

executes <strong>for</strong>ward and backward restart log recovery, removes the retained locks, and then<br />

self-terminates without accepting any new work.<br />

Chapter 8. Data sharing enhancements 337


<strong>DB2</strong> V8 improves Restart Light. If indoubt units of recovery (UR) exist at the end of restart<br />

recovery, <strong>DB2</strong> now remains running so that the indoubt URs can be resolved. After all the<br />

indoubt URs have been resolved, the <strong>DB2</strong> member that is running in LIGHT(YES) mode will<br />

shut down and can be restarted normally.<br />

A <strong>DB2</strong> member that has been started with LIGHT(YES) that remains active to resolve indoubt<br />

URs will still not accept any new connection requests, except those that originate from<br />

connection names that have indoubt URs.<br />

If DDF is normally active, Restart Light will also start DDF to facilitate the resolution of any<br />

distributed indoubt URs. However, no new DDF connections are allowed. Only resynch<br />

requests will be allowed from <strong>DB2</strong> clients.<br />

This enhancement to Restart Light has the potential to benefit both the availability and<br />

per<strong>for</strong>mance of applications that are still running on other active <strong>DB2</strong> members.<br />

For example, you do not have to bring <strong>DB2</strong> up a second time to resolve any indoubt threads<br />

and remove any retained locks held by those indoubt threads. (Remember that under V7,<br />

<strong>DB2</strong> would terminate immediately after a successful restart, when it is started in light mode.)<br />

Potentially more retained locks are released faster, making the data protected by those<br />

retained locks available sooner <strong>for</strong> applications that are running on other active <strong>DB2</strong><br />

members.<br />

8.5.4 Change to close processing <strong>for</strong> pseudo close<br />

In data sharing, any table space or index which has remained in a read-only state with no<br />

activity <strong>for</strong> a period of time longer than the pseudo-close interval (PCL<strong>OS</strong>ET DSNZPARM) will<br />

be physically closed. This is done in an attempt to reduce data sharing overhead (the object<br />

can become non-GBP-dependent if it is closed on all but one member), but it has the<br />

disadvantage of requiring that the next access to the object must go through dynamic<br />

allocation and data set open again. This can be a significant amount of overhead, particularly<br />

if a large number of objects are accessed at the same time after a period of inactivity (<strong>for</strong><br />

example, at the beginning of the business day).<br />

<strong>DB2</strong> V8 now honors the CL<strong>OS</strong>E YES or NO attribute of the table space or index. The physical<br />

close will now only take place <strong>for</strong> CL<strong>OS</strong>E YES objects, while CL<strong>OS</strong>E NO objects may remain<br />

open indefinitely. This allows you to control the behavior on an object-level basis; <strong>for</strong>merly, the<br />

only means of control was through the pseudo-close DSNZPARMs, and lengthening the<br />

pseudo-close interval to keep data sets open could have other undesirable effects.<br />

There is no per<strong>for</strong>mance impact in a data sharing environment when you specify CL<strong>OS</strong>E<br />

YES. However CL<strong>OS</strong>E NO does have an impact. No really means no now, in a data sharing<br />

environment. If you want things to behave as they did prior to <strong>DB2</strong> V8, (in a data sharing<br />

environment), you need to alter your CL<strong>OS</strong>E NO objects to CL<strong>OS</strong>E YES.<br />

Consider CL<strong>OS</strong>E NO <strong>for</strong> objects that you estimate to be GBP-dependent most of the time and<br />

you do not want the extra open/close overhead associated with CL<strong>OS</strong>E YES. For objects that<br />

are infrequently GBP-dependent, CL<strong>OS</strong>E YES will likely provide better per<strong>for</strong>mance. Once<br />

GBP-dependent, CL<strong>OS</strong>E NO objects will stay GBP-dependent until either DSMAX is hit and<br />

all CL<strong>OS</strong>E YES objects have been closed or until the CL<strong>OS</strong>E NO objects are manually closed<br />

as a result of a <strong>DB2</strong> command or a <strong>DB2</strong> shutdown.<br />

This enhancement is also made available in <strong>DB2</strong> V6 and V7 by PTF UQ74866 <strong>for</strong> APAR<br />

PQ69741.<br />

338 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


8.5.5 Buffer pool long term page fixing<br />

<strong>DB2</strong> V8 allows you to fix the buffer pages once in memory and keep them fixed in real<br />

storage. This is implemented by new - ALTER BUFFERPOOL parameter called PGFIX. The<br />

ability to long term page fix buffer pool pages in memory and keep them in real storage,<br />

avoids the processing time that <strong>DB2</strong> needs to fix and free pages each time there is an I/O.<br />

The ability to page fix buffer pool pages in memory has a significant improvement in <strong>DB2</strong><br />

per<strong>for</strong>mance, both <strong>for</strong> data sharing environments and non-data sharing environments.<br />

Although there are still significant CPU savings to be realized in data sharing, the CPU<br />

savings are generally not as much as in non-data sharing. This is because the castout buffers<br />

are NOT long term page fixed.<br />

The primary reason why an overall saving is not as high in data sharing is a higher fixed<br />

overhead of data sharing. A long term page fix applies to GBP read and write. It does not<br />

apply to castout work area, since cast work area is not a part of buffer pool and a long term<br />

page fix is a buffer pool option.<br />

Refer to 4.5, “Buffer pool long term page fixing” on page 169 <strong>for</strong> a more detailed analysis of<br />

long term page fixing <strong>DB2</strong> buffers, both in data sharing and non-data sharing environments.<br />

8.5.6 Batched index page splits<br />

In previous versions of <strong>DB2</strong>, index page splits <strong>for</strong> indexes with inter-<strong>DB2</strong> read/write interest,<br />

required multiple synchronous log writes and multiple separate writes to the group buffer pool.<br />

This was to ensure that when a leaf page split occurs, the index pages involved are written<br />

out in the correct order, to prevent another member from seeing a reference to an index page<br />

that does not yet exist in the group buffer pool.<br />

This caused significant overhead <strong>for</strong> GBP-dependent indexes, resulting in additional<br />

synchronous group buffer pool writes, and even more important, in high wait times <strong>for</strong><br />

synchronous log I/O.<br />

With this enhancement, <strong>DB2</strong> accumulates the index page split updates and processes them<br />

as a single entity, thereby reducing log writes and coupling facility traffic. The writes to the<br />

coupling facility of the accumulated updates use the new z/<strong>OS</strong> CF Batching commands<br />

described earlier.<br />

However even without CFCC level 12 and z/<strong>OS</strong> 1.4, (the prerequisites <strong>for</strong> CF Batching), you<br />

can still take advantage of some per<strong>for</strong>mance improvements through this enhancement. In<br />

this case the coupling facility writes are not batched, but the number of <strong>for</strong>ced writes to the log<br />

are reduced to just one or two.<br />

Batching the updates <strong>for</strong> index page splits will boost per<strong>for</strong>mance by reducing the cost of<br />

page set group buffer pool dependency, but even more by reducing the log I/O wait time, is a<br />

more efficient mechanism to process index page splits. Applications which have heavy<br />

insertion activity will see the most benefit in data sharing.<br />

This enhancement does not impact non-data sharing environments or data sharing<br />

environments where the index is not group buffer pool dependent. In these cases, <strong>DB2</strong> does<br />

not have to externalize the updated index pages in any particular sequence to be seen<br />

correctly by any other <strong>DB2</strong> members.<br />

In both V7 and V8, we see 2 or 3 <strong>for</strong>ced log writes now.<br />

Chapter 8. Data sharing enhancements 339


340 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Chapter 9. Installation and migration<br />

During the installation and/or migration to <strong>DB2</strong> V8, the system programmer should be aware<br />

of the way some installation parameters impact per<strong>for</strong>mance. Often the system parameters<br />

are chosen based on defaults and are carried along, but sometimes they change across<br />

versions and might need adjusting.<br />

In this chapter we review several factors that have an impact on the per<strong>for</strong>mance of the<br />

installation of <strong>DB2</strong> V8. If you want a more comprehensive and detailed description of the<br />

installation and migration processes, refer to the documentation listed in “Related<br />

publications” on page 425, specifically <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide,<br />

GC18-7418, and <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Data Sharing Planning and Administration<br />

Guide, SC18-7417.<br />

In this chapter, we discuss the following topics:<br />

► Unicode catalog<br />

► IVP sample programs<br />

► Installation<br />

► Migration<br />

► Catalog consistency query DSNTESQ<br />

9<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 341


9.1 Unicode catalog<br />

<strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> supports three types of encoding schemes:<br />

► EBCDIC<br />

► ASCII<br />

► UNICODE<br />

Traditionally <strong>IBM</strong> mainframes have been based on EBCDIC, while Unix and Windows<br />

applications are based on ASCII. Beginning with Windows NT®, everything stored in<br />

Windows was stored in Unicode (UTF-16). To handle larger character sets, which are<br />

absolutely necessary in Asian languages, double byte characters and mixtures of single byte<br />

and double byte characters were necessary.<br />

Each national language developed its own code pages in EBCDIC or ASCII. The character<br />

set <strong>for</strong> a language is identified by a numeric CCSID. An encoding scheme consists of a single<br />

byte character set (SBCS), and optionally a double byte character set (DBCS) along with a<br />

mixed character set. For example, the EBCDIC CCSID used by the z/<strong>OS</strong> operating system<br />

itself is 37, but Japanese can use 8482 <strong>for</strong> SBCS, 16684 <strong>for</strong> DBCS and 1390 <strong>for</strong> mixed.<br />

Terminology: Translation is what we do going from language to another, while conversion is<br />

what we do to character strings. CCSIDs (and code pages) are never converted, they are just<br />

definitions. The individual character strings are converted.<br />

9.1.1 Character conversion<br />

9.1.2 Unicode parsing<br />

The variety of CCSIDs made it very difficult <strong>for</strong> multinational corporations to combine data<br />

from different sources. Unicode has arisen to solve the problem. By storing data in a single<br />

Unicode CCSID, text data from different languages in different countries can be easily<br />

managed. However, to make the transition to Unicode can be difficult and a lot of data<br />

conversion is unavoidable. When storing into and retrieving data from <strong>DB2</strong>, <strong>DB2</strong> will convert<br />

data where necessary. Obviously, it is preferable that no conversion be carried out, because<br />

conversion impacts per<strong>for</strong>mance. However, considerable work has been done to improve<br />

conversion per<strong>for</strong>mance on zSeries. See 4.7, “Unicode” on page 174.<br />

Character conversion is necessary whenever there is a mismatch between the CCSID of a<br />

source and target string, such as between a host variable and its associated column. Such<br />

conversion support in <strong>DB2</strong> has existed since <strong>DB2</strong> began to support client/server connections.<br />

In <strong>DB2</strong> V2.3 such translations started out between different EBCDIC CCSIDs, as well as<br />

between EBCDIC and ASCII. To per<strong>for</strong>m such character conversion (not involving Unicode),<br />

<strong>DB2</strong> uses a translate table which is stored in SYS<strong>IBM</strong>.SYSSTRINGS. We will refer to such<br />

conversions as SYSSTRINGS conversions, which have particular per<strong>for</strong>mance<br />

characteristics.<br />

In <strong>DB2</strong> V8, because the catalog has changed to Unicode, data being sent or received by the<br />

application must be verified and possibly converted by the DBM1 address space.<br />

Figure 9-1 depicts a legacy COBOL application running in z/<strong>OS</strong> using CCSID 37. The<br />

database has been converted to Unicode. The table contains one CHAR column called<br />

COLC (CCSID 1208) and one GRAPHIC column called COLG (CCSID 1200). When the<br />

application inserts host variables HV1 and HV2 into the table, the strings are converted by the<br />

DBM1 address space into Unicode. The CPU time <strong>for</strong> these conversions is added to class 2<br />

CPU time.<br />

342 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Figure 9-1 Unicode conversion example<br />

<strong>DB2</strong> V8 brings significant enhancements in the Unicode area lifting restrictions that were in<br />

<strong>DB2</strong> V7. These enhancements include Unicode parsing and the conversion of the <strong>DB2</strong><br />

Catalog to Unicode. <strong>DB2</strong> V8 <strong>for</strong>malizes a two stage migration process that used to be<br />

followed by customers implicitly, but which is now en<strong>for</strong>ced by <strong>DB2</strong>.<br />

When you first start <strong>DB2</strong> V8, you are running in CM where the <strong>DB2</strong> catalog is still in EBCDIC<br />

and you are prevented from exploiting new function. However, all SQL parsing in <strong>DB2</strong> V8 is<br />

done in Unicode, that is, UTF-8, even in compatibility mode. SQL statements that are input in<br />

EBCDIC, ASCII or UTF-16 must be converted to UTF-8. In compatibility mode, metadata that<br />

is derived (in other words, parsed) from the SQL statement must be converted to EBCDIC in<br />

order to compare them to <strong>DB2</strong> catalog data.<br />

When you migrate the catalog to new-function mode (NFM), the <strong>DB2</strong> catalog is converted to<br />

Unicode, and fallback to V7 is no longer possible. New <strong>DB2</strong> V8 installations always run in<br />

NFM.<br />

SQL statement conversion is unaffected by the switch to NFM, but metadata derived from<br />

SQL is no longer converted since the metadata is already in the CCSID of the <strong>DB2</strong> catalog.<br />

On the other hand, Unicode conversion is introduced <strong>for</strong> column names specified within an<br />

SQLDA in EBCDIC or ASCII. <strong>DB2</strong> V8 also introduces the capability to join two tables of<br />

different CCSIDs. Needless to say, Unicode conversion is necessary to do this and the extra<br />

CPU time is likely to be substantial.<br />

<strong>DB2</strong> V8 major and minor conversion<br />

Conversion of SQL statements and metadata generally involves English alphanumeric<br />

characters. To improve per<strong>for</strong>mance, <strong>DB2</strong> V8 developed a faster way to convert such<br />

characters without calling the z/<strong>OS</strong> Conversion Services. This fast method is called minor<br />

conversion, while major conversion refers to those conversions per<strong>for</strong>med by the z/<strong>OS</strong><br />

Conversion Services. <strong>DB2</strong> does this by maintaining a translate table associated with the<br />

EBCDIC SBCS/single bytes of the mixed CCSIDs that are specified during <strong>DB2</strong> installation.<br />

The same translate table is used <strong>for</strong> accesses to the <strong>DB2</strong> catalog and user data. Minor<br />

conversion is supported <strong>for</strong> all European EBCDIC character sets, and some Asian EBCDIC<br />

character sets. Minor conversion does not apply to UTF-16 (GRAPHIC) or ASCII; it may only<br />

apply to conversions between EBCDIC and UTF-8.<br />

In a multinational corporate environment, we may see applications originating from different<br />

national languages accessing a common database. A Unicode database allows such a<br />

multinational corporation to store all of its data in a single database. Since we cannot assume<br />

Chapter 9. Installation and migration 343


that all applications are converted to Unicode, Unicode conversion is supported <strong>for</strong> every<br />

language that is used to access the common database. However, only one nation (code<br />

character set) is specified during <strong>DB2</strong> installation. This nation's character set is used as the<br />

default character set when a database is stored as EBCDIC or ASCII, and is also the default<br />

EBCDIC application encoding scheme. This nation will be referred to as the host nation.<br />

Minor conversion is only supported <strong>for</strong> the host nation's EBCDIC encoding scheme. All other<br />

nations will use major conversion.<br />

How does minor conversion work? The zSeries instruction set has always included a TR<br />

instruction that translates one byte <strong>for</strong> one byte, based on a 256-byte conversion table. A TRT<br />

instruction has also existed which could be used to test a string <strong>for</strong> certain one-byte<br />

characters. As long as a single byte Latin alphanumeric character can be represented in<br />

UTF-8 by a single byte, a TR instruction will suffice. <strong>DB2</strong> V8 has built-in translate tables <strong>for</strong><br />

most common single byte CCSIDs and if the TRT instruction is “successful”, <strong>DB2</strong> V8 can<br />

translate the string using a TR instruction. Such translations are called “minor conversions”.<br />

The presence of shift-in/shift-out characters in a mixed string will always cause the TRT<br />

instruction to fail. If the TRT fails, then <strong>DB2</strong> must invoke the z/<strong>OS</strong> Unicode conversion service.<br />

Such conversions in <strong>DB2</strong> are called “major conversions”. Whereas minor conversions cannot<br />

change the length of the string (in terms of bytes), major conversions may change the length,<br />

running the risk of possible truncation or padding when using fixed length columns or host<br />

variables.<br />

The per<strong>for</strong>mance of minor conversion is much better than the per<strong>for</strong>mance of major<br />

conversion, hence, minor conversion is one of the significant advantages of <strong>DB2</strong> V8<br />

compared to V7, and represents an advantage of UTF-8 over UTF-16. Even when <strong>DB2</strong> V8<br />

must resort to major conversion, V8 is still much faster than V7.<br />

9.1.3 <strong>DB2</strong> catalog changes<br />

The <strong>DB2</strong> catalog continues to grow with every release of <strong>DB2</strong>. In addition to the new catalog<br />

objects required to support the new functions in <strong>DB2</strong> (tables, columns, and so <strong>for</strong>th), V8<br />

introduces a number of other significant changes to the catalog:<br />

► Changing the definition of many existing columns to support long names<br />

► Converting the character columns in the catalog from EBCDIC to Unicode<br />

Refer to the <strong>DB2</strong> Release Planning Guide, SC18-7425, and Appendix A of the <strong>DB2</strong> SQL<br />

Reference, SC18-7426, <strong>for</strong> a complete list of changes to the <strong>DB2</strong> catalog.<br />

Table 9-1 shows how the <strong>DB2</strong> catalog has grown across its <strong>Version</strong>s.<br />

Table 9-1 <strong>DB2</strong> catalog growth<br />

<strong>DB2</strong> <strong>Version</strong> Table spaces Tables Indexes Columns Table check<br />

constraints<br />

V1 11 25 27 269 N/A<br />

V3 11 43 44 584 N/A<br />

V4 11 46 54 628 0<br />

V5 12 54 62 731 46<br />

V6 15 65 93 987 59<br />

V7 20 82 119 1206 105<br />

V8 22 84 132 1265 105<br />

344 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Summary of <strong>DB2</strong> Catalog changes<br />

The most important changes are:<br />

► Introduction of long names<br />

Long names (varchar 128) are supported <strong>for</strong> most of the objects. Catalogs are defined<br />

using Unicode, so if you have existing queries on the catalog, you will receive the results in<br />

a different ordering.<br />

► New tables<br />

– SYS<strong>IBM</strong>.IPLIST: Multiple IP addresses to one LOCATION can be defined <strong>for</strong> data<br />

sharing group.<br />

– SYS<strong>IBM</strong>.SYSSEQUENCEAUTH: Created in DSNDB06.SYSSEQ2. It records the<br />

privileges that are held by users over sequences.<br />

– SYS<strong>IBM</strong>.SYSOBDS: Created in DSNDB06.SYSALTER, it contains the version of a<br />

table space or an index space that is still needed <strong>for</strong> recovery.<br />

► New table spaces:<br />

– SYSEBCDC: EBCDIC table space, not used until NFM<br />

SYS<strong>IBM</strong>.SYSDUMMY1: has been moved from SYSSTR to SYSEBCDC<br />

– SYSALTER: New catalog table SYS<strong>IBM</strong>.SYSOBDS<br />

To store prior version in<strong>for</strong>mation of ALTERed tables<br />

– SYS<strong>IBM</strong>.IPLIST: Created in DSNDB06.SYSDDF<br />

Allows multiple IP addresses to be specified <strong>for</strong> a given LOCATION<br />

► Column changes<br />

– Existing binary columns will be ALTERed to be FOR BIT DATA columns to ensure they<br />

are handled properly during ENFM processing<br />

– Approximately 60 columns added to existing tables<br />

– Approximately 15 changes to values of existing columns<br />

– Approximately 45 column definitions have been changed<br />

– Approximately 10 changes to RI and table check constraints<br />

– Column length changes to support long names are only done during ENFM processing<br />

In summary, 17 catalog and 1 directory table space have been converted to Unicode, two<br />

tables have been dropped (SYSLINKS - No index data sets to be deleted,<br />

SYSPROCEDURES - VSAM data sets <strong>for</strong> Index DSNKCX01 can be deleted after ENFM),<br />

the table SYS<strong>IBM</strong>.SYSDUMMY1 has been moved from DSNDB06.SYSSTR to<br />

DSNDB06.SYSEDCBC, many columns have changed to VARCHAR to support long<br />

names, system-defined catalog indexes changed to NOT PADDED and 7 catalog and 1<br />

directory table space moved out of BP0.<br />

► Default changes<br />

The initial defaults <strong>for</strong> the - ALTER BUFFERPOOL command have changed:<br />

– DWQT: Specifies the buffer pool’s deferred write threshold as a default percentage of<br />

the total virtual buffer pool size. The initial default is decreased from 50% to 30%.<br />

– VDWQT: Specifies the virtual deferred write threshold <strong>for</strong> the virtual buffer pool. This<br />

parameter accepts two arguments. The first argument is a percentage of the total<br />

virtual buffer pool size. The default is decreased from 10% to 5%.<br />

The initial defaults <strong>for</strong> the ALTER GROUPBUFFERPOOL command have changed:<br />

Chapter 9. Installation and migration 345


– CLASST: Specifies the threshold at which class castout is started. It is expressed as a<br />

percentage of the number of data entries. The default is decreased from 10% to 5%.<br />

– GBPOOLT: Specifies the threshold at which the data in the group buffer pool is cast out<br />

to DASD. It is expressed as a percentage of the number of data entries in the group<br />

buffer pool. The default is decreased from 50% to 30%.<br />

– GBPCHKPT: Specifies the time interval in minutes between group buffer pool<br />

checkpoints. The default is lowered from 8 minutes to 4 minutes.<br />

9.2 IVP sample programs<br />

<strong>DB2</strong> continues to enhance the IVP samples in order to demonstrate the usage of new<br />

functions, to provide more features and enhance the usability of the samples themselves. In<br />

this section we are interested in the per<strong>for</strong>mance of multi-row fetch from the programs<br />

DSNTEP2, DSNTEP4 and DSNTIAUL. This function can be activated only in NFM. These<br />

programs are often used <strong>for</strong> testing during the migration to a new <strong>DB2</strong> release.<br />

Per<strong>for</strong>mance measurements<br />

In this section we describe how the tests were made, what kinds of scenarios were used, how<br />

we get the default, and how much improvement each program gets when using multi-row<br />

FETCH.<br />

Native measurements environment<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8 and V7 (non-data sharing)<br />

► z/<strong>OS</strong> Release 1.3.0<br />

► <strong>IBM</strong> z900 Series 2064 2-way processor<br />

► ESS 800 DASD with FICON channels<br />

Measurement scenarios<br />

► Non-partitioned table space, 10,000 row table, 26 columns, 1 index<br />

► Dynamic SQL with table space scan<br />

► Measured on both V7 and V8<br />

► Retrieve 5 columns, 10k rows<br />

► Retrieve 20 columns, 10k rows<br />

DSNTEP2 and DSNTEP4<br />

DSNTEP2 is a PLI program shipped with <strong>DB2</strong> to demonstrate the support <strong>for</strong> dynamic SQL.<br />

The DSNTEP2 has been enhanced <strong>for</strong>:<br />

► GET DIAGN<strong>OS</strong>TICS<br />

DSNTEP2 now uses GET DIAGN<strong>OS</strong>TICS to retrieve error in<strong>for</strong>mation.<br />

► Large SQL statement:<br />

The sample program DSNTEP2 can now handle SQL statements larger than 32 KB in<br />

size.<br />

► Greater than 18 character table/column names:<br />

The sample program DSNTEP2 has been modified to handle the longer table and column<br />

names.<br />

► New MAXERRORS value:<br />

A new MAXERRORS parameter has been added in DSNTEP2. It allows you to<br />

dynamically set the number of errors that DSNTEP2 will tolerate. In previous versions of<br />

<strong>DB2</strong>, DSNTEP2 stopped processing after it encountered 10 SQL errors. The<br />

346 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


MAXERRORS value can be modified during run time by coding the following functional<br />

comment in the SQL statements:<br />

SET MAXERRORS<br />

► SYSPRINT blocking in DSNTEP2:<br />

A change to SYSPRINT blocking in DSNTEP2 will speed up the rate in which DSNTEP2<br />

outputs its results. The blocking size was very small be<strong>for</strong>e, thus impacting the<br />

per<strong>for</strong>mance when processing large result sets. DSNSTEP2 can now also use the system<br />

default or user assigned JCL block size.<br />

A new sample program, DSNTEP4, has been added. It is like DSNTEP2, but it uses multi-row<br />

FETCH.<br />

In Figure 9-2 we show measurements of the new DSNTEP4 using different multi-row settings,<br />

and we compare them to DSNTEP2 (not using multi-row).<br />

Class 1 CPU Time (MSEC)<br />

Multi-row Fetch support of DSNTEP4<br />

(10,000 rows fetched / test)<br />

900<br />

600<br />

300<br />

0<br />

V7<br />

V8<br />

Ran with different number of<br />

rows in a FETCH call<br />

Figure 9-2 Multi-row fetch support of DSNTEP4<br />

As mentioned, <strong>DB2</strong> V8 ships DSNTEP2 and DSNTEP4. DSNTEP4 uses multi-row FETCH.<br />

You can specify a new parameter, MULT_FETCH, to specify the number of rows that are to be<br />

fetched at one time from the result table. The default fetch amount <strong>for</strong> DSNTEP4 is 100 rows,<br />

but you can specify from 1 to 32,676 rows. It can be coded as a functional comment<br />

statement as follows:<br />

//SYSIN DD *<br />

--#SET MULT_FETCH 5895<br />

SELECT * FROM DSN8810.EMP;<br />

V8<br />

mr=10 V8<br />

mr =100<br />

In Figure 9-3 we show a comparison of DSNTEP2 with DSNTEP4.<br />

V8 w/o MR : +5% to +7%<br />

V8 with MR : -5% to -35%<br />

5 columns 20 columns<br />

V8<br />

mr=1000<br />

V8<br />

mr=10000<br />

Chapter 9. Installation and migration 347


From these measurements we observe that DSNTEP2 under V8 uses 3% more CPU than<br />

DSNTEP2 under V7. DSNTEP4, by exploiting multi-row fetch, uses 10 to 30% less CPU<br />

depending on the number of rows specified.<br />

Class 1 CPU time (MSEC)<br />

1200<br />

800<br />

400<br />

0<br />

DSNTIAUL<br />

5 columns 20 columns<br />

DSNTIAUL is a sample assembler unload program. With <strong>DB2</strong> V8, it has been enhanced to:<br />

► Handle SQL statements up to 2 MB in size<br />

► Use multi-row FETCH<br />

You can specify an additional invocation parameter called “number of rows per fetch”. It<br />

indicates the number of rows per fetch that DSNTIAUL is to retrieve. You can specify a<br />

number from 1 to 32,767.<br />

In Figure 9-4 we show the impact of using multi-row fetch in V8, vs. single row fetch in V7, <strong>for</strong><br />

5 and <strong>for</strong> 20 columns. In this test, on average, the DSNTIAUL improvement is 40%.<br />

348 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Multi-row Fetch support of DSNTEP4<br />

(10,000 rows fetched / test)<br />

293<br />

937<br />

301<br />

955<br />

190<br />

846<br />

V7<br />

V8<br />

DSNTEP2<br />

V8<br />

DSNTEP2<br />

DSNTEP4<br />

Figure 9-3 Multi-row fetch support of DSNTEP4<br />

V8 DSNTEP4 :<br />

automatic exploitation of<br />

MR Fetch<br />

default MR=100 rows<br />

10% to 35% CPU time<br />

reduction vs. V7 DSNTEP2<br />

V8 DSNTEP2 :<br />

w/o MR exploitation<br />

within 3% CPU time<br />

regression vs. V7 DSNTEP2


Class 1 CPU time (MSEC)<br />

Multi-row Fetch support of DSNTIAUL<br />

(10,000 rows fetched / test)<br />

250<br />

200<br />

150<br />

100<br />

50<br />

0<br />

V7<br />

Figure 9-4 Multi-row fetch support of DSNTIAUL<br />

As shown on Figure 9-4, the default value <strong>for</strong> DSNTIAUL retrieves 100 rows per fetch. When<br />

you retrieve 1000 or 10000 rows, the CPU time stays almost the same.<br />

If you want to change the number of rows, the parameter can be specified together with the<br />

SQL parameter, as shown in Example 9-1.<br />

Example 9-1 DSNTIAUL with multi-row parameter<br />

//SYSTSIN DD *<br />

DSN SYSTEM(DSN)<br />

RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB81) PARMS('SQL,250') -<br />

LIB(’DSN810.RUNLIB.LOAD’)<br />

...<br />

//SYSIN DD *<br />

LOCK TABLE DSN8810.PROJ IN SHARE MODE;<br />

SELECT * FROM DSN8810.PROJ;<br />

V8<br />

Runs with different number of<br />

rows in a FETCH call<br />

V8<br />

mr = 10 V8<br />

mr = 100<br />

V8 w/o MR : +20%<br />

V8 with MR : -30% to -50%<br />

V8<br />

mr=1000 V8<br />

mr=10000<br />

5 columns<br />

20 columns<br />

In Figure 9-5, we compare the per<strong>for</strong>mance of DSNTIAUL running under V7 and V8 in terms<br />

of CPU. Elapsed times are very similar.<br />

Chapter 9. Installation and migration 349


Class 1 CPU time (MSEC)<br />

200<br />

150<br />

100<br />

50<br />

9.3 Installation<br />

0<br />

5 columns 20 columns<br />

Figure 9-5 Multi-row support of DSNTIAUL comparing V7 with V8<br />

<strong>DB2</strong> V8 brings major changes to the installation and migration processes. With a newly<br />

installed <strong>DB2</strong> V8 subsystem, you can immediately take advantage of all the new functions in<br />

V8. For more in<strong>for</strong>mation about the changes, refer to the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

Installation Guide, GC18-7418, and the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Data Sharing Planning<br />

and Administration Guide, SC18-7417.<br />

The key changes to the installation and migration processes are:<br />

► Valid CCSIDs must be defined <strong>for</strong> ASCII, EBCDIC, and Unicode.<br />

► You must supply your own tailored DSNHDECP module. You can no longer start <strong>DB2</strong> with<br />

the <strong>DB2</strong>-supplied DSNHDECP.<br />

► DSNHMCID is a new data-only module in V8. It is required by <strong>DB2</strong> facilities that run in<br />

<strong>DB2</strong> allied address spaces, such as attaches and utilities.<br />

► Buffer pools of sizes 4 KB, 8 KB, 16 KB, and 32 KB must be defined.<br />

► Only WLM-established stored procedures can be defined.<br />

Installation CLIST changes<br />

In this section we summarize the changes to installation CLISTs.<br />

► Installation panels changes<br />

350 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Multi-row support of DSNTIAUL<br />

(10,000 rows fetched / test)<br />

V7<br />

140<br />

173<br />

V8<br />

68<br />

120<br />

V8 DSNTIAUL<br />

automatic exploitation of<br />

Multi-row Fetch<br />

default MR=100 rows<br />

30% to 50% CPU time<br />

reduction compared to V7


Table 9-2 shows the most important installation panels changes. For a description of all of the<br />

installation panels and their contents, refer to the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation<br />

Guide, SC18-7418.<br />

Table 9-2 Clist changes in the installation panels<br />

Panel Id Panel parameter <strong>DB2</strong> V7 default <strong>DB2</strong> V8 default<br />

DSNTIP7 User LOB value storage 2048 (kb) 10240 (kb)<br />

DSNTPIE Max users 70 200<br />

DSNTIPE Max remote active 64 200<br />

DSNTIPE Max remote connected 64 10000<br />

DSNTIPE Max TSO connect 40 50<br />

DSNTIPE Max batch connect 20 50<br />

DSNTIPF Describe <strong>for</strong> static NO YES<br />

DSNTIPN SMF statistics YES (1,3,4,5) YES (1,3,4,5,6)<br />

DSNTIP8 Cache dynamic SQL NO YES<br />

DSNTIPP Plan auth cache 1024 bytes 3072 bytes<br />

DSNTIPP Package auth cache NO YES<br />

DSNTIPP Routine auth cache 32 KB 100 KB<br />

DSNTIPL Log apply storage 0 100 MB<br />

DSNTIPL Checkpoint frequency 50 000 records 500 000 records<br />

DSNTIPA Block size (archive log) 28672 24576<br />

DSNTIPR DDF threads ACTIVE INACTIVE<br />

DSBTIPR IDLE thread time-out 0 120<br />

DSNTIPR Extended security NO YES<br />

DSBTIP5 TCP/IP KEEPALIVE ENABLE 120 (seconds)<br />

DSNTPIC Max open data sets 3000 10000<br />

DSNTIPC EDMPOOL Storage Size 7312 KB 32768 KB<br />

DSNTIPC EDM Statement Cache n/a 102400 KB<br />

DSNTIPC EDM DBD cache n/a 102400 KB<br />

The <strong>DB2</strong> V8 Installation CLIST generates the job DSNTIJTC, which must also be run. This<br />

job executes the CATMAINT utility. In previous versions of <strong>DB2</strong> you only ran the<br />

CATMAINT utility during migration, in order to update the <strong>DB2</strong> catalog <strong>for</strong> the new version.<br />

With <strong>DB2</strong> V8, job DSNTIJTC must be run also <strong>for</strong> new installations in order to update the<br />

<strong>DB2</strong> catalog table spaces which are not moving to Unicode, keeping the default EBCDIC<br />

encoding schemes from DSNHDECP.<br />

The CATMAINT execution in this case will be very quick. For more in<strong>for</strong>mation, refer to<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide, GC18-7418.<br />

► Cache dynamic SQL now enabled by default<br />

This option specifies whether to cache prepared dynamic SQL statements <strong>for</strong> later use by<br />

eligible application processes. These prepared statements are cached in the EDM<br />

Chapter 9. Installation and migration 351


dynamic statement cache. If activated, consider this usage when calculating your EDM<br />

pool size. See “Calculating the EDM pool space <strong>for</strong> the prepared-statement cache” of the<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide, GC18-7418, <strong>for</strong> details about estimating<br />

storage. If you specify YES, you must specify YES <strong>for</strong> USE PROTECTION on panel<br />

DSNTIPP.<br />

► Fast log apply enabled by default<br />

LOG APPLY STORAGE is an option on panel DSNTIPBA. The acceptable values are: 0 to<br />

100 MB. The macro is DSN6SYSP LOGAPSTG.<br />

The value in this field represents the maximum ssnmDBM1 storage that can be used by<br />

the fast log apply process. The default value is 0 MB, which means that the fast log apply<br />

process is disabled except during <strong>DB2</strong> restart. During <strong>DB2</strong> restart, the fast log apply<br />

process is always enabled and a value of 100 MB is assumed.<br />

The value you specify, if not equal to zero, which disables the function, is used <strong>for</strong><br />

RECOVER utility executions. Since RECOVER jobs are likely to run in parallel, specify<br />

100 MB so you can also use 10 MB of log apply storage <strong>for</strong> each concurrent RECOVER<br />

job (up to 10) that you want to have faster log apply processing.<br />

FLA is also utilized by the new RESTORE utility. In this case the default assumed by <strong>DB2</strong><br />

will be 500 MB, unless disabled by the value zero in LOG APPLY STORAGE.<br />

► The data set size panel DSNTIP7 has four new fields which change the way <strong>DB2</strong><br />

manages VSAM data sets:<br />

– Vary DS control interval (2 fields were changed)<br />

– Optimize extent sizing<br />

– Table space allocation and index space allocation<br />

► The Per<strong>for</strong>mance and Optimization panel, DSNTIP8, provides the defaults <strong>for</strong> two new<br />

special registers which have been created to support Materialized Query Tables:<br />

– CURRENT REFRESH AGE<br />

Specifies the default value to be used <strong>for</strong> the CURRENT REFRESH AGE special<br />

register when no value is explicitly set using the SQL statement SET CURRENT<br />

REFRESH AGE. The values can be 0 or ANY. The default of 0 disables query rewrite<br />

using materialized query tables.<br />

– CURRENT MAINT TYPES<br />

Specifies the default value to be used <strong>for</strong> the CURRENT MAINTAINED TABLE TYPES<br />

FOR OPTIMIZATION special register when no value is explicitly set using the SQL<br />

statement SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION.<br />

Acceptable values are NONE, SYSTEM, USER, and ALL. The default (SYSTEM)<br />

allows query rewrite using system-maintained materialized query tables when the<br />

CURRENT REFRESH AGE is set to ANY. Alternatively, specifying USER allows query<br />

rewrite using user-maintained materialized query tables when CURRENT REFRESH<br />

AGE is set to ANY, and specifying ALL means query rewrite using both<br />

system-maintained and user-maintained materialized query tables.<br />

For materialized query tables refer to 3.2, “Materialized query table” on page 39.<br />

There are several other changes including:<br />

► Checkpoint frequency increased from 50,000 to 500,000 log records<br />

► Archive log block size reduced from 28672 to 24576 (<strong>for</strong> better DASD occupancy)<br />

► Remove hiperpool definitions and VPTYPE settings. They are no longer supported in V8<br />

► DDF panels have new terminology<br />

352 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


9.4 Migration<br />

– Use “Inactive DBAT” instead of “Type 1 Inactive Thread”<br />

– Use “Inactive Connection” instead of “Type 2 Inactive Thread”<br />

► CCSIDs must be specified <strong>for</strong> EBCDIC, ASCII and Unicode even when you do not use<br />

those encoding schemas in your application<br />

► The DSNHDECP module must be defined by the user. It is not defined by <strong>DB2</strong> by default.<br />

► Buffer pools BP8K0, BP16K0, and BP32K must be defined in advance since some catalog<br />

table spaces use 8 KB, 16 KB and 32 KB pages.<br />

► For data sharing groups: GBP8K0, GBP16K0 and GBP32K also need to be allocated.<br />

► The location name must be specified, even if DDF is not used. See PTF UQ90701 <strong>for</strong><br />

APAR PQ91009.<br />

Migration is the process of converting an existing <strong>DB2</strong> subsystem, user data, and catalog<br />

data to a new version. This process has changed from <strong>DB2</strong> V7 to V8 in order to minimize the<br />

possible impact of regression and fallback incompatibilities. For more in<strong>for</strong>mation refer to <strong>DB2</strong><br />

<strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide, GC18-7418.<br />

The migration to <strong>DB2</strong> V8 is only allowed from V7. As mentioned, a <strong>DB2</strong> V8 subsystem will<br />

migrate going through three different modes:<br />

► Compatibility mode (CM)<br />

► Enabling-new-function mode (ENFM)<br />

► New-function mode (NFM)<br />

We are interested in the per<strong>for</strong>mance of the catalog migration, how long the migration will<br />

take, and how big the catalog will be. In this section we are using general in<strong>for</strong>mation from<br />

several real migrations to illustrate the catalog migration. After reading this section you will be<br />

able to determine how long it is going to take to migrate your catalog and how large it will be<br />

after the migration.<br />

During the migration process, you must go through CM and ENFM, be<strong>for</strong>e reaching the NFM.<br />

When in CM, your Catalog and Directory have already successfully been converted to V8,<br />

new columns have been added to existing tables, new indexes and table spaces have been<br />

created and so on.<br />

However, there are two other major changes to the <strong>DB2</strong> catalog necessary to make most of<br />

the new functions provided with <strong>DB2</strong> V8 possible. These changes are:<br />

► Change existing catalog columns so that they can store long names.<br />

► Convert the catalog to Unicode.<br />

In CM, these two changes have not been done. Furthermore, the only new functions available<br />

<strong>for</strong> use in this mode of operation are those which allow fallback to V7.<br />

In ENFM, you are in the process of converting your Catalog table spaces so that after<br />

completion of the conversion, they now accept long names and exist in the Unicode encoding<br />

scheme. Catalog conversion is per<strong>for</strong>med by running job DSNTIJNE. You can spread<br />

conversion of your catalog table across several maintenance intervals. Use job DSNTIJNH to<br />

direct DSNTIJNE to halt after conversion of the current table space has completed. To<br />

resume, simply rerun DSNTIJNE from the top. It will automatically locate the next table space<br />

to be converted. The process of conversion is not disruptive, that is, you can continue<br />

operation while being in ENFM. Once you have migrated all table spaces of your <strong>DB2</strong> catalog<br />

to Unicode, your <strong>DB2</strong> subsystem will operate in NFM once you run the DSNTIJNF to indicate<br />

Chapter 9. Installation and migration 353


that everything is ready. This step can be helpful <strong>for</strong> instance in making sure that all your<br />

members of a data sharing group, or all subsystems DRDA related, have been migrated. Now<br />

all new functions which have been introduced with <strong>DB2</strong> V8 are available.<br />

9.4.1 Migration plan recommendations<br />

It is important to have an effective operational test environment and application regression<br />

workloads. The test environment should be a meaningful representation and closely mirror<br />

production characteristics, so that regression and stress tests would flush out any<br />

implementation issues. Unless several environments are available, it is not effective to run <strong>for</strong><br />

an extended period with different code and function levels across “test” and “production”<br />

environments. Application changes, quick fixes and <strong>DB2</strong> APARs (HIPERs, PEs, corrective)<br />

have to be tested and promoted to production. Observe a clear separation between toleration<br />

and exploitation of features in the new release.<br />

The exploitation phase should follow after a toleration phase where the new release has been<br />

running stable in production <strong>for</strong> a reasonable period (typically at least to complete one<br />

processing month cycle) and there is little chance of a need to fallback to the previous version<br />

of <strong>DB2</strong>. The exploitation project will focus on a prioritized list of new features offering business<br />

value. During the toleration period you will run with release N-1 of the <strong>DB2</strong> Precompiler to<br />

prevent new SQL features being used or you run the V8 Precompiler, specifying (or implying)<br />

NEWFUN = NO.<br />

Keep in mind the distinction between coexistence, referred to data sharing, and compatibility<br />

mode. The period of data sharing coexistence should be kept reasonably short to reduce the<br />

possibility of running into problems which are unique to coexistence.<br />

Note: To see the <strong>DB2</strong> mode you just need to execute a - DIS GROUP and look at the<br />

MODE (C*** BEGIN DISPLAY OF GROUP(........) GROUP LEVEL(...)<br />

MODE (E)<br />

MODE(N) )<br />

C is compatibility mode, E is enabling-new-function mode, N is new-function mode.<br />

Recommendations<br />

This is a set of general recommendations:<br />

1. Be<strong>for</strong>e the catalog migration to CM it is recommended that you clean up your catalog. Run<br />

MODIFY on all table spaces to clean up the SYSCOPY, SYSLGRNX entries. Also FREE<br />

the old versions of packages that are not used any more. You can also REORG the<br />

catalog in V7 to compact it.<br />

2. Migrate a V7 test data sharing group to V8 CM and hold. If you want to roll in the new<br />

release member by member, migrate the first two members, test, then roll through the<br />

remaining members quickly.<br />

3. After (2) has been proven <strong>for</strong> an extended period, migrate the production data sharing<br />

group to V8 compatibility mode. Migrate the first two members, wait, then roll through the<br />

remaining members quickly. We recommend a reorg on the catalog while in CM and<br />

be<strong>for</strong>e going to NFM. Online Reorg of the Catalog is available in CM.<br />

4. Run through a complete monthly processing cycle in production to flush out<br />

implementation or egression issues (can fallback or go <strong>for</strong>ward again if necessary).<br />

5. After (4) is successful, start to migrate the V8 test data sharing group to V8 NFM.<br />

354 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


6. After (5) is successful, start to migrate V8 production data sharing group to V8 NFM.<br />

For your development system, this is another set of recommendations:<br />

1. Migrate the development system to CM and run that way until you are satisfied with V8 on<br />

your development system,<br />

2. Run DSNTIJNE on your development system, but not DSNTIJNF. This will convert your<br />

development system catalog to support NFM, but will leave your development system in<br />

ENFM, thus not allowing any application developer to use any new function that cannot be<br />

deployed on your production system since it is still in CM.<br />

3. Migrate the corresponding production system to CM and run that way until you are<br />

satisfied with V8 on your production system.<br />

4. Run DSNTIJNE on your production system to prepare it <strong>for</strong> NFM.<br />

5. Run DSNTIJNF on both your production and development systems at roughly the same<br />

time.<br />

Note that steps 2 and 3 can be in the opposite order.<br />

9.4.2 Per<strong>for</strong>mance measurements<br />

Be<strong>for</strong>e we start showing the measurements, we take a look at a table that shows us what kind<br />

of data is going to be migrated. Note that we did a clean up in our catalog be<strong>for</strong>e the<br />

migration. If you have never done it, run a MODIFY and a REORG of your catalog after<br />

migrating to the CM and be<strong>for</strong>e going to ENFM.<br />

<strong>DB2</strong> V7 catalog<br />

In Table 9-3 you can see the most important tables and the number of rows from a <strong>DB2</strong> V7<br />

catalog.<br />

Table 9-3 Row counts <strong>for</strong> catalog tables - 698 MB catalog in V7<br />

Table Number of<br />

rows<br />

Table Number of<br />

rows Table<br />

Number of<br />

rows<br />

SYSCOPY 19032 LUMODES 0 SYSSTMT 225846<br />

SYSCOLUMNS 78948 LUNAMES 1 SYSCOLDIST 12235<br />

SYSFIELDS 0 MODESELECT 0 SYSCOLDISTSTATS 2822<br />

SYSFOREIGNKEYS 130 USERNAMES 0 SYSCOLSTATS 64534<br />

SYSINDEXES 6019 SYSRESAUTH 56 SYSINDEXSTATS 1397<br />

SYSINDEXPART 7382 SYSSTOGROUP 35 SYSTABSTATS 1397<br />

SYSKEYS 27097 SYSVOLUMES 35 SYSSTRINGS 752<br />

SYSRELS 65 SYSPACKAGE 8713 SYSCHECKS 107<br />

SYSSYNONYMS 32 SYSPACKAUTH 4412 SYSCHECKDEP 109<br />

SYSTABAUTH 49018 SYSPACKDEP 93944 SYSUSERAUTH 1375<br />

SYSTABLEPART 5368 SYSPROCEDURES 0 SYSVIEWDEP 173<br />

SYSTABLES 4217 SYSPACKLIST 232 SYSVIEWS 131<br />

SYSTABLESPACE 4005 SYSPACKSTMT 273762<br />

Chapter 9. Installation and migration 355


Table Number of<br />

rows<br />

SYSDATABASE 750 SYSPLSYSTEM 14<br />

SYSDBAUTH 756 SYSDBRM 6519<br />

IPNAMES 0 SYSPLAN 5515<br />

LOCATIONS 0 SYSPLANAUTH 6969<br />

LULIST 0 SYSPLANDEP 43949<br />

CATMAINT per<strong>for</strong>mance measurements show very similar CPU and elapsed times between<br />

data sharing and non-data sharing environments. This is true when migrating from V5 to V6,<br />

V6 to V7, V5 to V7 and V7 to V8 CM.<br />

<strong>DB2</strong> V8 catalog<br />

The in<strong>for</strong>mation related to the per<strong>for</strong>mance migration to the <strong>DB2</strong> V8 catalog is listed in<br />

Table 9-4, We show the per<strong>for</strong>mance of the utility Catmaint, and also job DSNTIJNE, Reorg of<br />

the catalog. We also describe how much larger they can grow. The statistics refer to three<br />

different case studies from customer scenarios.<br />

Table 9-4 CATMAINT statistics in non-data sharing<br />

V 7 to V 8 CM<br />

CATMAINT<br />

UPDATE<br />

V8 CM to V8<br />

NFM<br />

DSNTIJNE<br />

<strong>DB2</strong> Catalog<br />

Increase V8 NFM<br />

compared with<br />

V7<br />

Company 1<br />

(28.3 GB)<br />

The migration from V8 CM to V8 NFM does not use CATMAINT. When you migrate V7 to V8<br />

CM, the size of the catalog does not change.<br />

Dominant element in the catalog size<br />

Just to illustrate the size considerations with one example, we refer to a real life customer<br />

scenario of a bank with a production data sharing group holding 19 members. Their <strong>DB2</strong> V7<br />

catalog size is 3 MB and the directory is 7.3 MB. In this case the directory is 142% bigger<br />

than the catalog with the largest VSAM file from the directory being SPT01 with 3 MB (the<br />

same size of the catalog) because of the huge number of packages. This is a good case <strong>for</strong><br />

356 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Table Number of<br />

rows Table<br />

Company 2<br />

(15.2 GB)<br />

Company 3<br />

(698 MB)<br />

255 sec. 67 sec. 6 sec. CPU<br />

692 sec. 255 sec. 27 sec.<br />

55 min. 5 sec. 20 min. 53 sec. 2 min. 6 sec. CPU<br />

2 hrs 17 min.<br />

40 sec<br />

1 hr 28 min.<br />

48 sec<br />

8 min. 3 sec.<br />

Number of<br />

rows<br />

Elapsed time<br />

Elapsed time<br />

0.46% 1.03% 8% Increase in table<br />

size<br />

2.29% 8.21% 9%<br />

Increase in index<br />

size<br />

Note: The size of the catalog does not increase when you migrate from V7 to V8 CM. The<br />

size of the catalog just increases marginally when you are migrating from V8 CM to V8<br />

NFM.


spring cleaning of the directory: Be<strong>for</strong>e migrating it would be very appropriate to free all the<br />

packages that are not being used, reduce SPT01, and migrate faster.<br />

SPT01 is used to store skeleton package tables (SKPTs). These tables store the access<br />

paths to <strong>DB2</strong> data. When a package is executed, <strong>DB2</strong> uses this in<strong>for</strong>mation to access the<br />

data it needs. Because a single SKPT can be longer than the maximum record length that<br />

can be used in <strong>DB2</strong>, SKPTs are stored as a sequence of SKPT sections. The skeleton<br />

package table parent record (SPTR) contains as much of the SKPT section as the record can<br />

fit. The entire SKPT section is stored in this record if it fits; if it does not fit, it is stored in one or<br />

more SPTRs. Each SPTR is identified by a unique section and sequence number.<br />

How long will it take to migrate?<br />

Based on the measurements, you can estimate the migration time first to CM, and then to<br />

NFM.<br />

When migrating to V8 CM, if your catalog is less than 30 GB, your per<strong>for</strong>mance can be<br />

predicted using Figure 9-6. Assuming that the catalog has no major anomalies, the most<br />

important structure to influence the duration of CATMAINT is SYSDBASE, because<br />

CATMAINT does a scan on that structure.<br />

The elapsed time migrating to V8 is certainly longer than it was when migrating to V7 because<br />

<strong>DB2</strong> has to prepare the data <strong>for</strong> later conversion to Unicode at ENFM time. This is the step<br />

that involves a scan of SYSDBASE. <strong>DB2</strong> is not updating every page, as was done in the past,<br />

but it still scans the SYSDBASE.<br />

Estimation based on this graph is only valid <strong>for</strong> a particular CPU and DASD model upon which<br />

this measurement was done.<br />

Seconds<br />

800<br />

700<br />

600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

Figure 9-6 Migration times to CM<br />

<strong>DB2</strong> Catalog Migration V7 - V8 CM<br />

0 5 10 15<br />

Gigabytes<br />

20 25 30<br />

CPU time<br />

Elapsed time<br />

Note: The measurements in data sharing showed no difference with non-data sharing and<br />

in the case of migrating from V7 to V8 CM, data sharing was a little bit better in CPU.<br />

Chapter 9. Installation and migration 357


In Figure 9-7 we describe the per<strong>for</strong>mance of the migration from V8 CM to V8 NFM, with that<br />

you can find out how long it will take you to migrate your catalog from CM to NFM. You just<br />

need to find the size of your catalog.<br />

Time in Seconds<br />

9000<br />

8000<br />

7000<br />

6000<br />

5000<br />

4000<br />

3000<br />

2000<br />

1000<br />

0<br />

Figure 9-7 Migration from CM to NFM<br />

Note: The major component of job DSNTIJNE is the Online Reorg of SPT01 and the 17<br />

catalog table spaces.<br />

Job DSNTIJNE per<strong>for</strong>ms several functions:<br />

► Saves the current RBA or LRSN in the BSDS<br />

► Changes types and lengths of existing catalog columns<br />

► Converts catalog data to Unicode<br />

► Changes buffer pools <strong>for</strong> several catalog table spaces<br />

► Changes catalog indexes with varying length columns to NOT PADDED<br />

► Changes page size of several catalog table spaces<br />

This job can be run at any time. To stop it, you cannot use a - TERM UTIL command, you<br />

need to use job DSNTIJNH. When you want to resume running DSNTIJNE, you do not need<br />

to make any change, just run the job again. Just execute the steps as defined and you can<br />

stop and start it as needed. Do not take long though to migrate your catalog, you will use the<br />

new functions only after completing migration and you do not want to keep your <strong>DB2</strong><br />

subsystems not aligned <strong>for</strong> too long.<br />

358 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Migration V8 CM to V8 NFM<br />

CPU Time Elapsed Time<br />

0 5 10 15 20 25 30<br />

Gigabytes Catalog Size


Summary and recommendations<br />

Migration from V7 to V8 CM takes from 0.2 to 10 minutes depending on the size of the catalog<br />

and directory (medium to large). Be<strong>for</strong>e the catalog migration, it is recommended that you<br />

clean up your catalog doing a MODIFY on all table spaces: The result will be a cleanup on the<br />

SYSCOPY.SYSLGRNX entries. It is also useful to free the old version of packages that are<br />

not being used any more.<br />

Note: When you execute a MODIFY, do not <strong>for</strong>get to take a look at the tables that will be in<br />

copy pending, because your application might not be expecting the <strong>DB2</strong> return code.<br />

Reorg Catalog and Directory be<strong>for</strong>e migrating to NFM.<br />

Migration from V8 CM to V8 NFM takes from 0.1 to 2 hours depending on the size of the<br />

catalog and directory (medium to large). The longest step is the catalog reorg DSNTIJNE,<br />

and the execution of that job can be divided.<br />

The size of the catalog, both data and index, has been observed to increase between 1% and<br />

10%.<br />

Online REORG SHRLEVEL REFERENCE of SPT01 and 17 catalog tables is the most<br />

time-consuming component. A very rough Rule-of-Thumb on estimating the time <strong>for</strong> a<br />

medium to large catalog and directory in non-data sharing is:<br />

6 min. + 3 to 7 min. per GB of SPT01, SYSPKAGE, SYSDBASE, etc.<br />

The time is heavily dependent on the DASD and channel model used.<br />

Allocate larger work files <strong>for</strong> online REORG of large tables such as SYSDBASE, SYSPKAGE.<br />

Allocate work files on separate DASDs, LCUs <strong>for</strong> online REORG of tables with parallel<br />

sort/build indexes such as SYSHIST, SYSPKAGE, SYSSTATS, and SPT01.<br />

9.5 Catalog consistency query DSNTESQ<br />

The DSNTESQ sample job is provided to <strong>DB2</strong> users so that they can check the consistency<br />

of their <strong>DB2</strong> catalogs. This sample job consists of DDL, INSERT and 65 queries to verify the<br />

integrity of the catalogs and directories. The SQL can be run from SPUFI or DSNTEP2 and<br />

contains DDL which creates copies of the catalog using segmented table spaces. In some<br />

cases, the queries in DSNTESQ run faster when run on copies of the catalog instead of the<br />

actual catalog because the copies have additional indexes.<br />

Some of these catalog consistency queries can run <strong>for</strong> extended periods of time on<br />

subsystems with large amounts of catalog data. In order to improve the per<strong>for</strong>mance of most<br />

of these DSNTESQ catalog consistency queries, they were rewritten to use non correlated<br />

subqueries on table columns that are in index keys.<br />

In the past, some queries in DSNTESQ have had very poor per<strong>for</strong>mance. In <strong>DB2</strong> V6, a<br />

customer introduced a subset of queries rewritten from DSNTESQ which per<strong>for</strong>med very well<br />

against <strong>IBM</strong> supplied DSNTESQ queries. In <strong>DB2</strong> V8, some queries from DSNTESQ were<br />

rewritten <strong>for</strong> per<strong>for</strong>mance and retrofitted to <strong>DB2</strong> V7. On Table 9-7 we have an example of<br />

retrofitted queries followed by other rewritten queries.<br />

Table 9-5 Queries 5 and 18 rewritten <strong>for</strong> better per<strong>for</strong>mance<br />

Query (<strong>DB2</strong> V8 - New Function Mode) Old (V8 NFM) New (V8 NFM)<br />

Chapter 9. Installation and migration 359


Old - Query 5 New - Query 5 CPU<br />

(sec.)<br />

SELECT DBNAME, NAME<br />

FROM<br />

SYS<strong>IBM</strong>.SYSTABLESPAC<br />

E TS WHERE NTABLES<br />

<br />

(SELECT COUNT(*)<br />

FROM<br />

SYS<strong>IBM</strong>.SYSTABLES TB<br />

WHERE TYPE IN ('T',<br />

'X','M')<br />

AND TB.DBNAME =<br />

TS.DBNAME AND<br />

TB.TSNAME = TS.NAME<br />

AND TS.NAME <br />

'SYSDEFLT');<br />

Old - Query 18<br />

(<strong>DB2</strong> V8 NF Mode)<br />

SELECT TBCREATOR,<br />

TBNAME, NAME FROM<br />

SYS<strong>IBM</strong>.SYSCOLUMNS<br />

CL WHERE FLDPROC =<br />

'Y' AND NOT EXISTS<br />

(SELECT *<br />

FROM<br />

SYS<strong>IBM</strong>.SYSFIELDS FL !<br />

WHERE FL.TBCREATOR<br />

= CL.TBCREATOR<br />

AND FL.TBNAME =<br />

CL.TBNAME AND<br />

FL.NAME = CL.NAME<br />

AND FL.COLNO =<br />

CL.COLNO);<br />

Table 9-6 shows the old and new text of Query 31.<br />

Table 9-6 Catalog consistency - Query 31<br />

Table 9-7 shows the old and new text of Query 33.<br />

360 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

SELECT DBNAME,<br />

NAME<br />

FROM<br />

SYS<strong>IBM</strong>.SYSTABLESPA<br />

CE TS WHERE<br />

NTABLES¨ =<br />

(SELECT COUNT(*)<br />

FROM<br />

SYS<strong>IBM</strong>.SYSTABLES<br />

TB WHERE TYPE IN<br />

('T', 'X')<br />

AND TB.DBNAME =<br />

TS.DBNAME AND<br />

TB.TSNAME =<br />

TS.NAME<br />

AND TB.DBID =<br />

TS.DBID<br />

AND TS.NAME =<br />

'SYSDEFLT');<br />

New - Query 18<br />

(<strong>DB2</strong> V8 NF Mode)<br />

SELECT<br />

CL.TBCREATOR,<br />

CL.TBNAME, CL.NAME<br />

FROM<br />

SYS<strong>IBM</strong>.SYSCOLUMN<br />

S CL LEFT OUTER JOIN<br />

SYS<strong>IBM</strong>.SYSFIELDS FL<br />

ON FL.TBCREATOR =<br />

CL.TBCREATOR<br />

AND FL.TBNAME =<br />

CL.TBNAME AND<br />

FL.NAME = CL.NAME<br />

AND FL.COLNO =<br />

CL.COLNO<br />

WHERE CL.FLDPROC<br />

= 'Y'<br />

AND FL.TBCREATOR IS<br />

NULL;<br />

Elapse<br />

d time<br />

(sec.)<br />

CPU<br />

(sec.)<br />

Elapse<br />

d time<br />

(sec.)<br />

1926 2104 7.7506 10.366<br />

CPU<br />

(sec.)<br />

Old - Query 31 New - Query 31<br />

SELECT NAME<br />

FROM SYS<strong>IBM</strong>.SYSPLAN PL<br />

WHERE PLENTRIES = 0<br />

AND NOT EXISTS<br />

(SELECT * FROM SYS<strong>IBM</strong>.SYSDBRM<br />

WHERE PLNAME = PL.NAME);<br />

Elapse<br />

d time<br />

(sec.)<br />

CPU<br />

(sec.)<br />

Elapse<br />

d time<br />

(sec.)<br />

0.3745 0.4046 0.37382 0.3924<br />

SELECT NAME<br />

FROM SYS<strong>IBM</strong>.SYSPLAN<br />

WHERE PLENTRIES = 0<br />

AND NAME NOT IN<br />

(SELECT PLNAME FROM<br />

SYS<strong>IBM</strong>.SYSDBRM);


Table 9-7 Catalog consistency - Query 33<br />

Old - Query 33 New - Query 33<br />

SELECT NAME<br />

FROM SYS<strong>IBM</strong>.SYSPLAN PL<br />

WHERE PLENTRIES = 0<br />

AND NOT EXISTS<br />

(SELECT * FROM SYS<strong>IBM</strong>.SYSSTMT<br />

WHERE PLNAME = PL.NAME);<br />

As shown in Figure 9-8, the per<strong>for</strong>mance of the two queries has improved noticeably.<br />

Query<br />

31<br />

Old DSNTESQ<br />

CPU<br />

38 min<br />

53 sec<br />

E.T<br />

10 hr<br />

32 min<br />

36 sec<br />

Figure 9-8 Catalog consistency queries - Measurement results<br />

The old consistency Query 35 and Query 36 have merged into a new query, as shown in<br />

Table 9-8.<br />

Table 9-8 Catalog consistency - Queries 35 and 36 from SDSNSAMP.<br />

SELECT NAME<br />

FROM SYS<strong>IBM</strong>.SYSPLAN<br />

WHERE PLENTRIES = 0<br />

AND NAME NOT IN<br />

(SELECT PLNAME FROM SYS<strong>IBM</strong>.SYSSTMT);<br />

Old Query 35 Old Query 36 New Query 35 and 36<br />

SELECT PLNAME, NAME<br />

FROM SYS<strong>IBM</strong>.SYSDBRM DR<br />

WHERE NOT EXISTS<br />

(SELECT *<br />

FROM SYS<strong>IBM</strong>.SYSSTMT ST<br />

WHERE ST.PLNAME =<br />

DR.PLNAME<br />

AND ST.NAME = DR.NAME);<br />

V8 Compatibility Mode<br />

New DSNTESQ<br />

CPU<br />

1.2<br />

sec<br />

E.T<br />

17 sec<br />

CPU<br />

25 min<br />

35 sec<br />

SELECT DISTINCT PLNAME,<br />

NAME<br />

FROM SYS<strong>IBM</strong>.SYSSTMT ST<br />

WHERE NOT EXISTS<br />

(SELECT *<br />

FROM SYS<strong>IBM</strong>.SYSDBRM DR<br />

WHERE DR.PLNAME =<br />

ST.PLNAME<br />

AND DR.NAME =<br />

ST.NAME);<br />

V8 New Function Mode<br />

Old DSNTESQ<br />

10 hr<br />

2 min<br />

39 sec<br />

CPU<br />

14 sec<br />

SELECT DBRM.PLNAME,<br />

DBRM.NAME,<br />

STMT.PL NAME, STMT.NAME<br />

FROM SYS<strong>IBM</strong>.SYSDBRM<br />

DBRM FULL OUTER JOIN<br />

SYS<strong>IBM</strong>.SYSSTMT STMT<br />

ON DBRM.PLNAME =<br />

STMT.PLNAME<br />

AND DBRM.NAME =<br />

STMT.NAME<br />

WHERE (STMT.NAME IS<br />

NULL OR DBRM.NAME IS<br />

NULL)<br />

GROUP BY DBRM.PLNAME,<br />

DBRM.NAME,<br />

STMT.PLNAME, STMT.NAME;<br />

The per<strong>for</strong>mance of these queries has improved quite a lot as shown in Figure 9-9.<br />

23 sec<br />

33 49 min 9 hr 3.5 17.5 42 min 10 hr 18 sec 25 sec<br />

2 sec 58 min sec sec 12 sec 3 min<br />

55 sec<br />

37 sec<br />

E.T<br />

New DSNTESQ<br />

E.T<br />

Chapter 9. Installation and migration 361


Query<br />

35<br />

36<br />

Old DSNTESQ<br />

CPU<br />

1 hr<br />

1 min 39<br />

sec<br />

1 hr<br />

5 min<br />

38 sec<br />

V8 Compatibility Mode<br />

E.T<br />

11 hr<br />

53 min<br />

1 sec<br />

17 hr<br />

2 min<br />

20 sec<br />

CPU<br />

8 sec<br />

Figure 9-9 Catalog consistency queries - Measurement results<br />

With the changes to queries 31, 33, 35 and 36, the total CPU and elapsed time to execute the<br />

65 queries of DSNTESQ are greatly improved. The new queries have been retrofitted by<br />

APAR PQ71775 respectively with PTF UQ85042 to <strong>DB2</strong> V6 and UQ85043 to <strong>DB2</strong> V7.<br />

362 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

New DSNTESQ<br />

E.T<br />

24 sec<br />

Old DSNTESQ<br />

CPU<br />

51 min<br />

18 sec<br />

30 min<br />

25 sec<br />

V8 New Function Mode<br />

E.T<br />

11 hr<br />

48 min<br />

37 sec<br />

11 hr<br />

47 min<br />

9 sec<br />

New DSNTESQ<br />

CPU<br />

9 sec<br />

E.T<br />

23 sec


Chapter 10. Per<strong>for</strong>mance tools<br />

In this chapter, we discuss the <strong>IBM</strong> <strong>DB2</strong> per<strong>for</strong>mance tools and the key <strong>DB2</strong> V8 features they<br />

exploit.<br />

The following <strong>IBM</strong> tools are discussed in this chapter:<br />

► <strong>DB2</strong> Estimator<br />

► <strong>DB2</strong> Per<strong>for</strong>mance Expert<br />

► Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong><br />

► Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on z/<strong>OS</strong><br />

► <strong>DB2</strong> Archive Log Accelerator<br />

► <strong>DB2</strong> Query Monitor<br />

► <strong>DB2</strong> High Per<strong>for</strong>mance Unload<br />

► Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases<br />

► <strong>DB2</strong> Data Archive Expert<br />

► <strong>DB2</strong> Bind Manager<br />

► <strong>DB2</strong> High Per<strong>for</strong>mance Unload<br />

10<br />

The <strong>DB2</strong> tools may require maintenance to support <strong>DB2</strong> V8. You may look at the following<br />

URL to see the minimum maintenance level <strong>for</strong> the <strong>DB2</strong> tools in order to support and exploit<br />

<strong>DB2</strong> V8:<br />

http://www.ibm.com/support/docview.wss?rs=434&context=SSZJXP&uid=swg21162152&loc=en_US&c<br />

s=utf-8&lang=en+en<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 363


10.1 <strong>DB2</strong> Estimator<br />

<strong>DB2</strong> Estimator V8 is a no charge tool provided by <strong>DB2</strong> to help you predict the per<strong>for</strong>mance<br />

and cost of running <strong>DB2</strong> applications and utilities under <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>.<br />

This tool can be downloaded from the URL:<br />

http://www.ibm.com/software/data/db2/zos/estimate/<br />

With <strong>DB2</strong> Estimator you create definitions of <strong>DB2</strong> objects, SQL statements, transactions,<br />

utilities, and system configurations. You also have the option to combine elements to <strong>for</strong>m a<br />

workload which can be a representative sampling of an application. <strong>DB2</strong> Estimator uses this<br />

in<strong>for</strong>mation as input to provide per<strong>for</strong>mance estimates which you can use <strong>for</strong> tuning and also<br />

<strong>for</strong> capacity planning. You can also estimate the disk space used <strong>for</strong> tables and indexes.<br />

<strong>DB2</strong> Estimator calculates CPU time, I/O time, and elapsed time <strong>for</strong> utilities, SQL statements,<br />

transactions, and whole applications. The tool gives you the ability to experiment with <strong>DB2</strong><br />

applications and utilities on a PC without the need to use <strong>DB2</strong>. If you want to estimate <strong>DB2</strong> V8<br />

functions, then you need to create a new project and specify that you are using <strong>DB2</strong> V8.<br />

Tip: This can be done in two ways. You can create a new project or copy an existing project<br />

using “save as”. In both cases, specify you are using <strong>DB2</strong> V8.<br />

The <strong>DB2</strong> Estimator <strong>for</strong>mulas have been updated to reflect <strong>DB2</strong> V8 CPU times. There is<br />

support <strong>for</strong> a limited number of new <strong>DB2</strong> V8 features. Check the Web site <strong>for</strong> an up-to-date<br />

list.<br />

10.2 <strong>DB2</strong> Per<strong>for</strong>mance Expert<br />

One of the premier products <strong>for</strong> per<strong>for</strong>mance monitoring is the <strong>DB2</strong> Per<strong>for</strong>mance Expert (PE).<br />

This product has many different components providing a robust set of monitoring functions <strong>for</strong><br />

viewing your <strong>DB2</strong> subsystems. Here is a list of some of the most important functions <strong>DB2</strong> PE<br />

provides as a monitoring tool:<br />

► ISPF host online monitor<br />

► Workstation online monitor with the capability to monitor all of your <strong>DB2</strong> subsystems in a<br />

single view<br />

► Exception processing which handles both event and periodic exceptions<br />

► Batch reporting capability <strong>for</strong> all sorts of reports using <strong>DB2</strong> trace data as input<br />

► Per<strong>for</strong>mance Database which is a repository <strong>for</strong> <strong>DB2</strong> trace data controlled by the user<br />

► Per<strong>for</strong>mance Warehouse which is a repository <strong>for</strong> <strong>DB2</strong> accounting and statistics trace data<br />

controlled by PE<br />

► Buffer Pool Analysis to analyze your buffer pool configuration and make recommendations<br />

<strong>for</strong> improvement<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see:<br />

http://www.ibm.com/software/data/db2imstools/<br />

or refer to the book, <strong>DB2</strong> Per<strong>for</strong>mance Expert <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 2, SG24-6867-01, <strong>for</strong> details<br />

on the tool.<br />

364 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The following changes to <strong>DB2</strong> V8 have been incorporated into the batch reporting function of<br />

<strong>DB2</strong> PE after publication of that book:<br />

► Per<strong>for</strong>mance Expert PTF UQ90726 <strong>for</strong> APAR PQ88224 supports the ACCUMACC<br />

parameters in Batch Accounting reports, such that fields which are not valid <strong>for</strong> roll-up are<br />

shown as N/P or N/C (not present or not calculated). These fields are shown in the latest<br />

version of the <strong>DB2</strong> Per<strong>for</strong>mance Expert Reporting User's Guide, SC18-7978, in Appendix<br />

D.<br />

Note: The recent <strong>DB2</strong> APAR PQ90547 contains some rework on the roll-up mechanism<br />

which will be reflected in a Per<strong>for</strong>mance Expert PTF targeted <strong>for</strong> March/April 2005.<br />

► Per<strong>for</strong>mance Expert PTF UQ93207 <strong>for</strong> APAR PQ94872 supports new counters of IFCID<br />

225 <strong>for</strong> real storage statistics and dynamic statement caching introduced recently by <strong>DB2</strong><br />

in PQ91101.<br />

In addition, the PTFs provide enhanced support <strong>for</strong> V8 changes available in Record Trace,<br />

System Parameter and EXPLAIN reports.<br />

The following new major PE functions have been delivered with PTF UQ95694 <strong>for</strong> APAR<br />

PQ95989 in December 2004:<br />

► READS support of IFCID 225 in Workstation Online Monitor<br />

► Enhancements in Locking Suspension Reports to accumulate additional locking data and<br />

write it into a file which can be imported into a spreadsheet <strong>for</strong> further analysis<br />

► Enhancements in SQL Activity Reports <strong>for</strong> displaying in<strong>for</strong>mation on host variables<br />

► Enhancements in I/O Activity Reports supporting new ORDER functionality<br />

Virtual storage layout<br />

With PQ91101, <strong>DB2</strong> introduces new counters in IFCID 225 <strong>for</strong> real storage statistics and<br />

dynamic statement caching.<br />

<strong>DB2</strong> Per<strong>for</strong>mance Expert V2.1 supports this functionality with PTF UQ93207 <strong>for</strong> APAR<br />

PQ94872. See also 4.3, “Monitoring DBM1 storage” on page 157, and Appendix B, “The<br />

DBM1 storage map” on page 393. Here is a summary of the features:<br />

► Record Trace<br />

The report block <strong>for</strong> IFCID 225 has been rearranged to better match the layout in the<br />

statistics reports.<br />

► Statistics Report and Trace (long <strong>for</strong>mat)<br />

The report blocks have been implemented as follows:<br />

– DBM1 AND MVS STORAGE BELOW 2 GB<br />

This block contains the new fields related to dynamic statement caching.<br />

Two new fields AVERAGE THREAD FOOTPRINT (MB) and MAX NUMBER OF<br />

P<strong>OS</strong>SIBLE THREADS have been added. Here are the <strong>for</strong>mulas:<br />

Average Thread Footprint: (QW0225VR - QW0225AS) / (QW0225AT + QDSTCNAT)<br />

Max number of possible threads: ((QW0225RG – QW0225EL) – (200 * (1024 * 1024)) –<br />

(QW0225GM + QW0225GS + QW0225FX)) / average thread footprint<br />

(The block has been split up because the page size limit has been reached.)<br />

– DBM1 STORAGE ABOVE 2 GB<br />

The block has been extended to contain the field QW0225SJ with label STAR JOIN<br />

MEMORY POOL (MB).<br />

Chapter 10. Per<strong>for</strong>mance tools 365


– REAL AND AUXILIARY STORAGE<br />

This is the new block containing the real storage statistics counters.<br />

– EDM POOL<br />

The block has been extended to contain the field QISESTMT with label STATEMENTS<br />

IN GLOBAL CACHE.<br />

► Statistics SAVE file<br />

The statistics SAVE file layout has been changed. The Statistics SAVE migration and<br />

convert programs shipped with the PTF must be used from now on.<br />

► Per<strong>for</strong>mance Database<br />

The new fields of IFCID 225 are supported in the Statistics General Table of the<br />

Per<strong>for</strong>mance Database. The member SFPESAMP(DG<strong>OS</strong>UPDB) contains ALTER<br />

statements <strong>for</strong> migration purposes.<br />

The member SFPESAMP(DG<strong>OS</strong>QGEN) contains a query that calculates the <strong>for</strong>mulas<br />

<strong>for</strong> “average thread footprint” and “max number of possible threads” within the<br />

per<strong>for</strong>mance database.<br />

► Per<strong>for</strong>mance Warehouse<br />

The PE Server shipped with the PTF automatically adds the new columns to the<br />

Statistics General Table of the Per<strong>for</strong>mance Warehouse.<br />

► Documentation<br />

The PE books have been republished in December 2004 and contain updates about<br />

these changes.<br />

10.3 Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong><br />

<strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong> is the next evolution in OMEGAMON<br />

per<strong>for</strong>mance and availability solutions designed to help you proactively manage your <strong>DB2</strong><br />

mainframe environment and tune <strong>for</strong> optimal per<strong>for</strong>mance. Its Web interface provides a single<br />

interface at the big picture and granular levels, including interaction between <strong>DB2</strong> and other<br />

applications. <strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong> helps you identify per<strong>for</strong>mance<br />

spikes and anomalies that might otherwise go unseen, take action in real time and automate<br />

repetitive <strong>DB2</strong> operations.<br />

In addition to offering leading per<strong>for</strong>mance and availability management <strong>for</strong> <strong>DB2</strong>, Tivoli<br />

OMEGAMON XE <strong>for</strong> <strong>DB2</strong> integrates with other Tivoli products. You can use these integrated<br />

products to deploy true end-to-end availability management and help prevent threats to<br />

system per<strong>for</strong>mance be<strong>for</strong>e they impact service levels.<br />

Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> helps you monitor and tune how Workload Manager allocates<br />

and balances resources to find the source of per<strong>for</strong>mance problems quickly and adjust<br />

resources accordingly. You can gain visibility into, and control over, enclave usage. And you<br />

can analyze transaction rate in<strong>for</strong>mation to identify overloaded and under per<strong>for</strong>ming<br />

workloads. Optimize use of the coupling facility in Parallel Sysplex environments.<br />

Because Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> gives you a single point of control over your <strong>DB2</strong><br />

parallel data sharing environment, you have the in<strong>for</strong>mation necessary to detect, isolate and<br />

resolve problems. To optimize the per<strong>for</strong>mance of the coupling facility in the Parallel Sysplex,<br />

you can analyze coupling facility structures, participating member status and contention rates.<br />

366 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


The ability to integrate in<strong>for</strong>mation from Tivoli OMEGAMON XE monitors and third-party<br />

software into a single view enables you to identify and track problems across all your<br />

enterprise plat<strong>for</strong>ms.<br />

10.4 Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on<br />

z/<strong>OS</strong><br />

As communicated with the statement of direction from December 7 Announcement 204-297<br />

(US), <strong>IBM</strong> has converged and expanded the capabilities of <strong>DB2</strong> Per<strong>for</strong>mance Expert <strong>for</strong> z/<strong>OS</strong>,<br />

V2.1 (5655-J49) and Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong>, V3.0 (5608-A67).<br />

<strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Expert on z/<strong>OS</strong> represents the ef<strong>for</strong>t on<br />

converging OMEGAMON XE <strong>for</strong> <strong>DB2</strong> and <strong>DB2</strong> Per<strong>for</strong>mance Expert into one product that<br />

retains the best features of each. This new tool gives you a single, comprehensive tool to help<br />

assess the efficiency of and optimize per<strong>for</strong>mance from your <strong>DB2</strong> Universal Database in<br />

the z/<strong>OS</strong> environment. It automates the analysis of your database per<strong>for</strong>mance in real time<br />

and also adds expert database analysis functions to help you maximize per<strong>for</strong>mance and<br />

enhance productivity.<br />

The main functions of this tool allow you to:<br />

► Monitor, analyze, and tune the per<strong>for</strong>mance of <strong>IBM</strong> <strong>DB2</strong> Universal Database and <strong>DB2</strong><br />

applications on z/<strong>OS</strong><br />

► Improve productivity with meaningful views of per<strong>for</strong>mance<br />

► Quickly and easily identify per<strong>for</strong>mance bottlenecks using predefined rules of thumb<br />

► Enjoy substantial breadth and depth in monitoring <strong>DB2</strong> environments by combining<br />

batch-reporting capabilities with real-time monitoring and historical tracking functions<br />

► Support an enterprise-wide integrated systems management strategy activated by the<br />

<strong>IBM</strong> Tivoli OMEGAMON XE family<br />

► Store per<strong>for</strong>mance data and analysis tools in a per<strong>for</strong>mance warehouse<br />

The software combines the sophisticated reporting, monitoring, and buffer pool analysis<br />

features of the <strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance Monitor on z/<strong>OS</strong> and <strong>IBM</strong><br />

<strong>DB2</strong> Buffer Pool Analyzer products.<br />

The book A Deep Blue View of <strong>DB2</strong> Per<strong>for</strong>mance: <strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong><br />

Per<strong>for</strong>mance Expert on z/<strong>OS</strong>, SG24-7224 helps you understand ans install the main functions<br />

of the product, clarify the differences, and point out the advantages if you had one of the<br />

pre-existing products already in use.<br />

10.5 <strong>DB2</strong> Archive Log Accelerator<br />

If a hardware failure occurs while <strong>DB2</strong> is writing changed pages to DASD, or you have applied<br />

the wrong updates, you may need to recover the data, and recovery from the logs occurs. If<br />

necessary, the <strong>DB2</strong> recover utility will mount archive logs to get the needed data in order to<br />

restore the corrupted tables. The <strong>DB2</strong> archive logs can also be used in other critical recovery<br />

situations or an unplanned outage such as a <strong>DB2</strong> subsystem restart after a failed <strong>DB2</strong> or<br />

MVS image. The amount of time spent in such scenarios needs to be minimized to get the<br />

application back up as quickly as possible.<br />

Chapter 10. Per<strong>for</strong>mance tools 367


Another use is during back out of a long running process that issues a ROLLBACK. <strong>DB2</strong><br />

Archive Log Accelerator compresses the archive log as an ef<strong>for</strong>t to reduce the times to<br />

recover from such situations.<br />

Preliminary measurements are listed in Table 10-1.<br />

Table 10-1 RECOVER and Archive Log Accelerator<br />

RECOVER from<br />

active log has ET of<br />

335 sec.<br />

Stripes<br />

These measurements are <strong>for</strong> RECOVER with PTF UQ90143 <strong>for</strong> PQ88896 applied.<br />

RECOVER with ALA, striping and compression, shows an elapsed time improvement of<br />

almost 30%. Increasing the number of stripes did not improve elapsed time.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see:<br />

http://www.ibm.com/software/data/db2imstools/<br />

<strong>DB2</strong> Archive Log Accelerator V2.1 fully exploits <strong>DB2</strong> V8.<br />

10.6 <strong>DB2</strong> Query Monitor<br />

RECOVER from<br />

archive log<br />

CPU/ET (sec.)<br />

Monitoring and tuning the SQL activity in a <strong>DB2</strong> subsystem is important especially when<br />

problems occur that affect the response times. You may need to identify problematic SQL<br />

statements and focus on improving the response times of important transactions. <strong>DB2</strong> Query<br />

Monitor allows you to view current and historical query activity within your <strong>DB2</strong> subsystems<br />

and make important decisions affecting its per<strong>for</strong>mance.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see<br />

http://www.ibm.com/software/data/db2imstools/<br />

Here is a list of features of Query Monitor V2.1:<br />

► Data collection and activity viewing features<br />

► SQL statement resource consumption<br />

► Object access statistics with granularity down to the object level<br />

► Current active statements in <strong>DB2</strong><br />

► Pinpoint SQL from many different views:<br />

– Plan<br />

– Program<br />

– User<br />

– SQL statement<br />

► Ability to exclude workloads or specific SQLCODEs<br />

► Set exception limits and thresholds<br />

► Define alert notification thresholds<br />

368 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

With ALA<br />

CPU/ET (sec.)<br />

With ALA and<br />

compression<br />

CPU/ET (sec.)<br />

1 183/460 177/444 176/323<br />

2 N/A 176/439 176/330<br />

4 N/A 176/435 176/324<br />

non-ext ds 177/543 N/A N/A


<strong>DB2</strong> Query Monitor V2.1 supports and exploits <strong>DB2</strong> V8.<br />

10.7 <strong>DB2</strong> SQL Per<strong>for</strong>mance Analyzer <strong>for</strong> z/<strong>OS</strong><br />

<strong>DB2</strong> SQL Per<strong>for</strong>mance Analyzer <strong>for</strong> z/<strong>OS</strong> V2.2 (SQL PA) allows you to analyze SQL<br />

statements without having to execute them. It provides many different types of detailed<br />

reports giving the novice developer or experienced DBAs reports of different in<strong>for</strong>mation<br />

depending on the level of experience.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see<br />

http://www.ibm.com/software/data/db2imstools/<br />

SQL PA V2.2 has been completely redesigned and contains full support and exploits <strong>DB2</strong> V8<br />

in both compatibility and new-function modes.<br />

Here is a list of new features in the tool that expand on support <strong>for</strong> <strong>DB2</strong> V8:<br />

► Handles DBRMs in Unicode or EBCDIC<br />

► Supports larger SQL statements up to 2 MB<br />

► Provides consideration of MQTs <strong>for</strong> access paths<br />

► Supports the REFRESH statement which allows the EXPLAIN function to consider the<br />

use of MQTs when considering access path selection<br />

► Recognizes<br />

– <strong>DB2</strong> catalog and longer names<br />

– Columns containing data in Unicode<br />

– Padded/nonpadded indexes<br />

► Includes redesigned report structure in order to handle long names<br />

► Provides statistics collector program that supports <strong>DB2</strong> V8 catalog<br />

► Supports new PLAN_TABLE columns<br />

Additionally, SQL PA reports on table and index versioning, volatile tables, MQTs, DPSIs, and<br />

other <strong>DB2</strong> V8 enhancements.<br />

Refer to Appendix C, “SQL PA sample reports” on page 399 <strong>for</strong> a sample of the new SQL PA<br />

report illustrating some of the <strong>DB2</strong> V8 functionality.<br />

10.8 Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases<br />

If you need extra protection <strong>for</strong> your company’s IMS and <strong>DB2</strong> data in order to comply with<br />

regulatory legislation, then encryption may be the thing you are looking <strong>for</strong>.<br />

<strong>IBM</strong> Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases is implemented using standard IMS and<br />

<strong>DB2</strong> exits. The exit code invokes the zSeries and S/390® Crypto Hardware to encrypt data <strong>for</strong><br />

storage and decrypt data <strong>for</strong> application use, thereby protecting sensitive data residing on<br />

various storage media. This tool can help you save the time and ef<strong>for</strong>t required to write and<br />

maintain your own encryption software <strong>for</strong> use with such exits or within your applications.<br />

In IMS, the <strong>IBM</strong> Data Encryption tool implements encryption using the standard Segment<br />

Edit/Compression exit routine. Both IMS data and index databases can be encrypted and<br />

decrypted.<br />

Chapter 10. Per<strong>for</strong>mance tools 369


In <strong>DB2</strong>, the <strong>IBM</strong> Data Encryption tool implements encryption through the standard<br />

EDITPROC exit.<br />

Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases V1.1 supports and exploits <strong>DB2</strong> V8.<br />

For per<strong>for</strong>mance data see 4.7.1, “Per<strong>for</strong>mance” on page 184.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see<br />

http://www.ibm.com/software/data/db2imstools/<br />

10.9 <strong>DB2</strong> Data Archive Expert<br />

One of the pressing concerns <strong>for</strong> In<strong>for</strong>mation Technology is the increasing volumes of data;<br />

databases are growing at an exponential rate and many organizations are alarmed at the<br />

volume of data they need to keep on hand. Inactive data exists everywhere; data warehouses<br />

grow every day. Inactive data is not unusable; it just has a lower probability of access.<br />

Organizations may have governmental requirements to keep certain data and there may be<br />

be a valid business need.<br />

As databases grow in size, the percentage of inactive data also grows. Inactive data costs are<br />

high and many organizations are examining ways to archive dormant data to keep operational<br />

costs down. The Data Archive Expert tool can help you manage your archived data so that it<br />

can be quickly accessed whenever necessary.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see<br />

http://www.ibm.com/software/data/db2imstools/<br />

The <strong>DB2</strong> Data Archive Expert <strong>for</strong> z/<strong>OS</strong> V1.1 supports and exploits <strong>DB2</strong> V8.<br />

10.10 <strong>DB2</strong> Bind Manager<br />

It might be important to know if you per<strong>for</strong>m a rebind: Will the access path change? Does a<br />

plan or package need a rebind? Can we bypass a rebind because the application logic<br />

changed but not the SQL? Often, with a new release of <strong>DB2</strong>, there are changes in the access<br />

path, but it would be advantageous to know ahead of time the effect of a rebind on the access<br />

path selection by <strong>DB2</strong>. The bind process uses CPU resources and <strong>DB2</strong> must quiesce access<br />

to the plan or package. If the bind is unnecessary, you can save much in resource<br />

consumption by avoiding a bind.<br />

As the name implies, the <strong>DB2</strong> Bind Manager tool manages binds in the <strong>DB2</strong> environment and<br />

can help with all of the issues mentioned above.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see<br />

http://www.ibm.com/software/data/db2imstools/<br />

The <strong>DB2</strong> Bind Manager Tool V2.2 supports and exploits <strong>DB2</strong> V8.<br />

10.11 <strong>DB2</strong> High Per<strong>for</strong>mance Unload<br />

The <strong>DB2</strong> High Per<strong>for</strong>mance Unload (HPU) is a tool that allows you to unload data from your<br />

<strong>DB2</strong> tables outside of <strong>DB2</strong>. The UNLOAD utility is provided with the <strong>DB2</strong> Utilities Suite V7<br />

370 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


and <strong>DB2</strong> V8. These two products provide different unload capabilities. The major functional<br />

differences between them are outlined in Table 10-2 below.<br />

For more in<strong>for</strong>mation about this <strong>DB2</strong> tool, see the following Web site:<br />

http://www.ibm.com/software/data/db2imstools/<br />

Table 10-2 <strong>DB2</strong> HPU vs. UNLOAD utility<br />

<strong>DB2</strong> High Per<strong>for</strong>mance Unload tool UNLOAD utility<br />

Supports <strong>DB2</strong> V5, V6, V7 and V8 Supports <strong>DB2</strong> V and V8<br />

Supports any SQL statement by passing any<br />

statements it cannot process to <strong>DB2</strong><br />

Table 10-3 describes the different output <strong>for</strong>mats available with the <strong>DB2</strong> High Per<strong>for</strong>mance<br />

Unload tool.<br />

Table 10-3 HPU output <strong>for</strong>mats<br />

10.11.1 Per<strong>for</strong>mance measurements<br />

Supports a limited number of statements<br />

Has 4 output <strong>for</strong>mats <strong>DB2</strong> V7: only one output <strong>for</strong>mat - LOAD.<br />

<strong>DB2</strong> V8: supports delimited <strong>for</strong>mat in addition to<br />

LOAD above.<br />

Has a user exit that allows you to examine the row<br />

prior to writing to the output data set. You can also<br />

modify the row prior to writing it to the data set.<br />

Can unload data from a dropped table. HPU<br />

requires that the dropped table be recreated in<br />

the catalog and then per<strong>for</strong>m the unload from an<br />

image copy using the OBID of the original table.<br />

HPU UNLOAD command syntax same between<br />

z/<strong>OS</strong> product and MP product.<br />

HPU V2 supports BMC and CA UNLOAD product<br />

syntax.<br />

HPU output <strong>for</strong>mats Description<br />

Several per<strong>for</strong>mance measurements were made to compare the per<strong>for</strong>mance of different<br />

unload options. One set of tests compares the HPU V2.2 and the <strong>DB2</strong> V8 UNLOAD utility.<br />

Another set of tests illustrate the difference between unloading data using the <strong>DB2</strong> V8<br />

UNLOAD utility with a load output <strong>for</strong>mat as opposed to using the delimited data <strong>for</strong>mat. The<br />

results are discussed in this section.<br />

N/A<br />

If the created table has the same OBID as the<br />

original table, the UNLOAD utility does the<br />

unload. If the OBID is different, then the UNLOAD<br />

utility will not work.<br />

REORG UNLOAD Same <strong>for</strong>mat as the <strong>IBM</strong> REORG UNLOAD utility<br />

N/A<br />

N/A<br />

DSNTIAUL Output identical to DSNTIAUL <strong>for</strong>mat<br />

DELIMITED You can specify a separator and a delimiter<br />

character<br />

VARIABLE Treat all variable length fields as variable<br />

USER Completely user-defined; can customize every<br />

column differently<br />

Chapter 10. Per<strong>for</strong>mance tools 371


The utilities ran on a G7 Turbo with ESS F20 DASD using z/<strong>OS</strong> V1.5. The table space<br />

contains only one table with two indexes. The table space is a partitioned table space and so<br />

one case involves using parallelism <strong>for</strong> the UNLOAD. The table used contains 124,999 rows.<br />

The test cases are described in detail within Table 10-4.<br />

Table 10-4 Unload test cases<br />

Test case Description<br />

Case 1 Unload from a table space using an image copy data set<br />

Case 2 Unload from an image copy data set<br />

Case 3 UNLOAD SELECT * FROM tablename<br />

Case 4 UNLOAD SELECT C1, C2, C3, C4, C5 FROM tablename<br />

Case 5 UNLOAD SELECT * FROM tablename WHERE C1 constant<br />

C1 is a non-indexed column<br />

Case 6 UNLOAD SELECT C1, C2, C3, C4, C5 FROM tablename WHERE C1 constant<br />

C1 is a non-indexed column<br />

Case 7 UNLOAD SELECT * FROM tablename WHERE C3 = constant<br />

C3 is a non-indexed column<br />

Case 8 UNLOAD SELECT * FROM tablename WHERE C4 constant<br />

C4 is an indexed column<br />

Case 9 UNLOAD SELECT * FROM tablename WHERE C4 = constant<br />

C4 is an indexed column<br />

Case 10 Same as Case 9 but used HPU parameter FORCE <strong>DB2</strong><br />

Parallel Run unload against multiple partitions of the same table space in parallel<br />

HPU and UNLOAD utility<br />

The results of the per<strong>for</strong>mance measurement between HPU and the <strong>DB2</strong> V8 Unload utility<br />

are summarized in Table 10-5.<br />

Table 10-5 HPU V2.2 vs. <strong>DB2</strong> V8 UNLOAD utility<br />

Test case HPU V2.2 <strong>DB2</strong> V8 UNLOAD % Difference<br />

372 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CPU Elapsed CPU Elapsed CPU Elapsed<br />

Case 1 11.89 62 27.56 58 131.79 -6.45<br />

Case 2 9.44 61 46.86 57 396.39 -6.55<br />

Case 3 13.57 59 N/A N/A N/A N/A<br />

Case 4 9.67 46 42.11 46 335.47 0.00<br />

Case 5 18.00 58 33.02 57 83.44 -1.72<br />

Case 6 13.93 46 47.10 50 238.11 8.69<br />

Case 7 12.87 45 14.34 42 11.42 -6.66<br />

Case 8 17.80 59 33.60 58 88.76 -1.69<br />

Case 9 12.51 45 14.35 42 14.70 -6.66<br />

Case 10 2.39 22 14.35 42 500.41 90.90


Test case HPU V2.2 <strong>DB2</strong> V8 UNLOAD % Difference<br />

CPU Elapsed CPU Elapsed CPU Elapsed<br />

Parallel 15.33 24 68.08 31 344.09 29.16<br />

Even if an index is available, the UNLOAD utility does not take advantage of it.<br />

You can see that in all cases, HPU outper<strong>for</strong>ms the <strong>DB2</strong> V8 UNLOAD utility in CPU time.<br />

However, in most cases, the UNLOAD utility elapsed time is slightly better.<br />

In case 2, where the unload is per<strong>for</strong>med using an image copy, the UNLOAD utility takes<br />

almost 4 times more CPU than HPU although the elapsed time <strong>for</strong> the UNLOAD utility is<br />

almost 7% better than HPU.<br />

In case 4, the elapsed time <strong>for</strong> both HPU and the UNLOAD utility is the same, but HPU<br />

outper<strong>for</strong>ms the UNLOAD utility using 1/4 the CPU time.<br />

When parallelism is used, HPU outshines the <strong>DB2</strong> UNLOAD utility. The CPU time <strong>for</strong> the<br />

UNLOAD utility is almost 3.5 times more than HPU and the elapsed time <strong>for</strong> the UNLOAD<br />

utility is 29% higher than HPU.<br />

Case 10 is the same as Case 9 except the measurement <strong>for</strong> HPU involved the use of <strong>DB2</strong><br />

FORCE. This HPU parameter indicates that <strong>DB2</strong> must be used to extract the requested rows.<br />

This is generally preferred when the SELECT statement uses a filtering predicate that is<br />

efficiently processed through SQL, and the filter factor is high.<br />

Note: The <strong>DB2</strong> UNLOAD utility in case 1 unloads the entire table space. Case 3 unloads<br />

the entire table; since it is the same as case 1, the Unload is not reported <strong>for</strong> case 3.<br />

The graphical depiction of the results is in Figure 10-1 and Figure 10-2. The results are<br />

dramatic <strong>for</strong> the <strong>DB2</strong> HPU tool.<br />

Figure 10-1 shows Case 1 through Case 5.<br />

Chapter 10. Per<strong>for</strong>mance tools 373


time<br />

Figure 10-1 <strong>DB2</strong> HPU vs. UNLOAD utility Case 1 through Case 5<br />

Figure 10-2 shows Case 6 through Parallel.<br />

time<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

Figure 10-2 <strong>DB2</strong> HPU vs. UNLOAD utility Case 6 through Parallel<br />

HPU and DSNTIAUL<br />

We show two sets of measurements, one with DSNTIAUL not using multi-row fetch, and<br />

another one using multi-row fetch. Note that DSNTIAUL in V8 always uses multi-row fetch.<br />

374 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

0<br />

70<br />

60<br />

50<br />

40<br />

30<br />

20<br />

10<br />

0<br />

<strong>DB2</strong> HPU vs. UNLOAD HPU CPU<br />

UNLOAD CPU<br />

HPU ET<br />

UNLOAD ET<br />

Case 1 Case 2 Case 3 Case 4 Case 5<br />

<strong>DB2</strong> HPU vs. UNLOAD<br />

HPU CPU<br />

UNLOAD CPU<br />

HPU ET<br />

UNLOAD ET<br />

Case 6 Case 7 Case 8 Case 9 Case 10 Parallel


DSNTIAUL without multi-row fetch<br />

The results of the per<strong>for</strong>mance measurement between HPU and <strong>DB2</strong> V8 DSNTIAUL are<br />

summarized in Table 10-6 <strong>for</strong> the case where DSNTIAUL is not using multi-row fetch.<br />

Table 10-6 HPU V2.2 vs. <strong>DB2</strong> V8 DSNTIAUL (no multi-row)<br />

Test case HPU V2.2 <strong>DB2</strong> V8 DSNTIAUL % Difference<br />

CPU Elapsed CPU Elapsed CPU Elapsed<br />

Case 1 11.89 62 186.99 239 1472.66 285.48<br />

Case 2 9.44 61 N/A N/A N/A N/A<br />

Case 3 13.57 59 186.77 238 1276.34 303.38<br />

Case 4 9.67 46 148.46 166 1435.26 260.86<br />

Case 5 18.00 58 184.71 236 926.16 306.89<br />

Case 6 13.93 46 146.33 163 950.46 254.34<br />

Case 7 12.87 45 8.23 45 -36.05 0<br />

Case 8 17.80 59 191.34 237 974.94 301.69<br />

Case 9 12.51 45 1.75 22 -86.01 -51.11<br />

Case 10 2.39 22 1.75 22 -26.77 0<br />

Parallel 15.33 24 N/A N/A N/A N/A<br />

DSNTIAUL can use an index so one would assume that DSNTIAUL may have a slight<br />

advantage over the UNLOAD utility. However, the measurement cases illustrate otherwise.<br />

DSNTIAUL was the larger consumer of CPU time and also typically had the longer elapsed<br />

time, although two test cases showed DSNTIAUL being the better per<strong>for</strong>mer. However, when<br />

you compare DSNTIAUL with HPU, the results are extraordinary. HPU outper<strong>for</strong>med<br />

DSNTIAUL by using less than 10% of the CPU time.<br />

Nearly every unload product is written with the assumption that users will unload a large<br />

percentage of the available data, usually in the 50 - 100% range. In these instances, it may be<br />

better to scan the entire table rather than using an index.<br />

However, there are times when you may want to unload a small percentage of the rows,<br />

perhaps 10 - 20% and you know an index exists that allows access to the table data. In this<br />

case, a scan of the table may result in worse per<strong>for</strong>mance than if an SQL statement were<br />

executed directly by <strong>DB2</strong>; you may then see better per<strong>for</strong>mance with DSNTIAUL than with<br />

HPU.<br />

If you are using HPU and you have a query where using the SQL might per<strong>for</strong>m better than a<br />

table space scan, use the <strong>DB2</strong> FORCE parameter. This causes HPU to pass the query to<br />

<strong>DB2</strong> <strong>for</strong> execution and may result in better per<strong>for</strong>mance. This is evident in case 10 which is<br />

the same as case 9 except <strong>DB2</strong> FORCE is used. The results are once again dramatic; there<br />

is a 6X improvement in CPU time with the exact same elapsed time.<br />

Note: DSNTIAUL cannot unload from an image copy data set so the results are N/A <strong>for</strong><br />

case 2.<br />

Chapter 10. Per<strong>for</strong>mance tools 375


DSNTIAUL with multi-row fetch<br />

The results of the per<strong>for</strong>mance measurement between <strong>DB2</strong> V8 DSNTIAUL and HPU are<br />

summarized in Table 10-7 <strong>for</strong> the case where DSNTIAUL is using multi-row fetch.<br />

Table 10-7 HPU V2.2 vs. <strong>DB2</strong> V8 DSNTIAUL (multi-row)<br />

Test case HPU V2.2 <strong>DB2</strong> V8 DSNTIAUL % Difference<br />

With Unload using multi-row fetch there is a general improvement in CPU time, almost half<br />

than the single row case, and the elapsed time goes down accordingly.<br />

DSNTIAUL is still the largest consumer of CPU time and also typically has longer elapsed<br />

time when compared to HPU, although Case 7 and 10 show DSNTIAUL being the best<br />

per<strong>for</strong>mer. In general HPU outper<strong>for</strong>ms DSNTIAUL multi-row by using about 1/3 - 1/4 of the<br />

CPU time.<br />

You see better per<strong>for</strong>mance with DSNTIAUL than with HPU, in cases 7 and 10, by an even<br />

larger margin than in the previous case.<br />

HPU vs. UNLOAD with <strong>for</strong>mat delimited<br />

If the UNLOAD utility prepares the output in delimited output <strong>for</strong>mat, you can assume that<br />

there is more work it has to per<strong>for</strong>m to add both the additional column delimited character and<br />

character string delimiter into the output data set as opposed to the external <strong>for</strong>mat. In spite of<br />

the extra CPU expended <strong>for</strong> this processing, the usability this feature provides is well worth it;<br />

the process is much easier since you can load the data without manually re<strong>for</strong>matting the<br />

input file <strong>for</strong> the LOAD utility.<br />

Refer to 6.3, “LOAD and UNLOAD delimited input and output” on page 270 <strong>for</strong> the results of<br />

this per<strong>for</strong>mance analysis.<br />

376 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CPU Elapsed CPU Elapsed CPU Elapsed<br />

Case 1 11.89 62 109.27 159 819 156.45<br />

Case 2 9.44 61 N/A N/A N/A N/A<br />

Case 3 13.57 59 109.97 160 710.39 171.18<br />

Case 4 9.67 46 57.21 74 491.62 60.86<br />

Case 5 18.00 58 110.00 159 511.11 174.13<br />

Case 6 13.93 46 57.54 74 313.06 60.86<br />

Case 7 12.87 45 7.05 44 -45.22 -2.22<br />

Case 8 17.80 59 110.81 160 522.52 171.18<br />

Case 9 12.51 45 - - - -<br />

Case 10 2.39 22 1.44 21 -39.74 -93.45<br />

Parallel 15.33 24 N/A N/A N/A N/A


Appendix A. Summary of per<strong>for</strong>mance<br />

maintenance<br />

A<br />

In this appendix, we look at <strong>DB2</strong> V7 and V8 recent maintenance that generally relates to <strong>DB2</strong><br />

per<strong>for</strong>mance and availability.<br />

This list represents a snapshot of the current maintenance at the moment of writing, and as<br />

such, it becomes incomplete or even incorrect at the time of reading. It is here to identify<br />

areas of per<strong>for</strong>mance improvements.<br />

Make sure to contact your <strong>IBM</strong> Service Representative <strong>for</strong> the most current maintenance at<br />

the time of your installation and check on RETAIN® <strong>for</strong> the applicability of these APARs to<br />

your environment, as well as to verify pre- and post-requisites.<br />

We recommend you use the Consolidated Service Test (CST) as the base <strong>for</strong> service.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 377


A.1 Maintenance <strong>for</strong> <strong>DB2</strong> V8<br />

The APARs applicable to <strong>DB2</strong> V8 are listed in Table A-1.<br />

They are provided here as the maintenance of interest <strong>for</strong> per<strong>for</strong>mance and availability<br />

functions, at the time of writing.<br />

Make sure to contact your <strong>IBM</strong> Service Representative <strong>for</strong> the most current maintenance at<br />

the time of your installation.<br />

Effective June 15, 2007, a <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SUP tape is available world-wide <strong>for</strong> new<br />

customer orders. This SUP tape integrates PTFs COR-closed through December 2006,<br />

which had also completed a Consolidated Service Test (CST) cycle. It contains CST tested<br />

PTFs which were marked "RSU 0703", which means they completed CST testing in March<br />

2007.<br />

This SUP build integrates a total of 964 PTFs (the delta since the previous December 2005<br />

SUP) and will certainly help all new <strong>DB2</strong> customers during their V8 installation.<br />

For additional in<strong>for</strong>mation on CST and RSU, please see:<br />

http://www.ibm.com/servers/eserver/zseries/zos/servicetst/mission.html<br />

Table A-1 <strong>DB2</strong> V8 per<strong>for</strong>mance-related APARs<br />

APAR # Area Text PTF and Notes<br />

II10817 Storage<br />

usage<br />

Fix list part 1<br />

II14047 DFSORT Description of DFSORT changes <strong>for</strong> V8 utilities<br />

II4309 Storage<br />

usage<br />

II13695 Migration/fall<br />

back<br />

PQ80631 Dependent<br />

routines<br />

Fix list part 2<br />

Toleration, coexistence and compatibility PTFs<br />

between V8 and V7<br />

Support <strong>for</strong> dependent WLM-managed routines<br />

interface. This APAR along with WLM APAR<br />

OA04555 5/04 on z/<strong>OS</strong>1.4 allows <strong>DB2</strong> to in<strong>for</strong>m<br />

WLM when inserting work that there is an in-use<br />

WLM server TCB waiting <strong>for</strong> this work to complete.<br />

This allows WLM to be more responsive in starting<br />

server address spaces.<br />

PQ82878 Striping Partitioned TS ran out of 123 extents with striped<br />

data set with 3 track minimum extent size because<br />

primary volume did not have sufficient free space<br />

378 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UQ90159<br />

also in V7<br />

UQ90794<br />

also in V7<br />

PQ83649 RAS -DIS THD(*) SERVICE(WAIT) UQ87013<br />

also in V7<br />

PQ84160 Xloader Xloader per<strong>for</strong>mance 2x improvement, now even<br />

with Unload and Load<br />

PQ86071 DSMAX En<strong>for</strong>ce DSMAX limit by failing data set open if<br />

DSMAX exceeded and #open data set >32K, to<br />

prevent potential storage shortage<br />

UQ91422<br />

also in V7<br />

UQ87443


APAR # Area Text PTF and Notes<br />

PQ86074 DSC Instead of reserving 2K storage <strong>for</strong> Current Path<br />

Special Register in each statement stored in DSC,<br />

allocate just enough<br />

UQ86872<br />

PQ86201 DSC Reduce runtime structure in DSC UQ86831<br />

PQ86477 IFC The IFCID flat file <strong>for</strong> V7 and V8 now contains<br />

current in<strong>for</strong>mation<br />

UQ92475<br />

also in V7<br />

PQ86787 Java Abend and storage leak UQ87049<br />

PQ86904 IRLM Service Roll-up UQ87591<br />

PQ87126 DBM1 virtual<br />

storage<br />

Excessive DBM1 virtual storage use with<br />

KEEPDYN Y and input decimal hv<br />

PQ87129 Java JCC driver data type switching causes skipping the<br />

DDF per<strong>for</strong>mance feature<br />

UQ88971<br />

also in V7<br />

UQ87633<br />

also in V7<br />

PQ87168 Data Sharing Protocol 2: correct lock processing UQ87760<br />

PQ87381 Insert Insert per<strong>for</strong>mance suffers because of exhaustive<br />

search <strong>for</strong> space to extending the page set<br />

PQ87390 Access path Bad access path when running a complex query<br />

with OPTIMIZE FOR N ROWS<br />

PQ87447 Catalog<br />

query<br />

Query 5 and 18 of the DSNTESQ catalog<br />

consistency queries per<strong>for</strong>m slowly<br />

PQ87509 RUNSTATS DSTATS correction <strong>for</strong> COLGROUP FREQUENCY<br />

VALUES <strong>for</strong> aggregated statistics in partitioned<br />

table spaces<br />

UK06754<br />

also in V7<br />

UQ91022<br />

UQ90654<br />

also in V7<br />

UQ91099<br />

PQ87611 IRLM IRLM 2.2 storage management enhancements UK16124<br />

PQ87756 Data sharing Allow enablement of data sharing protocol 2 UQ87903<br />

PQ87848 IFC IFCID 173 <strong>for</strong> -905 occurrence UQ90756<br />

also in V7<br />

PQ87917 I/O I/O per<strong>for</strong>mance on ESS/2105 devices can be<br />

improved by utilizing the "bypass read/write<br />

serialization" option. It is already done <strong>for</strong> writer,<br />

this APAR adds support <strong>for</strong> reader.<br />

Support R/W I/O concurrency in same defined<br />

domain (but not same track). ESS “bypass define<br />

extent serialization” set by <strong>DB2</strong> is disabled when<br />

XRC/PPRC/FlashCopy in progress. Extent=1<br />

cylinder in V7, bigger in V8.<br />

PQ87969 Multi-row Problems while processing a FETCH against a<br />

rowset cursor, after a DELETE WHERE CURRENT<br />

OF request. The problem only occurred while index<br />

RID access path was chosen by the database.<br />

PQ88073 DSC A new keyword ALL is added to EXPLAIN<br />

STMTCACHE and a new explain table<br />

DSN_STATEMENT_CACHE_TABLE is created to<br />

hold the output of IFCID 316 and 318.<br />

UQ88680<br />

also in V7<br />

UQ92692<br />

UQ89372<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 379


APAR # Area Text PTF and Notes<br />

PQ88375 RUNSTATS Correction on COLGROUP CARDINALITY <strong>for</strong><br />

partitioned table spaces<br />

PQ88582 ODBC <strong>DB2</strong> V8 ODBC now supports SQL statements up<br />

to 2 MB in size (was 32765) when connected to z<br />

<strong>DB2</strong> servers running in NFM.<br />

PQ88665 Space<br />

allocation<br />

The secondary space allocation quantity in<br />

extending <strong>DB2</strong> data set may be smaller than the<br />

one specified by the user or calculated by the<br />

sliding scale. This happens in z/<strong>OS</strong> 1.5 where<br />

extent consolidation is in effect.<br />

PQ88784 Substrings The new and changed functions allow you to<br />

specify the code unit in which the strings should be<br />

processed. The code unit determines the length in<br />

which the operation is to occur.<br />

PQ88896 Archive logs Improved per<strong>for</strong>mance when sequentially reading<br />

DFSMS compressed archive logs.<br />

PQ89070 Locks LOCK AVOIDANCE extended to singleton<br />

SELECT with ISO(CS) and CD(YES)<br />

PQ89181 Locks CPU reduction, benefitting multi-row by eliminating<br />

redundant lock/unlock requests<br />

PQ89191 Load Load zero rows into a DEFINE NO TABLESPACE<br />

sets the non partitioning index to RBDP, not leaving<br />

it in RW<br />

PQ89297 FLA FLA per<strong>for</strong>mance enhancement with priority of Log<br />

Apply phase in RECOVER and RESTORE utility<br />

inherits that of the utility batch job instead of<br />

preempted SRB priority<br />

PQ89919 Data sharing ECSA storage is not being released by <strong>DB2</strong> when<br />

it is obtained while running a REORG utility. Also to<br />

exclude deferred write from 180 CI limit removal.<br />

PQ90022<br />

(and<br />

PQ93821)<br />

Visual<br />

Explain<br />

DSN8EXP stored procedure <strong>for</strong> usage by Visual<br />

Explain so the user is authorized to Explain without<br />

being authorized to the data<br />

PQ90075 LOBs To reduce 15 second timer interval to milliseconds<br />

in order to avoid intermittent 15 second wait in<br />

commit when another agent is also updating<br />

GBP-dependent LOG YES LOB written at commit<br />

380 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UQ88754<br />

UQ91257<br />

UQ89517<br />

UQ94797<br />

UQ90143<br />

UQ91470<br />

UQ90464<br />

UQ91700<br />

also in V7<br />

UQ92067<br />

(and in V7 <strong>for</strong> Recover)<br />

UQ89194<br />

also in V7<br />

UQ92323<br />

also in V7<br />

UQ89852<br />

also in V7<br />

PQ90147 RACF Support <strong>for</strong> 1012 secondary IDs UQ92698<br />

PQ90263 X Loader Improvements <strong>for</strong> LOBs support by XLoader UK03227<br />

Also in V7<br />

PQ90547 IFCID Loss of accounting fields UQ95032<br />

PQ90884 RUNSTATS DSTATS on non-indexed columns to achieve<br />

equivalent per<strong>for</strong>mance with V7 tool<br />

UQ93177<br />

PQ91009 DDF Location name is mandatory in BSDS UQ90701


APAR # Area Text PTF and Notes<br />

PQ91101 IFC For V7 and V8, this APAR adds fields to IFCID 225<br />

to record real storage statistics in<strong>for</strong>mation. In<br />

addition, <strong>for</strong> V8 only, this APAR adds fields to IFCID<br />

225 to record some statistics in<strong>for</strong>mation <strong>for</strong> use<br />

with dynamic statement caching.<br />

UQ92441<br />

also in V7<br />

PQ91493 Locks CPU reduction, benefitting multi-row UQ91466<br />

PQ91509 EWLM Preliminary DDF EWLM support UK03835<br />

PQ91898 Locks CPU reduction, benefitting multi-row UQ92546<br />

PQ92072 Multi-row ODBC array input support of multi-row Insert UK06883<br />

PQ92227 DPSI It improves per<strong>for</strong>mance in some cases where a<br />

data-partitioned secondary index is being used to<br />

access a table. It may do this by either:<br />

1. Reducing the overhead involved with DPSI<br />

2. Avoiding the DPSI<br />

PQ92749 Check Index Online Check Index support (availability<br />

improvement)<br />

PQ93156 Restore<br />

System<br />

FLA <strong>for</strong> Restore System utility, 4x faster with 100<br />

MB<br />

PQ93620 Multi-row Multi-row Delete shows high CPU when number of<br />

rows in a Fetch/Delete call is high<br />

PQ93821 Visual<br />

Explain<br />

UQ93972<br />

UK04683<br />

UQ93079<br />

UQ96567<br />

EXPLAIN sample stored procedure DSN8EXP UQ90022<br />

PQ94147 Prepare High CPU consumption <strong>for</strong> dynamic prepare<br />

occurs when FREQVAL COUNT in SYSCOLDIST<br />

is greater than 100<br />

UK00296<br />

also V7<br />

PQ94303 MLS Correction UQ96157<br />

PQ94872 IFC It adds fields to IFCID 225 to record some statistics<br />

in<strong>for</strong>mation <strong>for</strong> use with dynamic statement<br />

caching.<br />

PQ94822 Encryption Exploitation of the clear key DES instructions on<br />

the CPACF and ICSF CLE, coreq is OA08172<br />

PQ94923 IFC It adds fields to IFCID 225 to record some statistics<br />

in<strong>for</strong>mation <strong>for</strong> use with dynamic statement<br />

caching.<br />

PQ95164 Restore<br />

System<br />

PQ95881 Application<br />

connectivity<br />

PQ96189 Max open<br />

data sets<br />

Corrections on RBLP, LPL, and FLA default<br />

changed to 500 MB (5x faster).<br />

UQ93207<br />

UK00049<br />

UQ93207<br />

UQ95553<br />

JCC T4 z/<strong>OS</strong> XA Connectivity (<strong>Version</strong> 2.3) UQ96302<br />

<strong>DB2</strong> fails data set open if 65041 reached in<br />

z/<strong>OS</strong>1.6.<br />

UQ96862<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 381


APAR # Area Text PTF and Notes<br />

PQ96628 Reorg Online Reorg Claim/Drain lock avoidance<br />

For <strong>DB2</strong> V7, the data-first claiming and table space<br />

level claim/drain will only be enabled if the new<br />

CLAIMDTA ZPARM is set to YES.<br />

For <strong>DB2</strong> V8, data-first claiming and table space<br />

level claim and drain is always enabled.<br />

382 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UK01430<br />

also in V7<br />

PQ96772 DSC Relief <strong>for</strong> large dynamic SQL cache environments UK00991<br />

PQ96956 Check Index Check Index availability UK08561, see also II14106<br />

PQ97794 Runstats Problem with incorrect sort parameter file size UQ96531<br />

PQ99524 Cancel<br />

Routines<br />

Soft cancel recovery fixes <strong>for</strong> sp/udf code paths UK01175<br />

also V7<br />

PQ99608 Logging Additional I/O wait when FORCE <strong>for</strong> identity<br />

columns is used<br />

PQ99658 IFC Availability of virtual storage diagnostic record<br />

IFCID 225 with Class 1 Statistics<br />

System parameter STATIME default time is<br />

reduced from 30 minutes to 5.<br />

IFCID 225 is added to STATISTICS trace class 1.<br />

An internal cache of IFCID 225 records is being<br />

kept <strong>for</strong> storage changes over time.<br />

PQ99707 JCC Per<strong>for</strong>mance improvement <strong>for</strong> JCC clients with<br />

EWLM<br />

PK00213<br />

PK41182<br />

REORG Display claimers on an object when REORG fails to<br />

drain<br />

UK00314<br />

UK04394<br />

UK04393 <strong>for</strong> V7<br />

UK03058<br />

UK20497<br />

UK20496 <strong>for</strong> V7<br />

PK01510 Runstats NPI clusterratio UK03490<br />

PK01841 Storage Large increase in stack storage consumption UK01844<br />

PK01855 Storage Reducing stack storage related to partitions UK01467<br />

PK01911 Latches Waits on latch 32 <strong>for</strong> RRSAF batch programs UK04743<br />

PK03293 RLF Extra resource limit facility RLST scans UK04036<br />

PK03469 Runstats Errors <strong>for</strong> RUNSTATS TABLESPACE TABLE with<br />

multiple COLGROUPs<br />

PK04076 LOAD Sort is avoided <strong>for</strong> LOAD SHRLEVEL NONE if data<br />

is sorted and only one IX exists<br />

UK03176<br />

UK03983<br />

PK05360 Multi-row Allow hybrid join <strong>for</strong> local multi-row SQL UK9531<br />

PK04107 Optimizer Bidirectional indexability between Unicode and<br />

EBCDIC<br />

UK06418<br />

PK05644 Pre<strong>for</strong>mat Pageset pre<strong>for</strong>mat quantity adjustment to 2 cyls UK08807<br />

PK09158 Bind Speed-up Bind Replace or Free by eliminating a<br />

non-linear per<strong>for</strong>mance problem<br />

PK09268 Column<br />

processing<br />

UK05786<br />

also in V7<br />

Improved CPU time <strong>for</strong> date, time and timestamp UK06505


APAR # Area Text PTF and Notes<br />

PK10021 Multi-row Support parallelism in multi-row Fetch with host<br />

variable, parameter marker, or special register<br />

UK08497<br />

PK10278 LOBs File reference variable <strong>for</strong> LOAD/REORG UK13721<br />

also V7<br />

PK10662 EDM EDM LRU chain latch reduction (LC24) <strong>for</strong> large<br />

EDM pool where no LRU replacement takes place<br />

UK07167<br />

PK11355 Block fetch Avoid block fetch disablement in a specific situation UK07192<br />

PK12389 SQL stage 1<br />

and 2<br />

predicates<br />

Enabled in compatibility mode UK10002<br />

PK13455 Partitions High getpage with page range Y on table-based<br />

partitioning<br />

PK14393 Latches High LC32 contention from concurrent prefetch<br />

requests accessing a shared storage pool<br />

UK09343<br />

UK09097<br />

PK14477 Utilities Parallel tasks in index build <strong>for</strong> LOAD and REORG UK14058<br />

also V7<br />

PK15056 Data sharing GBP-dependency not removed <strong>for</strong> pagesets after<br />

extended period<br />

PK15288 Multi-row<br />

FETCH<br />

Optimize <strong>DB2</strong> ODBC's bulk fetch to use the<br />

multi-row FETCH statement<br />

PK18059 SORTDATA Make available optional operand YES/NO <strong>for</strong><br />

SORTDATA of the REORG utility <strong>for</strong> situations of<br />

insufficient sort disk or just space reclaim.<br />

PK18162 DSNTRACE CPU per<strong>for</strong>mance problems when DSNTRACE is<br />

used (like by CAF)<br />

UK10819<br />

UK26761<br />

UK12821<br />

UK13636<br />

PK18454 DRDA DRDA over TCP/IP is OK <strong>for</strong> zIIP redirect UK15499<br />

PK19191 DRDA Change to properly increment the accounting and<br />

statistics fields using block fetching <strong>for</strong> a cursor<br />

UK12124<br />

PK19303 WLM Lock holder inherits WLM priority from lock waiter OPEN<br />

PK19769 Real storage MVS discard and pool reset to reduce thread<br />

storage<br />

UK12253<br />

PK19920 Utilities Utilities aree OK <strong>for</strong> zIIP redirect UK15814<br />

PK20157 DDF/LOBs Running out of DDF Virtual Storage with LOBs UK12328<br />

PK21237 Virtual<br />

storage<br />

DBM1<br />

PK21268 Virtual<br />

storage<br />

The buffer manager engines to use a single above<br />

the bar storage pool. The default maximum <strong>for</strong> the<br />

number of engines has been reduced <strong>for</strong> deferred<br />

write, castout and GBP engines<br />

UK14283<br />

Move CURRENT PATH storage above the bar UK14343<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 383


APAR # Area Text PTF and Notes<br />

PK21861 Virtual<br />

storage<br />

DBM1<br />

PK21892 Virtual<br />

storage<br />

DBM1<br />

PK22442 Virtual<br />

storage<br />

DDF<br />

PK22611 Locking and<br />

prefetch<br />

PK22814 Sort Merge<br />

Join<br />

Dynamic Statement Caching and bind option<br />

KEEPDYNAMIC(YES). New online ZPARM<br />

CACHEDYN_FREELOCAL indicates that a<br />

cleanup will be in effect. More instrumentation<br />

fields in the IFCID 225 <strong>for</strong> more in<strong>for</strong>mation on the<br />

cache<br />

Reduce storage use <strong>for</strong> accumulation of cached<br />

stack entries of allied agents (like ND type CICS<br />

threads)<br />

DDF storage shortage while processing long<br />

threads with KEEPDYNAMIC=YES and hundreds<br />

of output columns causing large SQLDA<br />

For data sharing users excessive drain locks<br />

acquired. For both data sharing and non-data<br />

sharing users excessive sequential prefetches<br />

scheduled<br />

384 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UK15493<br />

UK14540<br />

UK14634<br />

UK14326<br />

Cost estimation with correlated subqueries UK13671<br />

PK22887 LOBs Improve insert or update per<strong>for</strong>mance <strong>for</strong> LOB data UK15037<br />

also in V7<br />

PK22910 LOBs LOAD and UNLOAD with file reference variables UK13721<br />

also V7<br />

PK23743 Virtual<br />

storage<br />

DDF<br />

<strong>DB2</strong> storage management will monitor xxxxDIST<br />

address space storage usage. When the storage<br />

cushion <strong>for</strong> the address space is breached, <strong>DB2</strong><br />

will begin contraction of storage pools<br />

UK17364<br />

PK23495 Views Push down predicates with outer join UK14370<br />

PK23523 UNION ALL Runtime structure memory consumption UK18547<br />

PK24556<br />

PK24585<br />

DSNAIMS DSNA317I DSNAIMS ERROR IN<br />

OTMA_OPENX.A<br />

PK24558 DISPLAY Poor per<strong>for</strong>mance <strong>for</strong> -DISPLAY DATABASE<br />

SPACENAM LOCKS command<br />

PK24710 Incorrect<br />

data<br />

UK15449<br />

UK15285, see also<br />

PK24819 (UK15224) <strong>for</strong> IMS<br />

UK15650<br />

also V7<br />

Incorrect output with IN list query UK15150<br />

PK25241 LOBs Insert/update per<strong>for</strong>mance UK18503<br />

PK25326 Real storage Contract PLOCK engines storage after use UK15958<br />

PK25427 Real storage Better real frame accounting with MVS OA15666 UK12253<br />

PK25742 Utilities REORG TABLESPACE SHRLEVEL CHANGE<br />

improved building the mapping table index <strong>for</strong><br />

BUILD or SORTBLD phases<br />

PK26199 DISPLAY<br />

per<strong>for</strong>mance<br />

Per<strong>for</strong>mance improvement <strong>for</strong> -DISPLAY<br />

DATABASE SPACENAM RESTRICT<br />

or ADVISORY command<br />

UK15904<br />

PK21371<br />

(PK13555)


APAR # Area Text PTF and Notes<br />

PK26692 PREPARE Short PREPARE CPU time degradation UK18020<br />

PK26879 Latches High LC32 contention with a large number of<br />

package search lists (collid*)<br />

UK16191<br />

PK27281 SQL Non correlated EXISTS subquery UK17220<br />

PK27287 LOAD New LOAD keyword, IDENTITYOVERRIDE, which<br />

enables LOAD REPLACE to reload unloaded<br />

identity column that was created as GENERATED<br />

ALWAYS back into the same table<br />

PK27578 Parallel<br />

queries<br />

UK17369<br />

Queries are OK <strong>for</strong> zIIP redirect UK16616<br />

PK27712 Utilities LOAD, REORG, and REBUILD now show correct t<br />

accounting <strong>for</strong> zIIP<br />

PK28561 Packages IFCID239 will no longer collect package detail<br />

in<strong>for</strong>mation by default<br />

UK17089<br />

UK18090<br />

PK28637 Packages Change improves all packages and triggers UK18201<br />

PK29626 Buffer pool<br />

management<br />

Real storage management and hash chain UK17312<br />

PK29791 Data sharing Option to LIGHT mode to allow the user the default<br />

V7 behavior which ignores the INDOUBT URs and<br />

terminates after freeing retained locks.<br />

PK29826 RECOVER It allows RECOVER PARALLEL utility to run when<br />

cataloged image copy data set is moved by<br />

external means from one kind of tape device to<br />

another<br />

PK30087 REBUILD<br />

INDEX<br />

REBUILD INDEX of a single NPI over a partitioned<br />

table space may experience degradation in the<br />

BUILD phase with zIIP<br />

PK30160 INSERT Free space is not reused correctly during space<br />

search <strong>for</strong> non-segmented table spaces<br />

PK34251 TEMPLATE Three new TEMPLATE utility keywords, SUBSYS,<br />

LRECL, and RECFM, to allow dynamic allocation<br />

of a DDNAME to use MVS BATCHPIPES<br />

SUBSYSTEM<br />

UK19282<br />

UK19777<br />

UK19776 <strong>for</strong> V7<br />

UK18276<br />

UK17805<br />

UK25290<br />

UK25291 <strong>for</strong> V9<br />

PK34441 REORG Improve availability of concurrent SQL UK21950<br />

PK35390 REORG REORG SHRLEVEL REFERENCE or CHANGE:<br />

reduce elapsed time during the SWITCH phase.<br />

PK36717 INSERT Insert per<strong>for</strong>mance suffers with segmented table<br />

spaces<br />

PK37354 IFC IFCID 225 to collect buffer manager storage blocks<br />

below the bar<br />

PK38201 INSERT Storage leak with PK32606 (PE) causes long insert<br />

time<br />

UK22021<br />

UK22020 <strong>for</strong> V7<br />

UK21175<br />

UK25044<br />

more functions in V9<br />

UK23728<br />

UK23727 <strong>for</strong> V7<br />

PK40057 Prepare Avoid column level authorization checking UK24197<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 385


APAR # Area Text PTF and Notes<br />

PK46170 Precompiler Precompiler porting from V7 UK28485<br />

PK47840 INSERT Implement P-lock failure threshold of 20 to improve<br />

INSERT per<strong>for</strong>mance <strong>for</strong> row locking<br />

PK49972 CPU<br />

reduction<br />

A.2 Maintenance <strong>for</strong> <strong>DB2</strong> V7<br />

The APARs applicable to <strong>DB2</strong> V7 are listed in Table A-2.<br />

They are provided here as the most known current maintenance of interest <strong>for</strong> per<strong>for</strong>mance<br />

and availability functions, at the time of writing.<br />

Make sure to contact your <strong>IBM</strong> Service Representative <strong>for</strong> the most current maintenance at<br />

the time of your installation.<br />

Table A-2 <strong>DB2</strong> V7 per<strong>for</strong>mance-related APARs<br />

Reduce GETMAIN and FREEMAIN activity during<br />

<strong>DB2</strong> SIGNON processing <strong>for</strong> recovery coordinators<br />

such as CICS or IMS<br />

386 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UK27594<br />

UK27593 <strong>for</strong> V7<br />

OPEN<br />

APAR # Area Text PTF and Notes<br />

II13695 Migration/fall<br />

back<br />

Toleration, coexistence and compatibility PTFs<br />

between V8 and V7<br />

PQ47973 IFC A new IFCID 234 trace record is created to<br />

return user authorization in<strong>for</strong>mation via READS<br />

PQ49458 DDF 1.OPT FOR <strong>for</strong> APS and network blocking when<br />

specified<br />

2. V7 FETCH FIRST <strong>for</strong> APS but not network<br />

blocking when no OPT FOR specified<br />

If you specify the OPTIMIZE FOR n ROWS and<br />

the FETCH FIRST m ROWS clauses, <strong>DB2</strong><br />

optimizes the query <strong>for</strong> n rows.<br />

PQ54042 Access path Per<strong>for</strong>mance improvements <strong>for</strong> SQL statements<br />

containing a BETWEEN predicate<br />

PQ61458 Star join Per<strong>for</strong>mance improvement <strong>for</strong> star join using<br />

sparse index on snowflake work files<br />

PQ62695 <strong>DB2</strong><br />

Universal<br />

Driver<br />

It provides 13 stored procedures <strong>for</strong> generating a<br />

result set corresponding to the Schema Metadata<br />

APIs documented in the JDBC and ODBC<br />

specifications<br />

PQ69741 Data sharing Code changes to determine whether an idle page<br />

set in data sharing should be physically closed <strong>for</strong><br />

CL<strong>OS</strong>E YES or NO attribute of the table space or<br />

index.<br />

UQ57178<br />

UQ79775<br />

UQ61327<br />

UQ67433<br />

UQ72083<br />

UQ74866<br />

Included in <strong>DB2</strong> V8


APAR # Area Text PTF and Notes<br />

PQ69741 Data sharing Close inactive GBP-dependent object if CL<strong>OS</strong>E Y<br />

to minimize per<strong>for</strong>mance disruption at the<br />

beginning of the day <strong>for</strong> example:<br />

Alter CL<strong>OS</strong>E Y from N if the old behavior is desired.<br />

PQ69983 Accounting It needs also V7 PQ74772 (<strong>DB2</strong> PE) to fix incorrect<br />

ET and CPU time in accounting <strong>for</strong> SP, UDF,<br />

triggers<br />

PQ71179 LOBs LOB space reuse code has been changed to rely<br />

upon read-LSN processing as be<strong>for</strong>e, but if<br />

read-LSN processing fails then a lock is obtained<br />

on the deallocated LOB to determine<br />

whether the page owned by the deallocated LOB<br />

can safely be reused<br />

PQ71766 Data spaces Avoid multiple I/Os resulting from single prefetch or<br />

deferred write request when multiple data spaces<br />

exist<br />

PQ71775 Catalog<br />

query<br />

Per<strong>for</strong>mance improvement <strong>for</strong> catalog consistency<br />

query DSNTSEQ, 200x faster by query rewrite<br />

PQ75064 Statistics Avoid incremental bind count in statistics <strong>for</strong> SP call<br />

with name in hv when the match is found in cache<br />

PQ78515 RDS This fix checks every ten minutes to see if RDS OP<br />

pool is greater than 50 MB. If it is greater than 50<br />

mb, then with fix applied it contracts/defragments<br />

only the leftover and unused storage. It does not<br />

flush any reusable parts of the RDS OP pool.<br />

PQ79232 DSMAX Increasing DSMAX and activating it via SET<br />

SYSPARM do not use new value even though trace<br />

shows new value<br />

PQ80631 Dependent<br />

routines<br />

Support <strong>for</strong> dependent WLM-managed routines<br />

interface. This APAR along with WLM APAR<br />

OA04555 5/04 on z/<strong>OS</strong>1.4 allows <strong>DB2</strong> to in<strong>for</strong>m<br />

WLM when inserting work that there is an in-use<br />

WLM server TCB waiting <strong>for</strong> this work to complete.<br />

This will allow WLM to be more responsive in<br />

starting server address spaces.<br />

PQ81904 RDS Use of thread rather than shared pool to reduce<br />

cl32 latch contention (RDS OP pool)<br />

PQ82878 Striping Partitioned TS ran out of 123 extents with striped<br />

data sets with 3 track minimum extent size because<br />

primary volume did not have sufficient free space<br />

PQ84160 Xloader Xloader per<strong>for</strong>mance 2x improvement, now even<br />

with Unload and Load<br />

UQ74866<br />

UQ77215<br />

UQ77421<br />

UQ75848<br />

UQ85043<br />

UQ79020<br />

UQ83466<br />

UQ81754<br />

UQ90158<br />

also in V8<br />

UQ84631<br />

UQ90793<br />

also in V8<br />

UQ91416<br />

also in V8<br />

PQ85764 IFI IFCID 225 available via READS UQ87093<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 387


APAR # Area Text PTF and Notes<br />

PQ85843 Data sharing Castout to skip 180CI limit if serviceability IFCID<br />

338 on to remove CPU spikes every 15 sec caused<br />

by excessive unlock castout and delete namelist.<br />

V8 PQ86071 4/04 unconditionally <strong>for</strong> all async I/O<br />

such as DASD read and castout.<br />

PQ86037 Insert Insert at end option <strong>for</strong> Member Cluster TS, with<br />

Alter TS <strong>for</strong> 0 PCTFREE and FREEPAGE to always<br />

search <strong>for</strong>ward <strong>for</strong> free space in Insert into MC TS<br />

to avoid periodically reading space map pages<br />

from the beginning costing >10sec, also heavy<br />

space map latch contention, <strong>for</strong> any page size.<br />

Load Replace dummy or REORG as needed if<br />

deletes later.<br />

PQ86049 Data sharing Request preference <strong>for</strong> CFLEVEL 13 instead of 7<br />

<strong>for</strong> GBP allocation to reduce high CF utilization and<br />

use read castout class<br />

PQ86477 IFC The IFCID flat file <strong>for</strong> V7 and V8 now contains<br />

current in<strong>for</strong>mation.<br />

PQ87126 Virtual<br />

storage<br />

Excessive DBM1 VS use with KEEPDYN Y and<br />

input decimal hv (also V8)<br />

PQ87381 Insert Insert per<strong>for</strong>mance suffers because of exhaustive<br />

search <strong>for</strong> space to extending the page set<br />

PQ87447 Catalog<br />

query<br />

Query 5 and 18 of the DSNTESQ catalog<br />

consistency queries per<strong>for</strong>m slowly<br />

PQ87783 Data sharing Correct false contention counter when 1 member in<br />

LPAR. If multiple members in the same data<br />

sharing group on the same LPAR (rather rare),<br />

false contention overreported. Needs <strong>DB2</strong> PE fix<br />

as of 8/04<br />

PQ87917 I/O I/O per<strong>for</strong>mance on ESS/2105 devices can be<br />

improved by utilizing the "bypass read/write<br />

serialization" option. It is already done <strong>for</strong> writer,<br />

this APAR adds support <strong>for</strong> reader.<br />

Support R/W I/O concurrency in same defined<br />

domain (but not same track). ESS “bypass define<br />

extent serialization” set by <strong>DB2</strong> is disabled when<br />

XRC/PPRC/FlashCopy in progress.<br />

PQ88587 Load LOAD utility with STATISTICS INDEX keywords<br />

specified at many tables present, appears to loop<br />

and completes with high elapsed time.<br />

PQ89191 Load Load zero rows into a DEFINE NO TABLESPACE<br />

sets the non partitioning index to RBDP, not leaving<br />

it in RW.<br />

PQ89297 FLA FLA per<strong>for</strong>mance enhancement with priority of Log<br />

Apply phase in RECOVER and RESTORE utility<br />

inherits that of the utility batch job instead of<br />

preempted SRB priority<br />

388 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UQ86458<br />

UQ86868<br />

also V8 (PQ87391) +PQ99524<br />

UQ87321<br />

UQ92474<br />

also in V8<br />

UQ88970<br />

UK06753<br />

also in V8<br />

UQ90653<br />

also in V8<br />

UQ88734<br />

UQ886790<br />

also in V8<br />

UQ89026<br />

UQ91968<br />

also in V8<br />

UQ92066<br />

(and V8 <strong>for</strong> Restore)


APAR # Area Text PTF and Notes<br />

PQ89919 Reorg ECSA storage is not being released by <strong>DB2</strong> when<br />

it is obtained while running a REORG utility.<br />

PQ89919 Data Sharing To exclude write<br />

1. IRWW non data sharing: +2.9% ITR, -3% CPU,<br />

IRWW 2way data sharing: +4.8% ITR, -4.4% CPU<br />

-> less improvement after excluding write, 0to3%<br />

instead of 0to4%?<br />

2. More pages read per list prefetch, reduced<br />

Unlock Castout (#async writes in GBP-dep LBP<br />

stats), reduced DBM1 SRB time<br />

PQ90022<br />

(and<br />

PQ93821)<br />

Visual<br />

Explain<br />

DSN8EXP stored procedure <strong>for</strong> usage by Visual<br />

Explain so the user in authorized to Explain without<br />

being authorized to the data<br />

PQ90075 LOBs To reduce 15 second timer interval to milliseconds<br />

in order to avoid intermittent 15 second wait in<br />

commit when another agent is also updating<br />

GBP-dependent LOG YES LOB written at commit<br />

PQ90263 Xloader<br />

LOBs<br />

UQ89190<br />

also in V8<br />

UQ89190<br />

also in V8<br />

UQ92322<br />

UQ89850<br />

also in V8<br />

>32 KB support UK03226<br />

also in V8<br />

PQ91101 IFC For V7 and V8, this APAR adds fields to IFCID 225<br />

to record real storage statistics in<strong>for</strong>mation. In<br />

addition, <strong>for</strong> V8 only, this APAR adds fields to IFCID<br />

225 to record some statistics in<strong>for</strong>mation <strong>for</strong> use<br />

with dynamic statement caching.<br />

PQ93009 Online stats New criteria <strong>for</strong> DSNACCOR to recommend<br />

RUNSTATS<br />

PQ94147 Bind To reduce bind time by hashing instead of<br />

sequential search on SYSCOLDIST entries in<br />

DSNXOCN, -6.7x CPU<br />

PQ94793 Data Sharing ABEND04E RC00D10340 in DSNJR006<br />

attempting to read/merge the logs in a data sharing<br />

environment. Also <strong>for</strong> <strong>DB2</strong> V7.<br />

PQ96628 Reorg Online Reorg Claim/Drain lock avoidance<br />

For <strong>DB2</strong> V7, the data-first claiming and table space<br />

level claim/drain will only be enabled if the new<br />

CLAIMDTA ZPARM is set to YES.<br />

For <strong>DB2</strong> V8, data-first claiming and table space<br />

level claim and drain is always enabled.<br />

PQ99524 Cancel<br />

Routines<br />

Soft cancel recovery fixes <strong>for</strong> stored procedures<br />

and UDFs code paths<br />

PQ99658 Statistics Availability of virtual storage diagnostic record<br />

IFCID 225 with Class 1 Statistics.<br />

System parameter STATIME default time is<br />

reduced from 30 minutes to 5.<br />

IFCID 225 is added to STATISTICS trace class 1.<br />

An internal cache of IFCID 225 records is being<br />

kept <strong>for</strong> storage changes over time.<br />

UQ92440<br />

also in V8<br />

UQ93893<br />

UK00295<br />

UQ93407<br />

UK01429<br />

also in V8<br />

UK01174<br />

also in V8<br />

UK04393<br />

also in V8<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 389


APAR # Area Text PTF and Notes<br />

PK09158 Bind Speed-up Bind Replace or Free by eliminating a<br />

non-linear per<strong>for</strong>mance problem<br />

A.3 Maintenance <strong>for</strong> z/<strong>OS</strong><br />

The APARs applicable to z/<strong>OS</strong> are listed in Table A-3.<br />

They are provided here as the most known current maintenance of interest <strong>for</strong> per<strong>for</strong>mance<br />

and availability functions, at the time of writing.<br />

Make sure to contact your <strong>IBM</strong> Service Representative <strong>for</strong> the most current maintenance at<br />

the time of your installation.<br />

Table A-3 z/<strong>OS</strong> <strong>DB2</strong> per<strong>for</strong>mance-related APARs<br />

390 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UK05785<br />

also <strong>for</strong> V8<br />

PK14477 Utilities Parallel tasks in index build <strong>for</strong> LOAD and REORG UK14057<br />

also V8<br />

PK22887 LOBs Improve insert or update per<strong>for</strong>mance <strong>for</strong> LOB data UK15036<br />

also V8<br />

PK24558 DISPLAY Poor per<strong>for</strong>mance <strong>for</strong> -DISPLAY DATABASE<br />

SPACENAM LOCKS command<br />

PK47840 INSERT Implement P-lock failure threshold of 20 to improve<br />

INSERT per<strong>for</strong>mance <strong>for</strong> row locking<br />

UK15649<br />

also V8<br />

UK27593<br />

UK27594 <strong>for</strong> V8<br />

APAR # Area Text PTF and Notes<br />

OA06729 Coupling<br />

Facility<br />

To avoid delay in getting asynchronous (heuristic<br />

synchronous to asynchronous conversion) lock<br />

request to be processed. Also fix inconsistent stats<br />

on lock request and contention.<br />

OA04555 WLM The WLM queue/server management application<br />

interfaces are changed by this SPE to allow an<br />

application to in<strong>for</strong>m WLM that a work request with<br />

a dependency to other work already in progress is<br />

inserted.<br />

OA05960 Extents The request <strong>for</strong> an extend to a specific CI or RBA<br />

number through Media Manager Services is now<br />

honored <strong>for</strong> all cases.<br />

UA11478<br />

UA11478<br />

UA11479<br />

UA11480<br />

UA11481<br />

UA11482<br />

UA11154<br />

UA11155<br />

UA11156<br />

UA08703<br />

OA07196 EWLM Function UA15188<br />

UA15189<br />

OA07356 EWLM Function UA15456<br />

OA08172 Encryption Enable more exploitation of the clear key DES<br />

instructions on the CPACF<br />

UA15677<br />

UA156780<br />

UA15679<br />

OA12005 EWLM Per<strong>for</strong>mance improvement UA22388


APAR # Area Text PTF and Notes<br />

OA15666 Storage DISCARDDATA request support UA27812<br />

OA17114 Storage Reduce excessive amount of fixed frames above<br />

the line (but below the bar)<br />

UA34634<br />

Appendix A. Summary of per<strong>for</strong>mance maintenance 391


392 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Appendix B. The DBM1 storage map<br />

B<br />

In this appendix we describe in more details the contents of the <strong>DB2</strong> PE Storage Statistics<br />

reports.<br />

We provide a description <strong>for</strong> the headings in the three sections of the report and point out<br />

what is applicable <strong>for</strong> V7 or V8 of <strong>DB2</strong>.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 393


B.1 <strong>DB2</strong> PE Storage Statistics trace and report<br />

This section describes the PE Storage Statistics report and all the fields contained in the<br />

report.<br />

It is important to know that this trace and report layout is used not only <strong>for</strong> <strong>DB2</strong> V8 but also <strong>for</strong><br />

the other supported versions of <strong>DB2</strong>. As a result, some of the in<strong>for</strong>mation in this report, when<br />

associated with a previous version (like a <strong>DB2</strong> V7 subsystem) is not available (N/A) or<br />

reported differently, and there<strong>for</strong>e shown as N/A. These storage headings are designated in<br />

bold characters in the tables below.<br />

The Storage Statistics trace has the following three different storage blocks:<br />

► DBM1 AND MVS STORAGE BELOW 2 GB<br />

► DBM1 AND MVS STORAGE ABOVE 2 GB<br />

► REAL AND AUXILIARY STORAGE<br />

The storage quantities are shown in MB; as a result, you need to multiply the number by<br />

1024x1024 to get the actual number of bytes.<br />

Table B-1 summarizes the storage areas below the 2 GB bar.<br />

Table B-1 DBM1 AND MVS STORAGE BELOW 2 GB<br />

Storage heading Description<br />

TOTAL DBM1 STORAGE BELOW 2 GB Sum of<br />

TOTAL GETMAINED STORAGE<br />

TOTAL VARIABLE STORAGE<br />

TOTAL FIXED STORAGE<br />

TOTAL GETMAINED STACK STORAGE<br />

TOTAL GETMAINED STORAGE Total storage acquired by GETMAIN macro. This includes space <strong>for</strong><br />

virtual pools, EDM pool, compression dictionaries, castout buffers, data<br />

space lookaside buffer, hiper pool control blocks, and data space buffer<br />

pool control blocks<br />

VIRTUAL BUFFER POOLS Total storage allocated <strong>for</strong> virtual buffer pools<br />

VIRTUAL POOL CONTROL BLOCKS Total storage allocated <strong>for</strong> virtual pool control blocks. Each virtual pool<br />

control block is 128 bytes resulting in 128 * (VIRTUAL BUFFER<br />

POOLS)<br />

EDM POOL Total storage <strong>for</strong> plans and packages in EDM pool<br />

COMPRESSION DICTIONARY Total storage <strong>for</strong> compression dictionaries<br />

CASTOUT BUFFERS Total storage <strong>for</strong> data sharing castout buffers<br />

DATA SPACE LOOKASIDE BUFFER Total storage <strong>for</strong> data space lookaside buffers<br />

HIPERPOOL CONTROL BLOCKS Total storage <strong>for</strong> hiper pool control blocks - 56 bytes <strong>for</strong> each hiper pool<br />

page<br />

DATA SPACE BP CONTROL BLOCKS Total storage <strong>for</strong> data space buffer pool control blocks - a control block<br />

is 128 bytes and one is allocated <strong>for</strong> each data space page<br />

TOTAL VARIABLE STORAGE Total storage used by all variables. This includes storage <strong>for</strong>:<br />

system agents, local agents, RID pool, pipe manager subpool, local<br />

dynamic cache storage blocks, local dynamic statement cache<br />

statement pool, buffer and data manager trace tables<br />

394 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Storage heading Description<br />

TOTAL AGENT LOCAL STORAGE The amount of storage allocated <strong>for</strong> agent-related local storage <strong>for</strong><br />

operations such as sort.<br />

TOTAL AGENT SYSTEM STORAGE Storage consumed by the various system agents, prefetch, castout, and<br />

deferred write engines.<br />

NUMBER OF PREFETCH ENGINES Number of engines used <strong>for</strong> sequential, list, and dynamic prefetch<br />

NUMBER OF DEFERRED WRITE ENGINES Number of engines used <strong>for</strong> deferred write operations<br />

NUMBER OF CASTOUT ENGINES Number of engines used <strong>for</strong> data sharing castout engines<br />

NUMBER OF GBP WRITE ENGINES Number of write engines used <strong>for</strong> group buffer pools<br />

NUMBER OF P-LOCK/NOTIFY EXIT<br />

ENGINES<br />

Number of engines used <strong>for</strong> data sharing P-lock or notify exit conditions<br />

TOTAL AGENT NON-SYSTEM STORAGE This is a derived field:<br />

TOTAL AGENT LOCAL STORAGE - TOTAL AGENT SYSTEM<br />

STORAGE<br />

TOTAL NUMBER OF ACTIVE USER<br />

THREADS<br />

Includes all active allied threads and the current number of active<br />

DBATs (derived from IFCID 225 and 001)<br />

RDS OP POOL Total storage <strong>for</strong> RDS operations pool used <strong>for</strong> sort, prepare, and other<br />

common functions. In V8 it is only used <strong>for</strong> binding (prepare)<br />

RID POOL Storage used by list prefetch, multiple index access processing, and<br />

hybrid joins; maximum size specified by DSNZPARM MAXRBLK<br />

PIPE MANAGER SUB POOL Storage allocated to pipe manager <strong>for</strong> parallel query operations<br />

LOCAL DYNAMIC STMT CACHE CNTL<br />

BLKS<br />

THREAD COPIES OF CACHED SQL<br />

STMTS<br />

Storage <strong>for</strong> local dynamic statement cache blocks<br />

Storage used <strong>for</strong> the local dynamic statement cache pool<br />

IN USE STORAGE The amount of storage used <strong>for</strong> thread copies in the local cache storage<br />

pool. This is a subset of the total allocated storage <strong>for</strong> THREAD<br />

COPIES OF CACHED SQL STMTS<br />

STATEMENTS COUNT Number of SQL statements in cached pools<br />

HWM FOR ALLOCATED STATEMENTS A statistics interval high water mark of allocated storage <strong>for</strong> thread<br />

copies in the local cache storage pool<br />

STATEMENT COUNT AT HWM The number of statements in the local cache storage pool at high<br />

storage time<br />

DATE AT HWM Date at high water mark <strong>for</strong> storage<br />

TIME AT HWM Timestamp at high water mark <strong>for</strong> storage<br />

BUFFER & DATA MANAGER TRACE TBL Storage used <strong>for</strong> Buffer and Data Manager trace tables<br />

TOTAL FIXED STORAGE Total amount of long-term page fixed storage<br />

TOTAL GETMAINED STACK STORAGE Total GETMAINed storage allocated <strong>for</strong> program stack use<br />

STORAGE CUSHION Storage reserved to allow <strong>DB2</strong> to complete critical functions while<br />

short-on-storage. This includes the contract warning cushion, storage<br />

reserved <strong>for</strong> must-complete operations, and storage <strong>for</strong> MVS use.<br />

Appendix B. The DBM1 storage map 395


Storage heading Description<br />

24 BIT LOW PRIVATE Amount of private MVS storage below the 16 MB line. This storage is<br />

obtained from bottom upward, usually <strong>for</strong> unauthorized programs<br />

24 BIT HIGH PRIVATE Amount of private MVS storage below 16 MB line. This storage is<br />

obtained from top downward, usually <strong>for</strong> authorized programs<br />

31 BIT EXTENDED LOW PRIVATE Amount of private MVS storage above 16 MB line. This storage is<br />

obtained from bottom upward, usually <strong>for</strong> unauthorized programs<br />

31 BIT EXTENDED HIGH PRIVATE Amount of private MVS storage above 16 MB line. This storage is<br />

obtained from top downward, usually <strong>for</strong> authorized programs<br />

EXTENDED REGION SIZE (MAX) Maximum amount of MVS private storage available above the 16 MB<br />

line<br />

EXTENDED CSA SIZE The size of the common storage area (ECSA) above the 16 MB line<br />

AVERAGE THREAD FOOTPRINT The current average memory usage of active user threads.<br />

Derived as (TOTAL VARIABLE STORAGE - TOTAL AGENT SYSTEM<br />

STORAGE) / (ALLIED THREADS + DBATS)<br />

MAX NUMBER OF P<strong>OS</strong>SIBLE THREADS The maximum number of possible threads dependent on storage size<br />

and average thread footprint<br />

Table B-2 summarizes all of the storage areas above the 2 GB bar.<br />

Table B-2 DBM1 STORAGE ABOVE 2 GB<br />

Storage heading Description<br />

FIXED STORAGE Total amount of long-term page fixed storage<br />

GETMAINED STORAGE Total storage acquired by GETMAIN macro. This includes space <strong>for</strong><br />

buffer pools, EDM pool, compression dictionaries and castout buffers<br />

COMPRESSION DICTIONARY Total storage <strong>for</strong> compression dictionaries<br />

CACHED DYNAMIC SQL STATEMENTS<br />

(MAX)<br />

Table B-3 describes the amount of real and auxiliary storage in use.<br />

396 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Maximum size of the dynamic statement cache. Since it can be<br />

increased and decreased dynamically using SET SYSPARM, this is its<br />

maximum value.<br />

DBD CACHE (MAX) Maximum size of the DBD cache. Since it can be increased and<br />

decreased dynamically using SET SYSPARM, this is its maximum<br />

value.<br />

VARIABLE STORAGE Amount of variable storage<br />

VIRTUAL BUFFER POOLS Total storage allocated <strong>for</strong> buffer pools<br />

VIRTUAL POOL CONTROL BLOCKS Total storage allocated <strong>for</strong> buffer pool control blocks<br />

CASTOUT BUFFERS Total storage used <strong>for</strong> castout buffers in data sharing<br />

STAR JOIN MEMORY POOL Total storage used <strong>for</strong> star join cache <strong>for</strong> data and keys


Table B-3 REAL AND AUXILIARY STORAGE<br />

Storage heading Description<br />

REAL STORAGE IN USE Number of real frames (4K) in use<br />

AUXILIARY STORAGE IN USE Number of auxiliary slots (4k) in use<br />

Appendix B. The DBM1 storage map 397


398 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Appendix C. SQL PA sample reports<br />

In this appendix we show samples of the new SQL PA reports illustrating some of the <strong>DB2</strong> V8<br />

functionality.<br />

For more in<strong>for</strong>mation on SQL PA <strong>Version</strong> 2.2, refer to the white paper Achieving Maximum<br />

Productivity With <strong>DB2</strong> SQL Per<strong>for</strong>mance Analyzer available from:<br />

http://www.ibm.com/software/data/db2imstools/db2tools/db2sqlpa.html<br />

C<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 399


C.1 <strong>DB2</strong> SQL PA additional reports<br />

Notice that the index used has a NOT PADDED attribute and a cartesian join was detected.<br />

Example C-1 reports the query definition and also some good news <strong>for</strong> the query.<br />

Example: C-1 SQL PA query description<br />

================================================================================<br />

SQL PA ANALYSIS FOR QUERYNO 100000001<br />

SELECT COUNT(*) FROM<br />

SYS<strong>IBM</strong>.SYSPACKSTMT A, SYS<strong>IBM</strong>.SYSPACKDEP B<br />

WHERE A.LOCATION = ? AND<br />

B.DLOCATION = ? AND<br />

B.DCOLLID = ? AND<br />

A.COLLID ?<br />

QUERYNO: 100000001 QBLOCKNO: 1 PLANNO: 1 MIXOPSEQ: 0<br />

PROCESS -><br />

+------------------------------------------------------------------+<br />

|ANL7002I *** GUIDELINE: |<br />

|This plan step has not selected any Sequential|List Prefetch I/O. |<br />

|If the SQL processes just a few rows that is OK, but if many rows |<br />

|are involved, you can help promote Sequential Detection by both |<br />

|accessing the data in sequential order (presort?) and by binding |<br />

|with Release (Deallocate) to avoid resetting counters at Commit. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7005I *** GOOD NEWS: |<br />

|This SQL features a Unique Index being used to access the table |<br />

|that can avoid Distinct Sorts with Group By and Count Distinct C1.|<br />

|Also, unique index will avoid 4K "in memory table" on Correlated |<br />

|Subquery, considers special access path when used with "=" preds, |<br />

|and may convert Subquery to Join on IN, =ANY or =SOME predicates. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL6005I *** NOTE: |<br />

|This statement contains a Built in Column Function: however, it |<br />

|is not being processed at either Stage 1 Retrieval or Sort Time. |<br />

|In general, this means poor per<strong>for</strong>mance, because the column(s) get|<br />

|evaluated only at the end of Stage 2 processing. This might be due|<br />

|to multiple columns used, Group By, not all Stage 1 preds, etc. |<br />

+------------------------------------------------------------------+<br />

Example C-2 provides in<strong>for</strong>mation about the indexes.<br />

Example: C-2 SQL PA index in<strong>for</strong>mation<br />

ACCESS IS VIA THE CLUSTERING (INSERT & LOAD ORDER) INDEX FOR THIS TABLE<br />

+------------------------------------------------------------------+<br />

|ANL5018W *** ALERT: |<br />

400 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


|This clustering (insert) index has a low cluster ratio (below 80) |<br />

|and/or is not well clustered (Clustered flag = N), meaning that |<br />

|inserts are following an unclustered pattern: this is not helpful.|<br />

|You should Reorganize your Table and Index, and re-run Runstats to|<br />

|update these statistics. That should result in better access paths|<br />

|and per<strong>for</strong>mance in general. |<br />

+------------------------------------------------------------------+<br />

RANDOM MATCH IX SCAN<br />

--------------------<br />

IX CREATOR: SYS<strong>IBM</strong><br />

INDEX NAME: DSNKSX01<br />

VERS: 1 KEY LEN: -1 PADDED: N C-ED: N C-ING: Y CLURATIO: 10.0000<br />

FULLKEY CARD: 25 FIRSTKEY CARD: 25<br />

TYPE: 2 NLEAF PAGES: 34 NLEVELS: 2 UNIQUE: U DECLARE UNIQ<br />

1 OF 5 COLUMNS ARE MATCHED CL<strong>OS</strong>E: N LOCK MODE: IS BPOOL: BP0<br />

KEY COLUMN NAME ORDER TYPE DIST LEN NULL COLCARD DIST#<br />

------------------------------------------------------------------------<br />

1 LOCATION A VARCHAR N 128 N -1 0<br />

2 COLLID A VARCHAR N 128 N -1 0<br />

3 NAME A VARCHAR N 128 N -1 0<br />

4 CONTOKEN A CHAR N 8 N -1 0<br />

5 SEQNO A SMALLINT N 2 N -1 0<br />

+------------------------------------------------------------------+<br />

|ANL6052I *** NOTE: |<br />

|This index is specified as "Not Padded", allowing storage of a |<br />

|varying length index key. Padded indexes use blanks to fill out |<br />

|their fixed length keys and are not eligible <strong>for</strong> Index Only scan. |<br />

|"Not Padded" indexes do not blank fill CHAR and VARCHAR columns, |<br />

|allowing greater flexibility and better use of storage, packing |<br />

|more entries into a single Leaf page. Index Only access allowed. |<br />

+------------------------------------------------------------------+<br />

NOTE: NO ALTERNATIVE INDEXES AVAILABLE FOR THIS TABLE<br />

+------------------------------------------------------------------+<br />

|ANL6016I *** NOTE: |<br />

|Presently this query is only matching some of the indexed columns |<br />

|on this index key. Maximizing use of Stage 1 predicates against |<br />

|these index columns will improve per<strong>for</strong>mance, by matching and/or |<br />

|screening rows and there<strong>for</strong>e reducing data page I/O requirements. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7034I *** GOOD NEWS: |<br />

|This index is Not Padded, making it a true variable length index. |<br />

|"Index Only" access is now possible and <strong>DB2</strong> will compare CHAR and |<br />

|VARCHAR columns of unequal length against this index during Stage |<br />

|1 processing. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7009I *** GUIDELINE: |<br />

|On composite (multi-column) indexes, favor matching index scan of |<br />

|as many columns as possible, using Equals (=), Range (>,,


|is the last matching predicate. Apply left to right against index |<br />

|columns, skipping no columns in the L-R sequence. <strong>DB2</strong> may "screen"|<br />

|remaining Stage 1 preds against the rid list be<strong>for</strong>e data access. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7010I *** GUIDELINE: |<br />

|On composite (multi-column) indexes, collect correlated key stats |<br />

|on column pairings, as well as cardinality stats, like 2ndkeycard,|<br />

|3rdkeycard, etc., with Runstats. These additional statistics will |<br />

|allow <strong>DB2</strong> to make better filter estimates <strong>for</strong> Equality and Range |<br />

|and In List predicates, thereby selecting proper indexes and more |<br />

|realistic estimates <strong>for</strong> rows returned from the query (QCARD). |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7024I *** GOOD NEWS: |<br />

|Index Screening is now available <strong>for</strong> List Prefetch processing, |<br />

|which allows Random indexes to "screen" additional predicates |<br />

|after matching index scan, and be<strong>for</strong>e data access. |<br />

+------------------------------------------------------------------+<br />

THIS IS AN "INDEX ONLY" ACCESS: NO DATA PAGES ARE READ FROM THE TABLE<br />

+------------------------------------------------------------------+<br />

|ANL7015I *** GUIDELINE: |<br />

|Collecting Non-uni<strong>for</strong>m column statistics greatly enhance the <strong>DB2</strong> |<br />

|Optimizer accuracy when processing Equals and In (List) preds. |<br />

+------------------------------------------------------------------+<br />

Example C-3 shows the analysis of the query.<br />

Example: C-3 SQL PA query analysis<br />

A JOIN OF 2 TABLES HAS BEEN DETECTED. THIS WAS THE FIRST TABLE ACCESS.<br />

+------------------------------------------------------------------+<br />

|ANL7023I *** GOOD NEWS: |<br />

|Equi-join predicates of unequal length may be handled at stage 1: |<br />

|<strong>DB2</strong> pads out CHAR and VARCHAR column types to accomplish the join.|<br />

+------------------------------------------------------------------+<br />

--------------------------------------------------------------------------------<br />

QUERYNO: 100000001 QBLOCKNO: 1 PLANNO: 2 MIXOPSEQ: 0<br />

PROCESS -><br />

+------------------------------------------------------------------+<br />

|ANL7002I *** GUIDELINE: |<br />

|This plan step has not selected any Sequential|List Prefetch I/O. |<br />

|If the SQL processes just a few rows that is OK, but if many rows |<br />

|are involved, you can help promote Sequential Detection by both |<br />

|accessing the data in sequential order (presort?) and by binding |<br />

|with Release (Deallocate) to avoid resetting counters at Commit. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL6005I *** NOTE: |<br />

402 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


|This statement contains a Built in Column Function: however, it |<br />

|is not being processed at either Stage 1 Retrieval or Sort Time. |<br />

|In general, this means poor per<strong>for</strong>mance, because the column(s) get|<br />

|evaluated only at the end of Stage 2 processing. This might be due|<br />

|to multiple columns used, Group By, not all Stage 1 preds, etc. |<br />

+------------------------------------------------------------------+<br />

ACCESS IS VIA THE CLUSTERING (INSERT & LOAD ORDER) INDEX FOR THIS TABLE<br />

+------------------------------------------------------------------+<br />

|ANL5018W *** ALERT: |<br />

|This clustering (insert) index has a low cluster ratio (below 80) |<br />

|and/or is not well clustered (Clustered flag = N), meaning that |<br />

|inserts are following an unclustered pattern: this is not helpful.|<br />

|You should Reorganize your Table and Index, and re-run Runstats to|<br />

|update these statistics. That should result in better access paths|<br />

|and per<strong>for</strong>mance in general. |<br />

+------------------------------------------------------------------+<br />

RANDOM MATCH IX SCAN<br />

--------------------<br />

IX CREATOR: SYS<strong>IBM</strong><br />

INDEX NAME: DSNKDX01<br />

VERS: 1 KEY LEN: -1 PADDED: N C-ED: N C-ING: Y CLURATIO: 10.0000<br />

FULLKEY CARD: 25 FIRSTKEY CARD: 25<br />

TYPE: 2 NLEAF PAGES: 34 NLEVELS: 2 UNIQUE: D DUPLICATE OK<br />

2 OF 4 COLUMNS ARE MATCHED CL<strong>OS</strong>E: N LOCK MODE: IS BPOOL: BP0<br />

KEY COLUMN NAME ORDER TYPE DIST LEN NULL COLCARD DIST#<br />

------------------------------------------------------------------------<br />

1 DLOCATION A VARCHAR N 128 N -1 0<br />

2 DCOLLID A VARCHAR N 128 N -1 0<br />

3 DNAME A VARCHAR N 128 N -1 0<br />

4 DCONTOKEN A CHAR N 8 N -1 0<br />

+------------------------------------------------------------------+<br />

|ANL6052I *** NOTE: |<br />

|This index is specified as "Not Padded", allowing storage of a |<br />

|varying length index key. Padded indexes use blanks to fill out |<br />

|their fixed length keys and are not eligible <strong>for</strong> Index Only scan. |<br />

|"Not Padded" indexes do not blank fill CHAR and VARCHAR columns, |<br />

|allowing greater flexibility and better use of storage, packing |<br />

|more entries into a single Leaf page. Index Only access allowed. |<br />

+------------------------------------------------------------------+<br />

ALTERNATIVE INDEX<br />

+++++++++++++++++<br />

CREATOR: SYS<strong>IBM</strong><br />

IX NAME: DSNKDX02<br />

VERS: 1 KEY LEN: -1 PADDED: N C-ED: N C-ING: N CLURATIO: 0.0000<br />

FULLKEY CARD: -1 FIRSTKEY CARD: -1<br />

TYPE: 2 NLEAF PAGES: -1 NLEVELS: -1 UNIQUE: D KEY COLS: 3<br />

1 A -1 BQUALIFIER<br />

2 A -1 BNAME<br />

3 A -1 BTYPE<br />

+------------------------------------------------------------------+<br />

Appendix C. SQL PA sample reports 403


|ANL6052I *** NOTE: |<br />

|This index is specified as "Not Padded", allowing storage of a |<br />

|varying length index key. Padded indexes use blanks to fill out |<br />

|their fixed length keys and are not eligible <strong>for</strong> Index Only scan. |<br />

|"Not Padded" indexes do not blank fill CHAR and VARCHAR columns, |<br />

|allowing greater flexibility and better use of storage, packing |<br />

|more entries into a single Leaf page. Index Only access allowed. |<br />

+------------------------------------------------------------------+<br />

ALTERNATIVE INDEX<br />

+++++++++++++++++<br />

CREATOR: SYS<strong>IBM</strong><br />

IX NAME: DSNKDX03<br />

VERS: 1 KEY LEN: -1 PADDED: N C-ED: N C-ING: N CLURATIO: 0.0000<br />

FULLKEY CARD: -1 FIRSTKEY CARD: -1<br />

TYPE: 2 NLEAF PAGES: -1 NLEVELS: -1 UNIQUE: D KEY COLS: 4<br />

1 A -1 BQUALIFIER<br />

2 A -1 BNAME<br />

3 A -1 BTYPE<br />

4 A -1 DTYPE<br />

+------------------------------------------------------------------+<br />

|ANL6052I *** NOTE: |<br />

|This index is specified as "Not Padded", allowing storage of a |<br />

|varying length index key. Padded indexes use blanks to fill out |<br />

|their fixed length keys and are not eligible <strong>for</strong> Index Only scan. |<br />

|"Not Padded" indexes do not blank fill CHAR and VARCHAR columns, |<br />

|allowing greater flexibility and better use of storage, packing |<br />

|more entries into a single Leaf page. Index Only access allowed. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL6016I *** NOTE: |<br />

|Presently this query is only matching some of the indexed columns |<br />

|on this index key. Maximizing use of Stage 1 predicates against |<br />

|these index columns will improve per<strong>for</strong>mance, by matching and/or |<br />

|screening rows and there<strong>for</strong>e reducing data page I/O requirements. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7034I *** GOOD NEWS: |<br />

|This index is Not Padded, making it a true variable length index. |<br />

|"Index Only" access is now possible and <strong>DB2</strong> will compare CHAR and |<br />

|VARCHAR columns of unequal length against this index during Stage |<br />

|1 processing. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7009I *** GUIDELINE: |<br />

|On composite (multi-column) indexes, favor matching index scan of |<br />

|as many columns as possible, using Equals (=), Range (>,,


|On composite (multi-column) indexes, collect correlated key stats |<br />

|on column pairings, as well as cardinality stats, like 2ndkeycard,|<br />

|3rdkeycard, etc., with Runstats. These additional statistics will |<br />

|allow <strong>DB2</strong> to make better filter estimates <strong>for</strong> Equality and Range |<br />

|and In List predicates, thereby selecting proper indexes and more |<br />

|realistic estimates <strong>for</strong> rows returned from the query (QCARD). |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL7024I *** GOOD NEWS: |<br />

|Index Screening is now available <strong>for</strong> List Prefetch processing, |<br />

|which allows Random indexes to "screen" additional predicates |<br />

|after matching index scan, and be<strong>for</strong>e data access. |<br />

+------------------------------------------------------------------+<br />

+------------------------------------------------------------------+<br />

|ANL6020I *** NOTE: |<br />

|This index is presently designated as allowing "duplicate values".|<br />

|Make sure this is a nonunique index that does not fall into one of|<br />

|the following "unique" categories: explicitly unique, primary key,|<br />

|non-primary RI parent key, unique where not null, unique column |<br />

|constraint. Unique indexes have definite advantages whenever they |<br />

|can be declared by the user, so be sure it contains duplicates. |<br />

+------------------------------------------------------------------+<br />

THIS IS AN "INDEX ONLY" ACCESS: NO DATA PAGES ARE READ FROM THE TABLE<br />

+------------------------------------------------------------------+<br />

|ANL7015I *** GUIDELINE: |<br />

|Collecting Non-uni<strong>for</strong>m column statistics greatly enhance the <strong>DB2</strong> |<br />

|Optimizer accuracy when processing Equals and In (List) preds. |<br />

+------------------------------------------------------------------+<br />

THIS TABLE IS JOINED WITH THE PRIOR TABLE VIA THE "NESTED LOOP" METHOD.<br />

THIS IS THE INNER TABLE IN THE NESTED LOOP JOIN.<br />

THIS IS A CARTESIAN JOIN, ALL ROWS TO ALL ROWS, NO JOIN PREDICATE.<br />

+------------------------------------------------------------------+<br />

|ANL6034I *** NOTE: |<br />

|Only the Nested Loop join method supports the use of non-Equijoin |<br />

|predicates (T1.C1


PREDICATE ANALYSIS<br />

------------------<br />

QBLKNO: 1 PREDNO: 1 FILTER: 1.0000000 TYPE: AND JOIN PRED? N<br />

STAGE 1? Y BOOLEAN TERM? Y INDEX KEYFIELD? N REDUNDANT? N AFTER JOIN? N<br />

ADDED BY PTC? N FOR NEGATION? N LITERALS:<br />

LEFT SIDE --> TABNO: 0 BLOCKNO: 0 PREDNO: 0<br />

RIGHT SIDE -> TABNO: 0 BLOCKNO: 0 PREDNO: 5<br />

PSUEDO TEXT:<br />

(((A.LOCATION=(EXPR) AND B.DLOCATION=(EXPR)) AND B.DCOLLID=(EXPR)) AND A.COLLID(EXPR))<br />

QBLKNO: 1 PREDNO: 2 FILTER: 0.0400000 TYPE: EQUAL JOIN PRED? N<br />

STAGE 1? Y BOOLEAN TERM? Y INDEX KEYFIELD? Y REDUNDANT? N AFTER JOIN? N<br />

ADDED BY PTC? N FOR NEGATION? N LITERALS: HV<br />

LEFT SIDE --> LOCATION TABNO: 1 BLOCKNO: 0 PREDNO: 0<br />

RIGHT SIDE -> VALUE TABNO: 0 BLOCKNO: 0 PREDNO: 0<br />

PSUEDO TEXT:<br />

A.LOCATION=(EXPR)<br />

QBLKNO: 1 PREDNO: 3 FILTER: 0.0400000 TYPE: EQUAL JOIN PRED? N<br />

STAGE 1? Y BOOLEAN TERM? Y INDEX KEYFIELD? Y REDUNDANT? N AFTER JOIN? N<br />

ADDED BY PTC? N FOR NEGATION? N LITERALS: HV<br />

LEFT SIDE --> DLOCATION TABNO: 2 BLOCKNO: 0 PREDNO: 0<br />

RIGHT SIDE -> VALUE TABNO: 0 BLOCKNO: 0 PREDNO: 0<br />

PSUEDO TEXT:<br />

B.DLOCATION=(EXPR)<br />

QBLKNO: 1 PREDNO: 4 FILTER: 0.0400000 TYPE: EQUAL JOIN PRED? N<br />

STAGE 1? Y BOOLEAN TERM? Y INDEX KEYFIELD? Y REDUNDANT? N AFTER JOIN? N<br />

ADDED BY PTC? N FOR NEGATION? N LITERALS: HV<br />

LEFT SIDE --> DCOLLID TABNO: 2 BLOCKNO: 0 PREDNO: 0<br />

RIGHT SIDE -> VALUE TABNO: 0 BLOCKNO: 0 PREDNO: 0<br />

PSUEDO TEXT:<br />

B.DCOLLID=(EXPR)<br />

QBLKNO: 1 PREDNO: 5 FILTER: 0.9600000 TYPE: EQUAL JOIN PRED? N<br />

STAGE 1? Y BOOLEAN TERM? Y INDEX KEYFIELD? N REDUNDANT? N AFTER JOIN? N<br />

ADDED BY PTC? N FOR NEGATION? Y LITERALS: HV<br />

LEFT SIDE --> COLLID TABNO: 1 BLOCKNO: 0 PREDNO: 0<br />

RIGHT SIDE -> VALUE TABNO: 0 BLOCKNO: 0 PREDNO: 0<br />

PSUEDO TEXT:<br />

A.COLLID(EXPR)<br />

ANL3026W NO STATISTICS FOUND IN CATALOG FOR ONE OR MORE VARIABLES<br />

OPTIMIZER DEFAULTS WERE USED WHERE MISSING VALUES FOUND.<br />

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*<br />

* QUERY 100000001 WILL REQUIRE 11.22512 SECONDS OF ELAPSED TIME *<br />

* DURING WHICH 8.09615 SECONDS OF CPU TIME WILL BE CONSUMED AND *<br />

* A TOTAL OF 6 PHYSICAL I/O REQUESTS WILL BE ISSUED TO DISK *<br />

* QUNITS 443 ESTIMATED PROCESSING C<strong>OS</strong>T $ 1.8903 DOLLARS *<br />

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*<br />

ANL5026W *** WARNING:<br />

ESTIMATE OF 443 EXCEEDS "SERVICE UNIT" LIMIT OF 200 QUNITS !<br />

406 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Appendix D. EXPLAIN and its tables<br />

D<br />

In this appendix we describe the <strong>DB2</strong> EXPLAIN function and show the contents of the<br />

EXPLAIN tables:<br />

► DSN_PLAN_TABLE<br />

► DSN_STATEMNT_TABLE<br />

► DSN_FUNCTION_TABLE<br />

We have all the EXPLAIN tables described here, including contents that have not changed<br />

with V8, in order to make the material more complete and understandable.<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 407


D.1 <strong>DB2</strong> EXPLAIN<br />

EXPLAIN describes the access paths selected by <strong>DB2</strong> to execute an SQL statement<br />

(UPDATE, SELECT, DELETE, and INSERT), obtains in<strong>for</strong>mation about how SQL statements<br />

from a package or plan will execute, and inserts that in<strong>for</strong>mation into the<br />

package_owner.PLAN_TABLE or plan_owner.PLAN_TABLE. For dynamically prepared SQL,<br />

the qualifier is the current SQLID. An EXPLAIN can be executed either statically from an<br />

application program, or dynamically, using QMF or SPUFI.<br />

You can use EXPLAIN to:<br />

► Help application program design<br />

► Assist in database design<br />

► Give a description of the access path chosen <strong>for</strong> a query by <strong>DB2</strong><br />

► Help you verify if your application needs to be rebound<br />

► Check if index or table scan is used by a statement<br />

► Check if <strong>DB2</strong> plans are using parallelism<br />

With <strong>DB2</strong> V8 EXPLAIN has been enhanced to:<br />

► EXPLAIN SQL in the dynamic statement cache (DSC)<br />

► Use ALIAS with the EXPLAIN_TABLE<br />

Be<strong>for</strong>e you start using EXPLAIN, you need to create a PLAN_TABLE to hold the results of the<br />

EXPLAIN. The EXPLAIN can use two other tables, FUNCTION_TABLE or<br />

STATEMNT_TABLE, but unless you need the in<strong>for</strong>mation they provide, it is not necessary to<br />

create them to use EXPLAIN. A description of the contents of these tables follows.<br />

With <strong>DB2</strong> V8, the PLAN_TABLE has had 7 additional columns defined, we list them in<br />

Table D-2 on page 410. The contents of 2 columns have been changed in order store MQT<br />

related in<strong>for</strong>mation:<br />

► TNAME<br />

The name of a table, materialized query table, created or declared temporary table,<br />

materialized view, table expression, or an intermediate result table <strong>for</strong> an outer join that is<br />

accessed in this step, blank if METHOD is 3.<br />

► TABLE_TYPE<br />

New type M <strong>for</strong> materialized query table<br />

EXPLAIN in<strong>for</strong>ms you about the access paths <strong>DB2</strong> chooses, and can tell you:<br />

► The number of indexes used<br />

► The I/O method used to read the pages (list prefetch or sequential prefetch)<br />

► How many index columns are used as search criteria<br />

► If an index access or table scan is used<br />

► The join method<br />

► The order in which the tables are joined<br />

► When and why sorts are per<strong>for</strong>med<br />

► To determine if <strong>DB2</strong> plans to use multiple concurrent I/O streams to access your data<br />

► Select, Update and Delete statements<br />

This in<strong>for</strong>mation is saved in the PLAN_TABLE. This table has been evolving with each release<br />

of <strong>DB2</strong> adding new columns in order to provide new functions. <strong>DB2</strong> inserts rows into the<br />

PLAN_TABLE whenever a plan or a package is bound or rebound, or each time an<br />

explainable SQL statement is executed.<br />

408 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Note: If you want to empty the PLAN_TABLE, you must use the DELETE statement, just<br />

as you would <strong>for</strong> deleting rows from any table. You also can use the DROP TABLE<br />

statement to drop the PLAN_TABLE completely. The action of binding, rebinding or<br />

executing another SQL statement does not replace or delete rows from the PLAN_TABLE.<br />

D.1.1 DSN_PLAN_TABLE<br />

The table can be created by the statements contained in member name DSNTESC of the<br />

<strong>DB2</strong> sample library. <strong>DB2</strong> tools also create or update your PLAN_TABLE when needed.<br />

Let us look at the evolution of the PLAN_TABLE in Table D-1.It is a way to see the evolution of<br />

<strong>DB2</strong>.<br />

Table D-1 PLAN_TABLE columns by release<br />

<strong>DB2</strong> release Columns in<br />

PLAN_TABLE<br />

V1 25<br />

V1R2 28<br />

V2 30<br />

V3 34<br />

V4 43<br />

V5 46<br />

V6 49<br />

V7 51<br />

V8 58<br />

Note: When you execute EXPLAIN using <strong>DB2</strong> Per<strong>for</strong>mance Expert in V8 <strong>for</strong> the first time,<br />

<strong>DB2</strong> PE advises you that your PLAN_TABLE is old and updates it <strong>for</strong> you.<br />

Of course, the 58-column <strong>for</strong>mat gives you the most in<strong>for</strong>mation. If you alter an existing<br />

PLAN_TABLE to add new columns, in general specify the columns as NOT NULL WITH<br />

DEFAULT, so that default values are included <strong>for</strong> the rows already in the table. However, as<br />

you can see in Table D-2, there are some exceptions, certain columns do allow nulls. Do not<br />

specify those columns as NOT NULL WITH DEFAULT.<br />

Table D-2 describes the PLAN_TABLE, giving a small description of each column and a brief<br />

history of <strong>DB2</strong> evolution. If you want more in<strong>for</strong>mation about it, refer to <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong><br />

<strong>Version</strong> 8 Administration Guide, SC18-7413.<br />

Note: There are some objects <strong>for</strong> which accesses are not described by EXPLAIN. They<br />

are, <strong>for</strong> example, the access to LOB values, which are stored separately from the base<br />

table, and access to parent or dependent tables needed to en<strong>for</strong>ce referential constraints,<br />

SQL <strong>for</strong> routines (triggers, functions, or stored procedures), and explicit access to<br />

SECLABELs <strong>for</strong> row level security.<br />

Appendix D. EXPLAIN and its tables 409


Table D-2 PLAN_TABLE contents and brief history<br />

Column Type Content<br />

QUERYNO INTEGER NOT NULL A number intended to identify the<br />

statement being explained.<br />

QBLOCKNO SMALLINT NOT NULL A number that identifies each query<br />

block within a query.<br />

APPLNAME CHAR(8) NOT NULL The name of the application plan <strong>for</strong><br />

the row.<br />

PROGNAME CHAR(8) NOT NULL The name of the program or package<br />

containing the statement being<br />

explained.<br />

PLANNO SMALLINT NOT NULL The number of the step in which the<br />

query indicated in QBLOCKNO was<br />

processed.<br />

METHOD SMALLINT NOT NULL A number (0, 1, 2, 3, or 4) that<br />

indicates the join method used <strong>for</strong> the<br />

step:<br />

0 = First table accessed, continuation<br />

of the previous table.<br />

1= NESTED LOOP JOIN<br />

2= MERGE SCAN JOIN<br />

3 = Sorts needed by ORDER BY,<br />

GROUP BY, SELECT DISTINCT,<br />

UNION,<br />

4= HYBRID JOIN<br />

CREATOR CHAR(8) NOT NULL The creator of the new table accessed<br />

in this step, blank if METHOD is 3.<br />

TNAME CHAR(18) NOT NULL The name of a table, materialized<br />

query table, created or declared<br />

temporary table, materialized view, or<br />

materialized table expression.<br />

TABNO SMALLINT NOT NULL Values are <strong>for</strong> <strong>IBM</strong> use only.<br />

410 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Column Type Content<br />

ACCESSTYPE CHAR(2) NOT NULL The method of accessing the new<br />

table:<br />

I - index<br />

I1 - One-fetch index scan<br />

M - Multiple index scan (followed by<br />

MX, MI, or MU)<br />

MI - intersection of multiple indexes<br />

MU - union of multiple indexes<br />

MX - index scan on the index named<br />

in ACCESSNAME<br />

N - index scan when the matching<br />

predicate contains the IN keyword<br />

R - Table space scan<br />

RW - Work file scan of the result of a<br />

materialized user-defined table<br />

function<br />

T - Sparse index (star join work files)<br />

V - Buffers <strong>for</strong> an INSERT statement<br />

within a SELECT<br />

blank - Not applicable to the current<br />

row ACCESSTYPE<br />

MATCHCOLS SMALLINT NOT NULL For ACCESSTYPE I, I1, N, or MX, the<br />

number of index keys used in an index<br />

scan; otherwise, 0.<br />

ACCESSCREATOR CHAR(8) NOT NULL For ACCESSTYPE I, I1, N, or MX, the<br />

creator of the index; otherwise, blank.<br />

ACCESSNAME CHAR (18) NOT NULL For ACCESSTYPE I, I1, N, or MX, the<br />

name of the index; otherwise, blank.<br />

INDEXONLY CHAR(1) NOT NULL Whether access to an index alone is<br />

enough to carry out the step, or<br />

whether data too must. Y = YES; N<br />

=NO<br />

SORTN_UNIQ CHAR(1) NOT NULL Whether the new table is sorted to<br />

remove duplicate rows. Y=Yes; N=No.<br />

SORTN_JOIN CHAR(1) NOT NULL Whether the new table is sorted <strong>for</strong><br />

join method 2 or 4. Y=Yes; N=No.<br />

SORTN_ORDERBY CHAR(1) NOT NULL Whether the new table is sorted <strong>for</strong><br />

ORDER BY.<br />

Y=Yes; N=No.<br />

SORTN_GROUPBY CHAR(1) NOT NULL Whether the new table is sorted <strong>for</strong><br />

GROUP BY.<br />

Y=Yes; N=No.<br />

SORTC_UNIQ CHAR(1) NOT NULL Whether the composite table is sorted<br />

to remove duplicate rows. Y=Yes;<br />

N=No.<br />

SORTC_JOIN CHAR(1) NOT NULL Whether the composite table is sorted<br />

<strong>for</strong> join method 1, 2 or 4. Y=Yes;<br />

N=No.<br />

Appendix D. EXPLAIN and its tables 411


Column Type Content<br />

SORTC_ORDER BY CHAR(1) NOT NULL Whether the composite table is sorted<br />

<strong>for</strong> an ORDER BY clause or a<br />

quantified predicate. Y=Yes; N=No.<br />

SORTC_GROUP BY CHAR(1) NOT NULL Whether the composite table is sorted<br />

<strong>for</strong> a GROUP BY clause. Y=Yes;<br />

N=No.<br />

TSLOCKMODE CHAR(3) NOT NULL An indication of the mode of lock to be<br />

acquired on either the new table, or its<br />

table space or table space partitions.<br />

If the isolation can be determined at<br />

bind time.<br />

TIMESTAMP CHAR(16) NOT NULL The time at which the row is<br />

processed, to the last .01 second. If<br />

necessary, <strong>DB2</strong> adds .01 second to<br />

the value to ensure that rows <strong>for</strong> two<br />

successive queries have different<br />

values.<br />

REMARKS VARCHAR(254) NOT NULL A field into which you can insert any<br />

character string of 762 or fewer<br />

characters.<br />

------- 25 COLUMNS FORMAT<br />

-----<strong>Version</strong> 1 -1983--<br />

PREFETCH CHAR(1) NOT NULL WITH<br />

DEFAULT<br />

412 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

------------25 COLUMNS FORMAT<br />

-----<strong>Version</strong> 1-1983-<br />

S = pure sequential prefetch; L =<br />

prefetch through a page list; D =<br />

optimizer expects dynamic prefetch;<br />

blank = unknown or no prefetch.<br />

COLUMN_FN_EVAL CHAR(1) NOT NULL WITH DEFAULT When an SQL aggregate function is<br />

evaluated. R = while the data is being<br />

read from the table or index; S = while<br />

per<strong>for</strong>ming a sort to satisfy a GROUP<br />

BY clause;<br />

blank = after data retrieval and after<br />

any sorts.<br />

MIXOPSEQ SMALLINT NOT NULL WITH<br />

DEFAULT<br />

---------28 COLUMNS FORMAT<br />

---<strong>Version</strong> 1 --1984---<br />

VERSION VARCHAR(64) NOT NULL WITH<br />

DEFAULT<br />

COLLID CHAR(18) NOT NULL WITH<br />

DEFAULT<br />

---------- 30 Columns Format<br />

-------<strong>Version</strong> 2 ---1988---<br />

The sequence number of a step in a<br />

multiple index operation.<br />

1,2,..., N For the steps of the multiple<br />

index procedure (ACCESSTYPE is<br />

MX, MI, or MU.)<br />

0 For any other rows (ACCESSTYPE<br />

is I, I1, M, N, R, or blank.)<br />

----------28 COLUMNS FORMAT<br />

-------<strong>Version</strong> 1-1984---<br />

The version identifier <strong>for</strong> the package.<br />

The collection ID <strong>for</strong> the package.<br />

----------- 30 columns <strong>for</strong>mat<br />

-------<strong>Version</strong> 2 ---1988-


Column Type Content<br />

ACCESS_DEGREE SMALLINT The number of parallel tasks or<br />

operations activated by a query.<br />

ACCESS_PGROUP_ID SMALLINT The identifier of the parallel group <strong>for</strong><br />

accessing the new table.<br />

JOIN_DEGREE SMALLINT The number of parallel operations or<br />

tasks used in joining the composite<br />

table with the new table.<br />

JOIN_PGROUP_ID SMALLINT The identifier of the parallel group <strong>for</strong><br />

joining the composite table with the<br />

new table.<br />

- 34 Columns Format -<strong>Version</strong> 3<br />

-Dec.1993-<br />

- 34 Columns Format - <strong>Version</strong> 3<br />

-Dec.1993-<br />

SORTC_PGROUP_ID SMALLINT The parallel group identifier <strong>for</strong> the<br />

parallel sort of the composite table.<br />

SORTN_PGROUP_ID SMALLINT The parallel group identifier <strong>for</strong> the<br />

parallel sort of the new table.<br />

PARALLELISM_MODE CHAR(1) The kind of parallelism, if any, that is<br />

used at bind time:<br />

I Query I/O parallelism<br />

C Query CP parallelism<br />

X Sysplex query parallelism<br />

MERGE_JOIN_COLS SMALLINT The number of columns that are<br />

joined during a merge scan join<br />

(Method=2).<br />

CORRELATION_NAME CHAR(18) The correlation name of a table or<br />

view that is specified in the statement.<br />

PAGE_RANGE CHAR(1) NOT NULL WITH DEFAULT The table qualifies <strong>for</strong> page range<br />

screening, so that plans scan only the<br />

partitions that are needed. Y = yes<br />

Blank =N<br />

JOIN_TYPE CHAR(1) NOT NULL WITH DEFAULT -Type of join F, L, S, blank<br />

GROUP_MEMBER CHAR(8) NOT NULL WITH DEFAULT member <strong>for</strong> EXPLAIN<br />

<strong>IBM</strong>_SERVICE_DATA VARCHAR(254) NULL WITH<br />

DEFAULT<br />

-43 Columns Format - <strong>Version</strong> 4 -<br />

Nov. 1995-<br />

<strong>IBM</strong> use only<br />

WHEN_OPTIMIZE CHAR(1) NOT NULL WITH DEFAULT -BIND, RUN<br />

- 43 Columns Format -<strong>Version</strong> 4<br />

-Nov. 1995-<br />

QBLOCK_TYPE CHAR(6) NOT NULL WITH DEFAULT For each query block, an indication of<br />

the type of SQL operation per<strong>for</strong>med.<br />

SELECT, INSERT, UPDATE...<br />

BIND_TIME TIMESTAMP NULL WITH DEFAULT The time at which the plan or package<br />

<strong>for</strong> this statement query block was<br />

bound.<br />

- 46 Column Format - <strong>Version</strong> 5 -<br />

June 1997 -<br />

- 46 Column Format - <strong>Version</strong> 5 -<br />

June 1997-<br />

Appendix D. EXPLAIN and its tables 413


Column Type Content<br />

OPTHINT CHAR(8) NOT NULL WITH DEFAULT A string that you use to identify this<br />

row as an optimization hint <strong>for</strong> <strong>DB2</strong>.<br />

<strong>DB2</strong> uses this row as input when<br />

choosing an access path.<br />

HINT_USED CHAR(8) NOT NULL WITH DEFAULT If <strong>DB2</strong> used one of your optimization<br />

hints, it puts the identifier <strong>for</strong> that hint<br />

(the value in OPTHINT) in this<br />

column.<br />

PRIMARY_ACCESSTYPE CHAR(1) NOT NULL WITH DEFAULT if direct row access.<br />

- 49 Column Format -----<strong>Version</strong> 6 -<br />

June 1999<br />

PARENT_QBLOCKNO SMALLINT NOT NULL WITH<br />

DEFAULT<br />

414 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

- 49 Column Format -<strong>Version</strong> 6<br />

-June 1999-<br />

A number that indicates the<br />

QBLOCKNO of the parent query<br />

block.<br />

TABLE_TYPE CHAR(1) T table, W work, RB, Q, M, F, C, B...<br />

------ 51 Column Format ----<strong>Version</strong><br />

7 --2001---<br />

- 51 Column Format -<strong>Version</strong> 7-Mar.<br />

2001-<br />

TABLE_ENCODE CHAR(1) The encoding scheme of the table. If<br />

the table has a single CCSID set,<br />

possible values are:<br />

A ASCII<br />

E EBCDIC<br />

U Unicode<br />

M is the value of the column when the<br />

table contains multiple CCSID sets<br />

TABLE_SCCSID SMALLINT NOT NULL WITH<br />

DEFAULT<br />

TABLE_MCCSID SMALLINT NOT NULL WITH<br />

DEFAULT<br />

TABLE_DCCSID SMALLINT NOT NULL WITH<br />

DEFAULT<br />

The SBCS (Single Byte Character<br />

Set) CCSID value of the table. If<br />

column TABLE_ENCODE is M, the<br />

value is 0.<br />

The mixed CCSID value of the table.<br />

Mixed and DBCS (Double Byte<br />

Character Set) CCSIDs are only<br />

available <strong>for</strong> a certain number of<br />

SBCS CCSIDs, namely, CCSIDs <strong>for</strong><br />

Japanese, Korean, and Chinese. That<br />

is, <strong>for</strong> CCSIDS such as 273 <strong>for</strong><br />

Germany, the mixed and DBCS<br />

CCSIDs do not exist.<br />

The DBCS (Double Byte Character<br />

Set) CCSID value of the table. If<br />

column TABLE_ENCODE is M, the<br />

value is 0.<br />

ROUTINE_ID INTEGER Values are <strong>for</strong> <strong>IBM</strong> use only.<br />

CTEREF SMALLINT NOT NULL WITH<br />

DEFAULT<br />

If the referenced table is a common<br />

table expression, the value is the<br />

top-level query block number.<br />

STMTTOKEN VARCHAR(240) User specified statement token.


Column Type Content<br />

--------58 Columns<br />

Format-------<strong>Version</strong> 8 ----2003-<br />

D.1.2 DSN_STATEMNT_TABLE<br />

EXPLAIN estimates the cost of executing an SQL SELECT, INSERT, UPDATE, or DELETE<br />

statement. The output appears in a table called DSN_STATEMNT_TABLE. The columns of<br />

this table and their contents are listed in Table D-3. For more in<strong>for</strong>mation about statement<br />

tables, see “Estimating a statement’s cost” on the <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Administration<br />

Guide, SC18-7413.<br />

Table D-3 EXPLAIN enhancements in DSN_STATEMNT_TABLE<br />

Column Name Type Content<br />

QUERYNO INTEGER NOT NULL WITH<br />

DEFAULT<br />

-58 Column Format -<strong>Version</strong> 8 -Mar.<br />

26, 2004-<br />

A number that identifies the statement<br />

being explained.<br />

APPLNAME CHAR(8) NOT NULL WITH DEFAULT The name of the application plan <strong>for</strong><br />

the row, or blank.<br />

PROGNAME VARCHAR (128) NOT NULL WITH<br />

DEFAULT<br />

COLLID VARCHAR (128) NOT NULL WITH<br />

DEFAULT<br />

GROUP_MEMBER CHAR (8) NOT NULL WITH<br />

DEFAULT<br />

The name of the program or package<br />

containing the statement being<br />

explained, or blank.<br />

The collection ID <strong>for</strong> the package.<br />

The member name of the <strong>DB2</strong> that<br />

executed EXPLAIN, or blank.<br />

EXPLAIN_TIME TIMESTAMP The time at which the statement is<br />

processed.<br />

STMT_TYPE CHAR (6) NOT NULL WITH<br />

DEFAULT<br />

C<strong>OS</strong>T_CATEGORY CHAR (1) NOT NULL WITH<br />

DEFAULT<br />

PROCMS INTEGER NOT NULL WITH<br />

DEFAULT<br />

PROCSU INTEGER NOT NULL WITH<br />

DEFAULT<br />

REASON VARCHAR (256) NOT NULL WITH<br />

DEFAULT<br />

STMT_ENCODE CHAR (1) NOT NULL WITH<br />

DEFAULT<br />

The type of statement being<br />

explained. SELECT,<br />

UPDATE,INSERT, or UPDATE...<br />

Indicates if <strong>DB2</strong> was <strong>for</strong>ced to use<br />

default values when making its<br />

estimates (B) or used statistics (A).<br />

The estimated processor cost, in<br />

milliseconds, <strong>for</strong> the SQL statement.<br />

The estimated processor cost, in<br />

service units, <strong>for</strong> the SQL statement.<br />

A string that indicates the reasons <strong>for</strong><br />

putting an estimate into cost category<br />

B.<br />

Encoding scheme of the statement.<br />

A = ASCII<br />

E = EBCDIC<br />

U = Unicode<br />

Appendix D. EXPLAIN and its tables 415


D.1.3 DSN_FUNCTION_TABLE<br />

You can use <strong>DB2</strong> EXPLAIN to obtain in<strong>for</strong>mation about how <strong>DB2</strong> resolves functions. <strong>DB2</strong><br />

stores the in<strong>for</strong>mation in a table called DSN_FUNCTION_TABLE. <strong>DB2</strong> inserts a row in<br />

DSN_FUNCTION_TABLE <strong>for</strong> each function that is referenced in an SQL statement when one<br />

of the following events occurs:<br />

► You execute the SQL EXPLAIN statement on an SQL statement that contains<br />

user-defined function invocations<br />

► You run a program whose plan is bound with EXPLAIN(YES), and the program executes<br />

an SQL statement that contains user-defined function invocations<br />

Be<strong>for</strong>e you use EXPLAIN to obtain in<strong>for</strong>mation about function resolution, you need to create<br />

the DSN_FUNCTION_TABLE. The contents are listed in Table D-4.<br />

Table D-4 DSN_FUNCTION_TABLE extensions<br />

Column Type Content<br />

QUERYNO INTEGER A number that identifies the statement<br />

being explained.<br />

QBLOCKNO INTEGER A number that identifies each query<br />

block within a query.<br />

APPLNAME VARCHAR (128) The name of the application plan <strong>for</strong><br />

the row.<br />

PROGNAME VARCHAR (128) The name of the program or package<br />

containing the statement being<br />

explained.<br />

COLLID CHAR (8) The collection ID <strong>for</strong> the package.<br />

GROUP_MEMBER CHAR (8) The member name of the <strong>DB2</strong> that<br />

executed EXPLAIN, or blank.<br />

EXPLAIN_TIME TMESTAMP Timestamp when the EXPLAIN<br />

statement was executed.<br />

SCHEMA_NAME VARCHAR(128) NOT NULL WITH<br />

DEFAULT<br />

FUNCTION_NAME VARCHAR(128) NOT NULL WITH<br />

DEFAULT<br />

SPEC_FUNC_NAME VARCHAR(128) NOT NULL WITH<br />

DEFAULT<br />

416 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

Schema name of the function that is<br />

invoked in the explained statement.<br />

Name of the function that is invoked in<br />

the explained statement.<br />

Specific name of the function that is<br />

invoked in the explained statement.<br />

FUNCTION_TYPE CHAR(2) NOT NULL WITH DEFAULT The type of function that is invoked in<br />

the explained statement. Possible<br />

values are: SU - Scalar function, TU -<br />

Table function<br />

VIEW_CREATOR VARCHAR(128) NOT NULL WITH<br />

DEFAULT<br />

The creator of the view, if the function<br />

that is specified in the<br />

FUNCTION_NAME column is<br />

referenced in a view definition.<br />

Otherwise, this field is blank.


Column Type Content<br />

VIEW_NAME VARCHAR(128) NOT NULL WITH<br />

DEFAULT<br />

PATH VARCHAR(2048) NOT NULL WITH<br />

DEFAULT<br />

FUNCTION_TEXT VARCHAR(1500) NOT NULL WITH<br />

DEFAULT<br />

D.1.4 DSN_STATEMNT_CACHE_TABLE<br />

This new table was recently introduced by PTF UQ89372 <strong>for</strong> APAR PQ88073. With this<br />

enhancement a new keyword ALL is added to EXPLAIN STMTCACHE and a new explain<br />

table DSN_STATEMENT_CACHE_TABLE is created to hold the output of IFCID 316 and<br />

IFCID 318.<br />

A brief description follows, as reported in the APAR text.<br />

There are two different sets of in<strong>for</strong>mation that can be collected from the SQL statements in<br />

the dynamic statement cache. Specifying STMTCACHE with the STMTID or STMTTOKEN<br />

keywords causes the traditional access path in<strong>for</strong>mation to be written to the PLAN_TABLE <strong>for</strong><br />

the associated SQL statement as well as a single row written to<br />

DSN_STATEMENT_CACHE_TABLE if it exists.<br />

However, specifying STMTCACHE with the new ALL keyword causes in<strong>for</strong>mation to be<br />

written to only DSN_STATEMENT_CACHE_TABLE. It consists of one row per SQL statement<br />

in the dynamic statement cache <strong>for</strong> which the current authorization ID is authorized to<br />

execute.<br />

The contents of these rows show identifying in<strong>for</strong>mation about the cache entries, as well as<br />

an accumulation of statistics reflecting the executions of the statements by all processes that<br />

have executed the statement.<br />

This in<strong>for</strong>mation is nearly identical to the in<strong>for</strong>mation returned from the IFI monitor READS<br />

API <strong>for</strong> IFCIDs 0316 and 0317.<br />

Note that the collection and reset of the statistics in these records is controlled by starting and<br />

stopping IFCID 318. For more details, see "Controlling collection of dynamic statement cache<br />

statistics with IFCID 0318" in <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Administration Guide,<br />

SC18-7413-01, Appendix E - Programming <strong>for</strong> the Instrumentation Facility Interface (IFI).<br />

The new EXPLAIN option is:<br />

EXPLAIN STMTCACHE ALL;<br />

The name of the view, if the function<br />

that is specified in the<br />

FUNCTION_NAME column is<br />

referenced in a view definition.<br />

Otherwise, this field is blank.<br />

The value of the SQL path when <strong>DB2</strong><br />

resolved the function reference.<br />

The text of the function reference (the<br />

function name and parameters).<br />

SQLCODE -20248 is issued if no statement is found in the cache <strong>for</strong> the auth ID that is used.<br />

-20248 ATTEMPTED TO EXPLAIN A CACHED STATEMENT WITH<br />

STMTID, STMTTOKEN ID-token, OR ALL BUT THE REQUIRED<br />

EXPLAIN INFORMATION IS NOT ACCESSIBLE.<br />

Be<strong>for</strong>e you can use EXPLAIN STMTCACHE ALL, Statement Cache must be turned on. You<br />

must also create the table DSN_STATEMENT_CACHE_TABLE to hold the results of<br />

EXPLAIN STMTCACHE ALL. The DDL is shown in Example D-1.<br />

Appendix D. EXPLAIN and its tables 417


Example: D-1 Creating DSN_STATEMENT_CACHE_TABLE<br />

CREATE DATABASE DSNSTMTC;<br />

CREATE TABLESPACE DSNSUMTS IN DSNSTMTC;<br />

CREATE LOB TABLESPACE DSNLOBTS IN DSNSTMTC<br />

BUFFERPOOL BP32K1;<br />

CREATE TABLE DSN_STATEMENT_CACHE_TABLE<br />

(<br />

STMT_ID INTEGER NOT NULL,<br />

STMT_TOKEN VARCHAR(240) ,<br />

COLLID VARCHAR(128) NOT NULL,<br />

PROGRAM_NAME VARCHAR(128) NOT NULL,<br />

INV_DROPALT CHAR(1) NOT NULL,<br />

INV_REVOKE CHAR(1) NOT NULL,<br />

INV_LRU CHAR(1) NOT NULL,<br />

INV_RUNSTATS CHAR(1) NOT NULL,<br />

CACHED_TS TIMESTAMP NOT NULL,<br />

USERS INTEGER NOT NULL,<br />

COPIES INTEGER NOT NULL,<br />

LINES INTEGER NOT NULL,<br />

PRIMAUTH VARCHAR(128) NOT NULL,<br />

CURSQLID VARCHAR(128) NOT NULL,<br />

BIND_QUALIFIER VARCHAR(128) NOT NULL,<br />

BIND_ISO CHAR(2) NOT NULL,<br />

BIND_CDATA CHAR(1) NOT NULL,<br />

BIND_DYNRL CHAR(1) NOT NULL,<br />

BIND_DEGRE CHAR(1) NOT NULL,<br />

BIND_SQLRL CHAR(1) NOT NULL,<br />

BIND_CHOLD CHAR(1) NOT NULL,<br />

STAT_TS TIMESTAMP NOT NULL,<br />

STAT_EXEC INTEGER NOT NULL,<br />

STAT_GPAG INTEGER NOT NULL,<br />

STAT_SYNR INTEGER NOT NULL,<br />

STAT_WRIT INTEGER NOT NULL,<br />

STAT_EROW INTEGER NOT NULL,<br />

STAT_PROW INTEGER NOT NULL,<br />

STAT_SORT INTEGER NOT NULL,<br />

STAT_INDX INTEGER NOT NULL,<br />

STAT_RSCN INTEGER NOT NULL,<br />

STAT_PGRP INTEGER NOT NULL,<br />

STAT_ELAP FLOAT NOT NULL,<br />

STAT_CPU FLOAT NOT NULL,<br />

STAT_SUS_SYNIO FLOAT NOT NULL,<br />

STAT_SUS_LOCK FLOAT NOT NULL,<br />

STAT_SUS_SWIT FLOAT NOT NULL,<br />

STAT_SUS_GLCK FLOAT NOT NULL,<br />

STAT_SUS_OTHR FLOAT NOT NULL,<br />

STAT_SUS_OTHW FLOAT NOT NULL,<br />

STAT_RIDLIMT INTEGER NOT NULL,<br />

STAT_RIDSTOR INTEGER NOT NULL,<br />

EXPLAIN_TS TIMESTAMP NOT NULL,<br />

SCHEMA VARCHAR(128) NOT NULL,<br />

STMT_TEXT CLOB(2M) NOT NULL,<br />

STMT_ROWID ROWID NOT NULL GENERATED ALWAYS<br />

)<br />

IN DSNSTMTC.DSNSUMTS CCSID EBCDIC;<br />

418 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


CREATE TYPE 2 INDEX DSN_STATEMENT_CACHE_IDX1<br />

ON DSN_STATEMENT_CACHE_TABLE (STMT_ID ASC) ;<br />

CREATE TYPE 2 INDEX DSN_STATEMENT_CACHE_IDX2<br />

ON DSN_STATEMENT_CACHE_TABLE (STMT_TOKEN ASC)<br />

CLUSTER;<br />

CREATE TYPE 2 INDEX DSN_STATEMENT_CACHE_IDX3<br />

ON DSN_STATEMENT_CACHE_TABLE (EXPLAIN_TS DESC) ;<br />

CREATE AUX TABLE DSN_STATEMENT_CACHE_AUX IN<br />

DSNSTMTC.DSNLOBTS<br />

STORES DSN_STATEMENT_CACHE_TABLE COLUMN STMT_TEXT;<br />

CREATE TYPE 2 INDEX DSN_STATEMENT_CACHE_AUXINX<br />

ON DSN_STATEMENT_CACHE_AUX;<br />

The contents of this new EXPLAIN table are described in Table D-5.<br />

Table D-5 Contents of DSN_STATEMNT_CACHE_TABLE<br />

Column Type Content<br />

STMT_ID Statement ID, EDM unique token<br />

STMT_TOKEN Statement token. User-provided<br />

identification string<br />

COLLID Collection id value is<br />

DSNDYNAMICSQLCACHE<br />

PROGRAM_NAME Program name, Name of package or<br />

DBRM that per<strong>for</strong>med the initial<br />

PREPARE<br />

INV_DROPALT Invalidated by DROP/ALTER<br />

INV_REVOKE Invalidated by REVOKE<br />

INV_LRU Removed from cache by LRU<br />

INV_RUNSTATS Invalidated by RUNSTATS<br />

CACHED_TS Timestamp when statement was<br />

cached<br />

USERS Number of current users of statement.<br />

These are the users that have<br />

prepared or executed the statement<br />

during their current unit of work.<br />

COPIES Number of copies of the statement<br />

owned by all threads in the system<br />

LINES Precompiler line number from the<br />

initial PREPARE<br />

PRIMAUTH User ID - Primary authorization ID of<br />

the user that did the initial PREPARE<br />

CURSQLID CURRENT SQLID of the user that did<br />

the initial prepare<br />

Appendix D. EXPLAIN and its tables 419


Column Type Content<br />

BIND_QUALIFIER Bind Qualifier, object qualifier <strong>for</strong><br />

unqualified table names<br />

BIND_ISO ISOLATION BIND option:<br />

'UR' - Uncommitted Read<br />

'CS' - Cursor Stability<br />

'RS' - Read Stability<br />

'RR' - Repeatable Read<br />

BIND_CDATA CURRENTDATA BIND option:<br />

'Y' - CURRENTDATA(YES)<br />

'N' - CURRENTDATA(NO)<br />

BIND_DYNRL DYNAMICRULES BIND option:<br />

'B' - DYNAMICRULES(BIND)<br />

'R' - DYNAMICRULES(RUN)<br />

BIND_DEGRE CURRENT DEGREE value:<br />

'A' - CURRENT DEGREE = ANY<br />

'1' - CURRENT DEGREE = 1<br />

BIND_SQLRL CURRENT RULES value:<br />

‘D' - CURRENT RULES = <strong>DB2</strong><br />

'S' - CURRENT RULES = SQL<br />

BIND_CHOLD Cursor WITH HOLD bind option<br />

'Y' - Initial PREPARE was done <strong>for</strong> a<br />

cursor WITH HOLD<br />

'N' - Initial PREPARE was not done <strong>for</strong><br />

a cursor WITH HOLD<br />

STAT_TS Timestamp of stats when IFCID 318 is<br />

started<br />

STAT_EXEC Number of executions of statement<br />

For a cursor statement, this is the<br />

number of OPENs<br />

STAT_GPAG Number of getpage operations<br />

per<strong>for</strong>med <strong>for</strong> statement<br />

STAT_SYNR Number of synchronous buffer reads<br />

per<strong>for</strong>med <strong>for</strong> statement<br />

STAT_WRIT Number of buffer write operations<br />

per<strong>for</strong>med <strong>for</strong> statement<br />

STAT_EROW Number of rows examined <strong>for</strong><br />

statement<br />

STAT_PROW Number of rows processed <strong>for</strong><br />

statement<br />

STAT_SORT Number of sorts per<strong>for</strong>med <strong>for</strong><br />

statement<br />

STAT_INDX Number of index scans per<strong>for</strong>med <strong>for</strong><br />

statement<br />

STAT_RSCN Number of table space scans<br />

per<strong>for</strong>med <strong>for</strong> statement<br />

420 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Column Type Content<br />

STAT_PGRP Number of parallel groups created <strong>for</strong><br />

statement<br />

STAT_ELAP Accumulated elapsed time used <strong>for</strong><br />

statement<br />

STAT_CPU Accumulated CPU time used <strong>for</strong><br />

statement<br />

STAT_SUS_SYNIO Accumulated wait time <strong>for</strong><br />

synchronous I/O<br />

STAT_SUS_LOCK Accumulated wait time <strong>for</strong> lock and<br />

latch request<br />

STAT_SUS_SWIT Accumulated wait time <strong>for</strong><br />

synchronous execution unit switch<br />

STAT_SUS_GLCK Accumulated wait time <strong>for</strong> global locks<br />

STAT_SUS_OTHR Accumulated wait time <strong>for</strong> read<br />

activity done by another thread<br />

STAT_SUS_OTHW Accumulated wait time <strong>for</strong> write<br />

activity done by another thread<br />

STAT_RIDLIMT Number of times a RID list was not<br />

used because the number of RIDs<br />

would have exceeded one or more<br />

<strong>DB2</strong> limits<br />

STAT_RIDSTOR Number of times a RID list was not<br />

used because not enough storage<br />

was available to hold the list of RIDs<br />

EXPLAIN_TS When statement cache table is<br />

populated<br />

SCHEMA CURRENT SCHEMA value<br />

STMT_TEXT Statement text<br />

STMT_ROWID Statement ROWID<br />

Appendix D. EXPLAIN and its tables 421


422 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Abbreviations and acronyms<br />

ACS automatic class selection<br />

AIX Advanced Interactive eXecutive<br />

from <strong>IBM</strong><br />

APAR authorized program analysis report<br />

ARM automatic restart manager<br />

ASCII American National Standard Code<br />

<strong>for</strong> In<strong>for</strong>mation Interchange<br />

BCRS business continuity recovery<br />

services<br />

BLOB binary large objects<br />

BPA buffer pool analysis<br />

BCDS DFSMShsm backup control data<br />

set<br />

BSDS boot strap data set<br />

CCA channel connection address<br />

CCA client configuration assistant<br />

CCP collect CPU parallel<br />

CCSID coded character set identifier<br />

CD compact disk<br />

CEC central electronics complex<br />

CF coupling facility<br />

CFCC coupling facility control code<br />

CFRM coupling facility resource<br />

management<br />

CLI call level interface<br />

CLP command line processor<br />

CPU central processing unit<br />

CRCR conditional restart control record<br />

CRD collect report data<br />

CSA common storage area<br />

CTT created temporary table<br />

DASD direct access storage device<br />

<strong>DB2</strong> PE <strong>DB2</strong> Per<strong>for</strong>mance Expert<br />

DBAT database access thread<br />

DBD database descriptor<br />

DBID database identifier<br />

DBRM database request module<br />

DCL data control language<br />

DDCS distributed database connection<br />

services<br />

DDF distributed data facility<br />

DDL data definition language<br />

DES Data Encryption Standard<br />

DLL dynamic load library manipulation<br />

language<br />

DML data manipulation language<br />

DNS domain name server<br />

DRDA distributed relational database<br />

architecture<br />

DSC dynamic statement cache, local or<br />

global<br />

DTT declared temporary tables<br />

DWDM dense wavelength division<br />

multiplexer<br />

DWT deferred write threshold<br />

EA extended addressability<br />

EBCDIC extended binary coded decimal<br />

interchange code<br />

ECS enhanced catalog sharing<br />

ECSA extended common storage area<br />

EDM environment descriptor<br />

management<br />

ELB extended long busy<br />

ERP enterprise resource planning<br />

ERP error recovery procedure<br />

ESA Enterprise Systems Architecture<br />

ESP Enterprise Solution Package<br />

ESS Enterprise Storage Server<br />

ETR external throughput rate, an<br />

elapsed time measure, focuses on<br />

system capacity<br />

EWLM enterprise workload manager<br />

FIFO first in first out<br />

FTD functional track directory<br />

FLA fast log apply<br />

FTP File Transfer Program<br />

GB gigabyte (1,073,741,824 bytes)<br />

GBP group buffer pool<br />

GRS global resource serialization<br />

GUI graphical user interface<br />

HPJ high per<strong>for</strong>mance Java<br />

I/O input/output<br />

<strong>IBM</strong> International Business Machines<br />

Corporation<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 423


ICF integrated catalog facility<br />

ICF integrated coupling facility<br />

ICMF integrated coupling migration facility<br />

CSF Integrated Cryptographic Service<br />

Facility<br />

IFCID instrumentation facility component<br />

identifier<br />

IFI instrumentation facility interface<br />

IFI Instrumentation Facility Interface<br />

IGS <strong>IBM</strong> Global Services<br />

IPLA <strong>IBM</strong> Program Licence Agreement<br />

IRLM internal resource lock manager<br />

ISPF interactive system productivity<br />

facility<br />

IRWW <strong>IBM</strong> Relational Warehouse<br />

Workload<br />

ISV independent software vendor<br />

IT In<strong>for</strong>mation Technology<br />

ITR internal throughput rate, a<br />

processor time measure, focuses<br />

on processor capacity<br />

ITSO International Technical Support<br />

Organization<br />

IVP installation verification process<br />

JDBC Java Database Connectivity<br />

JFS journaled file systems<br />

JNDI Java Naming and Directory<br />

Interface<br />

JVM Java Virtual Machine<br />

KB kilobyte (1,024 bytes)<br />

LOB large object<br />

LPAR logical partition<br />

LPL logical page list<br />

LRECL logical record length<br />

LRSN log record sequence number<br />

LRU least recently used<br />

LUW logical unit of work<br />

LVM logical volume manager<br />

MB megabyte (1,048,576 bytes)<br />

NPI non-partitioning index<br />

NVS non volatile storage<br />

ODB object descriptor in DBD<br />

ODBC Open Data Base Connectivity<br />

OP Online per<strong>for</strong>mance<br />

<strong>OS</strong>/390 Operating System/390®<br />

PAV parallel access volume<br />

424 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

PDS partitioned data set<br />

PIB parallel index build<br />

PPRC Peer-to-Peer Remote Copy<br />

PSID pageset identifier<br />

PSP preventive service planning<br />

PTF program temporary fix<br />

PUNC possibly uncommitted<br />

PWH Per<strong>for</strong>mance Warehouse<br />

QA Quality Assurance<br />

QMF Query Management Facility<br />

RACF Resource Access Control Facility<br />

RBA relative byte address<br />

RBLP recovery base log point<br />

RECFM record <strong>for</strong>mat<br />

RID record identifier<br />

RR repeatable read<br />

RRS resource recovery services<br />

RRSAF resource recovery services attach<br />

facility<br />

RPO recovery point objective<br />

RS read stability<br />

RTO recovery time objective<br />

SCUBA self contained underwater<br />

breathing apparatus<br />

SDM System Data Mover<br />

SMIT System Management Interface Tool<br />

SPL selective partition locking<br />

SU Service Unit<br />

UOW unit of work<br />

XRC eXtended Remote Copy<br />

WLM workload manager<br />

WTO write to operator


Related publications<br />

<strong>IBM</strong> <strong>Redbooks</strong><br />

The publications listed in this section are considered particularly suitable <strong>for</strong> a more detailed<br />

discussion of the topics covered in this book.<br />

For in<strong>for</strong>mation on ordering these publications, see “How to get <strong>IBM</strong> <strong>Redbooks</strong>” on page 427.<br />

Note that some of the documents referenced here may be available in softcopy only.<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8: Everything You Ever Wanted to Know, ... and More,<br />

SG24-6079<br />

► Disaster Recovery with <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-6370<br />

► <strong>DB2</strong> Per<strong>for</strong>mance Expert <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 2, SG24-6867-01<br />

► A Deep Blue View of <strong>DB2</strong> Per<strong>for</strong>mance: <strong>IBM</strong> Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> Per<strong>for</strong>mance<br />

Expert on z/<strong>OS</strong>, SG24-7224<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Technical Preview, SG24-6871<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 <strong>Version</strong> 7 Per<strong>for</strong>mance <strong>Topics</strong>, SG24-6129<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390 <strong>Version</strong> 7 Selected Per<strong>for</strong>mance <strong>Topics</strong>, SG24-6894<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390: Ready <strong>for</strong> Java, SG24-6435<br />

► Distributed Functions of <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390, SG24-6952<br />

► z/<strong>OS</strong> Multilevel Security and <strong>DB2</strong> Row-level Security Revealed, SG24-6480<br />

► Ready <strong>for</strong> e-business: <strong>OS</strong>/390 Security Server Enhancements, SG24-5158<br />

► XML <strong>for</strong> <strong>DB2</strong> In<strong>for</strong>mation Integration, SG24-6994<br />

► <strong>IBM</strong> Enterprise Workload Manager, SG24-6350<br />

► <strong>IBM</strong> eServer zSeries 990 (z990) Cryptography Implementation, SG24-7070<br />

► <strong>DB2</strong> <strong>for</strong> MVS/ESA <strong>Version</strong> 4 Data Sharing Per<strong>for</strong>mance <strong>Topics</strong>, SG24-4611<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>: Data Sharing in a Nutshell, SG24-7322<br />

► How does the MIDAW facility improve the per<strong>for</strong>mance of FICON channels using <strong>DB2</strong> and<br />

other workloads?, REDP4201<br />

► Disk storage access with <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, REDP4187<br />

The following publications, not referenced in this book, provide other up-to-date in<strong>for</strong>mation<br />

on related topics:<br />

► Data Integrity with <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-7111<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>: Design Guidelines <strong>for</strong> High Per<strong>for</strong>mance and Availability, SG24-7134<br />

► The Business Value of <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong>, SG24-6763<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> Stored Procedures: Through the CALL and Beyond, SG24-7083<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and WebSphere: The Perfect Couple, SG24-6319<br />

► Large Objects with <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> and <strong>OS</strong>/390, SG24-6571<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 425


► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> V8: Through the Looking Glass and What SAP Found There,<br />

SG24-7088<br />

► Moving Data Across the <strong>DB2</strong> Family, SG24-6905<br />

Other publications<br />

Online resources<br />

These recently updated publications are also relevant as further in<strong>for</strong>mation sources:<br />

► z/Architecture Principles of Operation, SA22-7832<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Administration Guide, SC18-7413-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Application Programming and SQL Guide, SC18-7415-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Application Programming Guide and Reference <strong>for</strong> Java,<br />

SC18-7414-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Command Reference, SC18-7416-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Data Sharing: Planning and Administration, SC18-7417-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Installation Guide, GC18-7418-02<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Messages and Codes, GC18-7422-01<br />

► <strong>DB2</strong> <strong>UDB</strong> ODBC Guide and Reference, SC18-7423-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 RACF Access Control Module Guide, SC18-7433-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Release Planning Guide, SC18-7425-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 SQL Reference, SC18-7426-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Utility Guide and Reference, SC18-7427-01<br />

► <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Program Directory, GI10-8566-02<br />

► z/<strong>OS</strong> Planning <strong>for</strong> Multilevel Security and Common Criteria, SA22-7509<br />

► Article Unicode Per<strong>for</strong>mance in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, by Jeffrey Berger and Kyoko Amano,<br />

published in the IDUG Solutions Journal Volume 11 Number 2<br />

► Article Using 64-bit Virtual Storage and Large Real Storage to Improve Per<strong>for</strong>mance and<br />

Availability in <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong>, by Jeffrey Berger, The IDUG Solutions Journal Volume 11<br />

Number 3<br />

► Article <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> <strong>OS</strong>/390 Storage Management by John Campbell and Mary Petras,<br />

The IDUG Solutions Journal Spring 2000 - Volume 7, Number 1.<br />

► The manual <strong>DB2</strong> <strong>UDB</strong> Internationalization Guide<br />

is available from the <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> Web site:<br />

http://www.ibm.com/software/data/db2/zos/v8books.html<br />

These Web sites and URLs are also relevant as further in<strong>for</strong>mation sources:<br />

► <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> :<br />

http://ibm.com/software/db2zos/<br />

► The CFSIZER can be found at:<br />

http://www.ibm.com/servers/eserver/zseries/cfsizer/<br />

► <strong>DB2</strong> Data Management Tools and <strong>DB2</strong> <strong>for</strong> z/<strong>OS</strong> V8.1 Compatibility:<br />

426 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


http://www.ibm.com/support/docview.wss?rs=434&context=SSZJXP&uid=swg21162152&loc=en_US&c<br />

s=utf-8&lang=en+en<br />

► The CF levels are described at:<br />

http://www.ibm.com/servers/eserver/zseries/pso/coupling.html<br />

► <strong>DB2</strong> Estimator:<br />

http://www.ibm.com/software/data/db2/zos/estimate/<br />

How to get <strong>IBM</strong> <strong>Redbooks</strong><br />

Help from <strong>IBM</strong><br />

You can search <strong>for</strong>, view, or download <strong>Redbooks</strong>, Redpapers, Hints and Tips, draft<br />

publications and Additional materials, as well as order hardcopy <strong>Redbooks</strong> or CD-ROMs, at<br />

this Web site:<br />

ibm.com/redbooks<br />

<strong>IBM</strong> Support and downloads<br />

ibm.com/support<br />

<strong>IBM</strong> Global Services<br />

ibm.com/services<br />

Related publications 427


428 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


Index<br />

Numerics<br />

00D70027 229<br />

16 exabytes 3, 142<br />

-20248 417<br />

4096 partitions 144<br />

64-bit<br />

Addressability 13, 142, 144, 157<br />

Virtual storage xxv, 2, 18, 127<br />

65041 open data sets 5, 128, 213<br />

767 5<br />

-952 307<br />

A<br />

AA12005 313<br />

Accounting enhancements 208<br />

ACCUMACC 26, 365<br />

Additional high water mark counters 205<br />

Advisory reorg pending 230<br />

Agent level workfile tracing 211<br />

ALTER BUFFERPOOL 25, 169, 339, 345<br />

ALTER GROUPBUFFERPOOL 25, 345<br />

ALTER INDEX<br />

NOT PADDED 242<br />

PADDED 242<br />

ALTER TABLE<br />

ADD MATERIALIZED QUERY 41<br />

ROTATE PARTITION FIRST TO LAST 233<br />

ALTER TABLE ADD PARTITION 233<br />

Application Program Interface 31<br />

application requestor 287<br />

application server 285<br />

Architecture xxv, 2, 9, 12–13, 16, 130, 281, 284–285<br />

AREO* 230, 235<br />

Array fetch 285, 292<br />

Array input 285<br />

AS 40, 84<br />

AS SECURITY LABEL 193<br />

ASENSITIVE 94–96, 99, 103<br />

Assign 147, 194, 258<br />

ATOMIC 53, 87<br />

Audit record 212<br />

AUTHCACH 26<br />

Automatic LPL recovery 257, 337<br />

Automatic query rewrite 39–41, 43, 46–47, 52<br />

automatic space management 5, 229<br />

Automatic summary tables 39<br />

Availability enhancements<br />

Other 217<br />

AVG 109<br />

B<br />

BACKUP 4, 6, 26, 217, 219, 221–223, 243, 261<br />

BACKUP SYSTEM 217–218, 220, 223–226<br />

DATA ONLY 223–224<br />

FULL 223<br />

Backward index scan 7, 107<br />

Batched index page splits 320<br />

BLKSIZE 25<br />

BOTH 274<br />

BOTH, 74<br />

BPSIZE 142<br />

BSDS 6, 219–220, 358<br />

Buffer pool<br />

Control blocks 17, 19, 141–142, 159, 162, 164, 394<br />

Buffer pools 141–142<br />

BUILD2 4, 248, 255<br />

Elimination of 248<br />

Built-in functions 188–189<br />

DECRYPT_BIN 188<br />

DECRYPT_CHAR 188<br />

ENCRYPT 188–189<br />

ENCRYPT_TDES 188<br />

GETHINT 188<br />

Built-in security labels 193<br />

Business In<strong>for</strong>mation Warehouse 6<br />

Byte addressable 142<br />

C<br />

CACHE 25–26, 29, 53, 59, 65, 129, 143, 147, 153, 158,<br />

165, 198, 201, 336, 351, 366, 394–395<br />

Cached statement ID 210–211<br />

CACHEDYN 25<br />

CARDF 276<br />

CARDINALITY 7, 30, 41, 73–74, 83, 85–86, 114–115,<br />

124, 273, 275, 277, 402, 405<br />

CARDINALITY MULTIPLIER 83<br />

Cardinality values 74, 273<br />

CASTOUT 3, 12, 18, 20, 25, 142, 153, 158–160,<br />

322–323, 333, 337, 339, 346, 394–396<br />

Castout owner 323<br />

CASTOUT processing 22, 138, 319, 321, 323, 334–335<br />

CATEGORY 114, 117, 192, 194, 310, 415<br />

CATMAINT 351, 356–357<br />

CATMAINT UPDATE 351, 356<br />

CCSID 174–177, 179–181, 183–184, 304, 343<br />

1200 177<br />

1208 177, 179<br />

UNICODE 175, 342<br />

CCSID set 414<br />

CF 324, 336, 339, 388<br />

CF level 12 22, 319, 321<br />

CF lock propagation reduction 8<br />

CF request batching 22, 26, 132, 135, 138, 319, 321–325<br />

Change Log Inventory utility 283–284<br />

changeable parameters 256<br />

Changing partition boundaries 230<br />

character conversion 342<br />

© Copyright <strong>IBM</strong> Corp. 2005. All rights reserved. 429


character set 174<br />

CHECK DATA 262<br />

CHECK INDEX 5, 133, 240, 242, 249, 253, 262–267<br />

CHECK INDEX SHRLEVEL(REFERENCE) PART 265<br />

Child L-lock propagation 331<br />

CHKFR 26<br />

CI size 6, 199, 202<br />

CICS 130, 160<br />

CISIZE 199<br />

CLASSPATH 293–294<br />

CLASST 25, 346<br />

clear key 189<br />

CLOB 307, 309<br />

CL<strong>OS</strong>E NO 320<br />

close processing <strong>for</strong> pseudo close 320<br />

CLUSTER 4, 8, 115, 199, 401, 403<br />

cluster table 246<br />

Cluster tables 8<br />

Clustering 400, 403<br />

Clustering index 3–4, 247<br />

Secondary index 247<br />

Clusters 8<br />

CMTSTAT 26<br />

Code page 22, 174, 177<br />

COLGROUP 73–74, 274, 276<br />

Collating sequence 68, 247<br />

Column type change 4<br />

COMMENT 205, 347<br />

Common table expression and recursive SQL 6<br />

Common table expressions 259<br />

Recursive SQL 6<br />

Communications database 283<br />

Compatibility mode 8, 13, 133–136, 286, 343, 354<br />

compatibility mode<br />

functions available 18<br />

Compression dictionaries 141<br />

Compression dictionary 6, 144, 158, 160, 394, 396<br />

Concurrent copy 6, 200, 263, 266<br />

CONDBAT 25, 206<br />

CONNECT 182, 206, 283, 285, 351<br />

connection concentration 299<br />

CONTOKEN 401<br />

Control Center 314<br />

CONTSTOR 145–146<br />

Conversion<br />

Remote applications 176<br />

Coprocessor 188, 190<br />

COPY 112, 133, 142, 200, 202, 218, 220, 226, 263, 266,<br />

359, 364, 371<br />

Copy pool 218–222, 225<br />

COPYPOOL 219, 223–224<br />

COUNT 30, 40–41, 46–47, 50–51, 69, 72–73, 108–109,<br />

158, 164, 189, 206, 254–255, 274, 276, 279, 360, 395,<br />

400<br />

Coupling Facility 257, 319–325, 327–332, 336, 339<br />

CPACF 188<br />

Create index dynamic statement invalidation 5<br />

CSA 158, 162, 172, 396<br />

CSV 270<br />

CT 143<br />

430 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

CTHREAD 25, 162, 205–206<br />

CURRENT MAINT TYPES 42, 352<br />

CURRENT MAINTAINED TABLE TYPES FOR OPTIMI-<br />

ZATION 124, 352<br />

CURRENT REFRESH AGE 42, 44, 124, 352<br />

CURRENT SQLID 212, 259, 408<br />

CYCLE 223, 226, 354<br />

D<br />

Data caching 6, 65<br />

Data Encryption <strong>for</strong> IMS and <strong>DB2</strong> Databases 369<br />

Data Encryption Tool 189<br />

DATA INITIALLY DEFERRED 40–41<br />

Data Manager 158, 394–395<br />

data set extend 226<br />

data sharing 319<br />

Data sharing locking 319, 325–326, 328, 335<br />

Data source property 179, 188<br />

data space 141–143, 148, 158–159, 164, 394<br />

Data space buffer pool 141, 159<br />

Database name 283<br />

Data-partitioned secondary index 4, 248, 274<br />

Data-partitioned secondary indexes 4<br />

DATE 53, 122, 158, 175, 206, 272, 395<br />

<strong>DB2</strong> Administration Tools 230<br />

<strong>DB2</strong> Archive Log Accelerator 367<br />

<strong>DB2</strong> authorization 260<br />

<strong>DB2</strong> Bind Manager 370<br />

<strong>DB2</strong> catalog changes 11, 23, 344<br />

<strong>DB2</strong> CLI 285<br />

<strong>DB2</strong> Connect 177–179, 187, 281, 284–285, 290, 297,<br />

299<br />

<strong>DB2</strong> Connect and DRDA 3<br />

<strong>DB2</strong> Connect Personal Edition 112<br />

<strong>DB2</strong> Data Archive Expert 370<br />

<strong>DB2</strong> Estimator 364<br />

<strong>DB2</strong> High Per<strong>for</strong>mance Unload 370<br />

<strong>DB2</strong> per<strong>for</strong>mance consulting offering 167<br />

<strong>DB2</strong> Query Monitor 368<br />

<strong>DB2</strong> restart light 337<br />

<strong>DB2</strong> SQL Per<strong>for</strong>mance Analyzer <strong>for</strong> z/<strong>OS</strong> 369<br />

<strong>DB2</strong> tools 363<br />

<strong>DB2</strong> Universal driver 292, 294–295, 303–304, 306<br />

<strong>DB2</strong> Universal Driver <strong>for</strong> SQLJ and JDBC 281, 285,<br />

293–294<br />

<strong>DB2</strong> Utilities Suite 370<br />

<strong>DB2</strong> V8 APARs 378, 386<br />

Dbalias 283<br />

DBCS 174, 180, 186, 342, 414<br />

DBD 20, 23, 25, 135, 142, 158, 243, 351, 396<br />

DBD01 220<br />

DBM1 STORAGE STATISTICS 163<br />

DBM1 Storage Statistics 158<br />

DBM1 virtual storage constraint 129<br />

DBRM 23, 113, 206, 361<br />

DDF 8, 21, 25–26, 94, 208–209, 281, 283–285, 295, 338,<br />

351–352<br />

Declared temporary table 91, 408, 410<br />

Delayed index availability 231<br />

DELIMITED 371


UNLOAD 371<br />

DES 188–189<br />

DFSMS 201, 217–218, 221, 226, 229<br />

DFSMShsm 4, 27, 218–220, 224<br />

DFSORT 26, 263, 274<br />

DIS GROUP 354<br />

DISABLE QUERY OPTIMIZATiON 40, 53<br />

Disaster recovery 4, 221<br />

Disjoint 194<br />

DIST address space 152, 176–177, 290–291<br />

Distribution statistics 7, 72, 76, 273–278, 280<br />

DNAME 403<br />

Dominance 193–194, 196<br />

Dominate 194–195, 197<br />

Double Byte Character Set 174, 342, 414<br />

DPSI 92, 247–256<br />

BUILD2 250–251<br />

CHECK INDEX 252<br />

Data sharing 255<br />

LOAD 248<br />

DRAIN ALL 264, 337<br />

DRDA 3, 15, 18, 21–22, 130, 132, 136, 177, 179, 181,<br />

206, 208, 280–281, 284–290, 293, 295–296, 303, 354<br />

DSC 7, 152<br />

DSC statement ID in Explain 7<br />

DSMAX 26, 162, 213, 338<br />

DSN6ARV 25<br />

DSN6FAC 25–26<br />

DSN6SPRM 25–26<br />

DSN6SYSP 25–26, 352<br />

DSN8EXP 259<br />

DSNAIMS 384<br />

DSNB250E 337<br />

DSNB406I 169<br />

DSNB508I 153<br />

DSNB536I 153, 157<br />

DSNB543I 169<br />

DSNB610I 153, 157<br />

DSNDB06.SYSDDF 345<br />

DSNDB06.SYSSTR 345<br />

DSNHDECP 175, 350–351, 353<br />

DSNHMCID 350<br />

DSNI031I 207<br />

DSNJ031I 258<br />

DSNJU003 220<br />

DSNR031I 207, 256<br />

DSNR035I 258<br />

DSNTEJ3M 123<br />

DSNTEJXP 259<br />

DSNTEP2 346<br />

DSNTEP4 29, 136, 346–347<br />

MULT_FETCH 347<br />

DSNTESQ 359, 362<br />

DSNTIAUL 136, 189, 346, 348–350, 371, 374–375<br />

DSNTIJNE 353, 356, 358–359<br />

DSNTIJNF 353<br />

DSNTIJNH 353, 358<br />

DSNTIJTC 351<br />

DSNTIP5 25<br />

DSNTIP6 42<br />

DSNTIP7 25, 351<br />

DSNTIP8 352<br />

DSNTIPC 25, 351<br />

DSNTIPE 25, 351<br />

DSNTIPF 351<br />

DSNTIPN 26, 351<br />

DSNTIPP 26, 351<br />

DSNTIPR 26, 351<br />

DSNU1129I 245<br />

DSNUTILB 263<br />

DSNUTILS 111, 117<br />

DSNUTILS stored procedure 111<br />

DSNWZP 111<br />

DSNX@XAC 195<br />

DSNZPARM 9, 14, 17, 20, 42, 64–65, 111, 128, 136,<br />

138, 143–144, 147, 160, 173, 199, 205, 207, 209, 213,<br />

220, 225–227, 232, 246, 256–257, 332, 395<br />

CACHEDYN 20, 143<br />

CMTSTAT 209<br />

NPGTHRSH 246<br />

UIFCIDS 205<br />

DSNZPARM default values 24–25<br />

DSSIZE 4, 229<br />

DSTATS 275–278, 280<br />

DSVCI 199<br />

DTT 91, 93<br />

DTYPE 404<br />

DWQT 25, 345<br />

Dynamic allocations 213<br />

Dynamic scrollable cursor<br />

Example 107<br />

Dynamic scrollable cursors 91, 94–95, 97, 107<br />

Considerations 95<br />

Locking 94<br />

UPDATE 94<br />

Dynamic statement cache 3, 5, 7, 12, 20, 143, 146, 148,<br />

152, 160, 211, 236, 304, 352, 394–396<br />

DYNAMICRULES 259<br />

E<br />

ECSA 21, 127, 162, 172–174, 396<br />

EDITPROC 189<br />

EDM pool 3, 16, 20, 25, 139, 141–143, 148–149, 153,<br />

158–159, 162, 209, 331, 352, 366, 394, 396<br />

EDMDBDC 25, 143<br />

EDMDSPAC 143<br />

EDMPOOL 25, 143, 160, 351<br />

EDMSTMTC 25, 143<br />

ENABLE QUERY OPTIMIZATION 40<br />

Enabling-new-function mode 8<br />

ENCODING 174, 205, 342, 351<br />

Encoding scheme 11, 174, 176, 304, 342, 344, 353,<br />

414–415<br />

encryption 188<br />

Encryption functions 188<br />

encryption keys 190<br />

ENDING AT 233<br />

ENFM 8, 13–14, 24, 135, 345, 353, 357<br />

ENFORCED 21, 41, 194, 268, 343<br />

Enterprise Workload Manager 312<br />

Index 431


Equi-join predicates 54, 402<br />

Equivalence 51, 194<br />

ESS FlashCopy 218<br />

EWLM 312<br />

EXISTS 360<br />

Expanded storage 13, 17, 19, 153<br />

Explain 7, 42, 47, 50, 72, 111, 115, 124, 127, 161, 211,<br />

258–259, 275, 365, 369, 407–408, 413, 415–416<br />

Explicit clustering 248<br />

Explicit clustering index 247<br />

External access control 192<br />

EXTSEQ 26<br />

F<br />

FACILITY class 194<br />

Fact table 54–55, 58–59<br />

Fallback 8, 14, 18, 135, 138, 176, 343, 353–354<br />

False contention 8, 328–329, 331<br />

Fast cached SQL statement invalidation 7<br />

fast column processing 22<br />

Fast log apply 21, 220, 225–226, 352<br />

Fast Replication 27<br />

Fast replication services 217<br />

FETCH 7, 15, 31, 35–36, 38, 81–82, 85–86, 91, 93,<br />

95–97, 99–100, 102–104, 115, 124, 131, 139, 190, 196,<br />

208, 234, 237–238, 285–286, 292, 323, 347–349, 411<br />

FETCH CURRENT 96<br />

FETCH RELATIVE 96<br />

FETCH SENSITIVE 93, 100–101, 105<br />

Fetch/Delete 35<br />

Fetch/Updat 35<br />

Filter factor estimation 74<br />

Fixed pools 141<br />

FLA 21, 220–221, 225, 388<br />

FlashCopy 200, 218, 224, 261, 263, 265–266<br />

FOR BIT DATA 189, 345<br />

FOR n ROWS 284<br />

FOR ROW n OF ROWSET 34<br />

FOR UPDATE OF 97<br />

FORMAT DELIMITED 376<br />

FRBACKUP 219<br />

FRDELETE 219<br />

FREEMAIN 141, 162<br />

FREQVAL 73, 274, 276, 279<br />

FRRECOV 219, 224<br />

Full system backup 220<br />

G<br />

GBP checkpoint 25<br />

GBPCHKPT 25, 346<br />

GBP-dependent objects 325<br />

GBPOOLT 25, 346<br />

GET DIAGN<strong>OS</strong>TICS 346<br />

Multi-row insert 33<br />

GETMAIN 141, 394, 396<br />

Getmained Block Storage 141<br />

GETVARIABLE 199<br />

Global lock contention 131, 319, 325–326, 331<br />

global lock contention 136<br />

432 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

GMB 141<br />

Granularity 87, 174, 191, 195, 326, 368<br />

GRAPHIC 68–69, 72, 124, 175, 177–178, 180–181, 183,<br />

185, 187, 231, 343<br />

Group restart 327<br />

H<br />

Hardware compression 144<br />

HC3 184<br />

Hierarchical security level 192<br />

Hiperpool 19, 141, 158–159, 352, 394<br />

Host variable array 32, 38, 289<br />

host variable array 32<br />

Host variables impact on access paths 7<br />

Host-variable 33, 256<br />

HPSIZE 142<br />

HVA 32<br />

Hybrid join 54, 75<br />

I<br />

I/O CI limit removed<br />

319<br />

ICF catalog 219<br />

ICSF 188–190<br />

IDBACK 25, 205–206<br />

IDFORE 25, 205–206<br />

IDTHTOIN 25<br />

IFCID<br />

0335 256<br />

124 211<br />

140 212<br />

142 212<br />

148 321<br />

172 206<br />

217 205<br />

234 212<br />

239 209<br />

3 207, 209, 212, 256, 258, 321<br />

313 207, 258<br />

317 211<br />

335 212<br />

337 207<br />

342 211<br />

350 211<br />

63 211<br />

IFCID 173 210<br />

IFCID 225 145, 159, 365–366<br />

IFCID 316 417<br />

IFCID 318 417<br />

IFCIDs 205, 210<br />

II10817 378<br />

II13695 378, 386<br />

II14047 269, 378<br />

II14106 382<br />

II4309 378<br />

image copy 375<br />

Immediate index availability 231<br />

IMMEDWRI 332<br />

IMMEDWRITE 137, 319, 332


IMMEDWRITE NO 333<br />

Implicit clustering 248<br />

Improved LPL recovery 257, 320, 336<br />

IMS 171, 188–189<br />

Inactive connection 353<br />

Inactive DBAT 353<br />

Index only access <strong>for</strong> varchar 7<br />

Index-controlled partitioning 247<br />

Indoubt units of recovery 320, 338<br />

indoubt URs 320, 338<br />

in<strong>for</strong>mational referential constraints 45<br />

Inherit WLM priority from lock waiter 258<br />

In-memory workfiles 6, 56<br />

INSENSITIVE 92–96, 98, 103, 107<br />

INSERT 7, 16, 32, 35, 38, 40–41, 86, 102, 111, 124, 131,<br />

136, 139, 179, 181, 183, 188, 196–197, 208, 227, 229,<br />

232, 234–236, 248–249, 251–252, 259, 270, 281, 285,<br />

288–292, 310–311, 319, 321, 332, 359, 400, 403, 408,<br />

411–413, 415<br />

Integrated Cryptographic Service Facility 188–189<br />

IPCS 165<br />

IRLM 9, 12, 127, 134–137, 140, 153–154, 172–173, 324,<br />

327–331<br />

IRLM V2.2 21, 127, 153, 171–173<br />

IRR.WRITEDOWN.BYUSER profile 194<br />

IS NULL 360–361<br />

ISO 99, 101, 103, 105, 215<br />

IVP sample programs 346<br />

IXQTY 228<br />

J<br />

Java xxv, 3, 66, 112, 175–177, 179–182, 281, 285,<br />

292–293, 295, 304, 312<br />

Java Common Connectivity 293<br />

JCC 292–295, 304<br />

JDBC 2.0 294, 306<br />

JDBC 3.0 293<br />

JDBC-ODBC bridge 292<br />

JOIN_TYPE 54, 413<br />

K<br />

KEEPDYNAMIC 147–148, 209, 304–305<br />

L<br />

LARGE 229<br />

large address space 3<br />

large catalog/directory 359<br />

large CIs 200<br />

large pages 202<br />

large secondary allocations 228<br />

large strings 186<br />

large table space scan 6<br />

Larger buffer pools 17, 139, 141, 171<br />

LEAST 40, 74, 106, 143, 187, 194, 256, 274, 276, 284,<br />

326, 354<br />

LEAST frequently occurring values 74, 273<br />

Legacy driver 177, 179, 294<br />

LIST 219<br />

List prefetch 12, 137, 160, 221, 225, 319, 321, 333, 335,<br />

395, 400, 402, 405<br />

list prefetch 335, 408<br />

LISTDEF 264<br />

L-locks 8, 319, 325–329, 331<br />

LOAD 132, 271<br />

FORMAT DELIMITED 271<br />

LOAD table PART n REPLACE 243<br />

LOB 72, 145, 228, 305, 307, 351, 380, 389, 409<br />

LOB ROWID transparency 5<br />

LOBVALA 25, 145<br />

LOBVALS 145<br />

Local SQL cache issues and short prepare 7<br />

Location alias 284<br />

Location name 206, 219, 283–284, 293<br />

Lock contention 96, 131, 174, 319, 325–326, 331<br />

Lock escalation 33, 173–174, 207–208<br />

Lock escalation trace record 8<br />

Locking 7, 23, 93, 134–136, 138, 173–174, 208, 319,<br />

325–328, 330–331, 335, 337, 365<br />

log copy 6<br />

Log data sets 128, 202, 213<br />

LOG NO events 218<br />

Log truncation point 220<br />

LOGAPSTG 26<br />

Logical partition 233, 245, 255, 264<br />

Logical partitions 250–251<br />

Long index keys 129<br />

Long names 5, 33, 129, 135, 152, 205, 261, 344–345,<br />

353<br />

long names 164<br />

Long running UR backout 256<br />

long term page fix 320<br />

Longer SQL statements xxv<br />

Longer table and column names 5, 346<br />

Long-term page fixing 169<br />

Lookaside pool 17<br />

LOOP 48, 50, 53–54, 58, 405, 410<br />

LPL 337<br />

LPL recovery 257, 320, 336<br />

LRDRTHLD 207, 258<br />

LRSN 358<br />

LRU 13, 171<br />

M<br />

Management Client Package 112<br />

Materialized query table 39–40, 42–43, 53, 124, 408, 410<br />

materialized query tables 6, 23, 39, 41, 43, 124, 352<br />

Materialized snowflakes 53<br />

MAXCSA 172–173<br />

MAXDBAT 25, 206<br />

Maximum number of partitions 4<br />

MAXKEEPD 145–147, 160<br />

MEMLIMIT 172, 174<br />

Memory usage 152, 396<br />

MGEXTSZ 227, 229<br />

Migration 8, 11, 14, 19, 113, 148, 199, 283, 341,<br />

350–351, 353–354, 356–359, 366<br />

Migration process 8, 343, 353<br />

Minimize impact of creating deferred indexes 5<br />

Index 433


MINSTOR 145–146<br />

Mismatched data type 67, 77<br />

MLMT 172<br />

MLS 191, 194–195, 198<br />

MODIFY 139, 172, 226, 233, 354, 359, 371<br />

Monitor system checkpoints 212, 256<br />

Monitoring<br />

Log offload activity 212<br />

More log data sets xxv, 6<br />

More partitions 4, 256<br />

M<strong>OS</strong>T 74, 274<br />

MQT 39–43, 45, 48, 50–53, 123–124, 408<br />

Considerations 52<br />

Creation 40<br />

CURRENT REFRESH AGE 123<br />

Summary 47<br />

System-maintained 40<br />

User-maintained 40<br />

MSTR 154<br />

MSTR address space 137, 153, 155, 332–333<br />

MSTR SRB 333<br />

Multilevel security 8, 26, 191, 193–194, 197<br />

Requirements 27<br />

Utilities 197<br />

Multilevel security at the object level 192<br />

Multilevel security with row-level granularity 192<br />

Multiple DISTINCT clauses in SQL statements 5<br />

Multiple IN values 7<br />

Multiple physical partitions 247<br />

Multi-row fetch 21, 31–33, 35, 37–38, 103–106, 136,<br />

281, 285, 287–291, 346, 348<br />

Positioned DELETE 33<br />

Positioned UPDATE 33<br />

Rowset 106<br />

multi-row fetch 31<br />

Multi-row FETCH and INSERT 102, 285<br />

Multi-row INSERT 16, 32, 36, 289, 291<br />

ATOMIC 33<br />

GET DIAGN<strong>OS</strong>TICS 33<br />

multi-row INSERT and FETCH 6<br />

MVS system failure 325, 337<br />

N<br />

nested loop join 69, 112<br />

Net driver 293, 299<br />

New Function Mode 289<br />

New table spaces 345<br />

New tables 345<br />

New-function mode 8, 218<br />

NO SCROLL 94<br />

Non-clustering index 247<br />

Non-GBP-dependent 326, 338<br />

Non-partitioned index 247, 255, 265, 267, 275<br />

Non-partitioned indexes 248, 255<br />

NOT CLUSTER 248<br />

NOT EXISTS 113<br />

NOT NULL WITH DEFAULT 409<br />

NOT PADDED 217, 237–239, 242, 358, 400–401,<br />

403–404<br />

NPAGES 246<br />

434 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

NPGTHRSH 246<br />

NPI 137, 243–244, 249–255, 265<br />

NPSI 248<br />

NUMLKTS 174<br />

NUMLKUS 174<br />

O<br />

OA04555 390<br />

OA05960 390<br />

OA06729 390<br />

OA07196 xxii, 313, 390<br />

OA07356 xxii, 313, 390<br />

OA08172 190, 390<br />

OA10984 202<br />

OA12005 xxii, 390<br />

OA15666 384, 391<br />

OA17114 391<br />

Object 11, 111, 176, 181, 185, 192, 195, 205, 207, 230,<br />

258, 263, 284, 323, 336, 338<br />

ODBC 15, 154, 281, 285–286, 290–292, 306<br />

Online DSNZPARMs 256<br />

Online partitioning changes 4<br />

Online REORG 5, 133, 248, 255, 258, 264, 359<br />

Online schema evolution 3–4, 217, 230, 261<br />

Open Group’s DRDA 281<br />

optimistic locking 107<br />

optimizer enhancements 18<br />

ORDER BY 23, 82, 86, 99, 410<br />

<strong>OS</strong>/390 V2R10 190<br />

OW54685 336<br />

P<br />

Package level accounting 8, 208<br />

PADDED 137, 183, 217, 232, 237–239, 241–242, 264,<br />

358, 401, 403–404<br />

VARCHAR 11, 137, 232, 237–238, 345, 401,<br />

403–404<br />

page set 323<br />

Page set P-locks 326, 331<br />

Panel<br />

DSNTIP4 42, 147<br />

DSNTIP7 199, 352<br />

DSNTIPP 352<br />

Parallel Access Volume 30<br />

Parallel index build 268–269<br />

parallelism 254<br />

Parallelism details 111<br />

Parameter marker 256<br />

Parent lock contention 326<br />

PARTITION 4, 59, 111, 137, 144, 160, 230, 233, 243,<br />

245, 248–253, 255, 257, 262, 264–265, 267–268, 275,<br />

327, 336<br />

PARTITION BY 247<br />

Partition management 233<br />

Partition pruning 247, 255<br />

PARTITIONED 4, 34, 36, 38, 160, 217, 233, 237,<br />

246–248, 254–257, 263, 268, 270, 274, 327, 346, 372<br />

Partitioned index 245, 247, 255, 265, 267, 275<br />

Partitioned secondary indexes 4, 247, 264


Partitioning 4, 217, 233, 247–248, 255–257, 261<br />

Partitioning index 3–4, 217, 246–248, 257<br />

Partitioning indexes 257<br />

Partitioning key update 257<br />

PARTKEYU 257<br />

PC=NO 127, 172–173<br />

PC=YES 136, 172–173<br />

Per<strong>for</strong>mance 6<br />

Multi-row operations 37, 289<br />

PERMIT 107, 193<br />

PGFIX 21, 169–171, 339<br />

PGPROT 172<br />

Physical partitions 245, 247, 250–251, 255<br />

Physically partitioned 247–248<br />

PIECESIZE 229<br />

PK00213 382<br />

PK01510 xxii, 382<br />

PK01841 382<br />

PK01855 382<br />

PK01911 382<br />

PK03293 382<br />

PK03469 xxii, 382<br />

PK04076 xxii, 269, 382<br />

PK04107 382<br />

PK05360 xxii, 382<br />

PK0564 230<br />

PK05644 xxii, 382<br />

PK09158 382, 390<br />

PK09268 xxii, 382<br />

PK10021 383<br />

PK10278 383<br />

PK10662 383<br />

PK11355 383<br />

PK12389 xxii, 383<br />

PK13455 383<br />

PK14393 383<br />

PK14477 383, 390<br />

PK15056 383<br />

PK15288 383<br />

PK18059 383<br />

PK18162 383<br />

PK18454 383<br />

PK19191 383<br />

PK19303 383<br />

PK19769 383<br />

PK19920 383<br />

PK20157 383<br />

PK21237 150, 383<br />

PK21268 383<br />

PK21371 384<br />

PK21861 384<br />

PK21892 384<br />

PK22442 384<br />

PK22611 384<br />

PK22814 384<br />

PK22887 384, 390<br />

PK22910 384<br />

PK23495 384<br />

PK23523 384<br />

PK23743 384<br />

PK24556 384<br />

PK24558 384, 390<br />

PK24585 384<br />

PK24710 384<br />

PK24819 384<br />

PK25241 384<br />

PK25326 384<br />

PK25427 384<br />

PK25742 384<br />

PK26199 384<br />

PK26692 385<br />

PK26879 385<br />

PK27281 385<br />

PK27287 385<br />

PK27578 385<br />

PK27712 385<br />

PK28561 385<br />

PK28637 385<br />

PK29626 385<br />

PK29791 385<br />

PK29826 385<br />

PK30087 385<br />

PK30160 385<br />

PK32606 385<br />

PK34251 385<br />

PK34441 385<br />

PK35390 385<br />

PK36717 385<br />

PK37354 385<br />

PK38201 385<br />

PK40057 385<br />

PK41182 382<br />

PK46170 386<br />

PK47840 386, 390<br />

PK49972 386<br />

PLAN_TABLE access via a <strong>DB2</strong> alias 259<br />

P-locks 326, 331<br />

PM<strong>DB2</strong> 166<br />

point-in-time 4, 27, 218–219<br />

PORT 112, 293, 304<br />

P<strong>OS</strong>ITION 91, 270, 281<br />

PQ47973 212, 386<br />

PQ49458 386<br />

PQ54042 67, 84, 386<br />

PQ61458 58–59, 65, 386<br />

PQ62695 112, 386<br />

PQ69741 320, 338, 386–387<br />

PQ69983 387<br />

PQ71179 387<br />

PQ71766 387<br />

PQ71775 362, 387<br />

PQ74772 387<br />

PQ75064 387<br />

PQ78515 387<br />

PQ79232 387<br />

PQ80631 378, 387<br />

PQ81904 387<br />

PQ82878 378, 387<br />

PQ83649 378<br />

PQ8416 280<br />

Index 435


PQ84160 378, 387<br />

PQ85764 387<br />

PQ85843 388<br />

PQ86037 388<br />

PQ86049 388<br />

PQ86071 335, 378<br />

PQ86074 379<br />

PQ86201 379<br />

PQ86477 204, 379, 388<br />

PQ86787 305, 379<br />

PQ86904 327, 379<br />

PQ87126 305, 379, 388<br />

PQ87129 305, 379<br />

PQ87168 327, 379<br />

PQ87381 379, 388<br />

PQ87390 379<br />

PQ87447 379, 388<br />

PQ87509 275, 379<br />

PQ87611 172, 379<br />

PQ87756 327, 379<br />

PQ87764 157<br />

PQ87783 388<br />

PQ87848 210, 379<br />

PQ87917 379, 388<br />

PQ87969 39, 379<br />

PQ88073 379, 417<br />

PQ88224 365<br />

PQ88375 275, 380<br />

PQ8841 179<br />

PQ88582 307, 380<br />

PQ88587 388<br />

PQ88665 229, 380<br />

PQ88784 24<br />

PQ88896 368, 380<br />

PQ89070 215, 380<br />

PQ89181 39<br />

PQ89297 380, 388<br />

PQ89919 335, 380, 389<br />

PQ90022 111, 259, 380, 389<br />

PQ90075 380, 389<br />

PQ90147 260, 380<br />

PQ90263 380, 389<br />

PQ90547 365, 380<br />

PQ90884 275, 277, 280, 380<br />

PQ91009 353, 380<br />

PQ91101 158, 163, 365, 381, 389<br />

PQ91493 381<br />

PQ91509 313, 381<br />

PQ91898 39, 381<br />

PQ92072 381<br />

PQ92227 254, 381<br />

PQ92749 262, 268, 381<br />

PQ93009 389<br />

PQ93156 381<br />

PQ93458 285<br />

PQ93620 39, 381<br />

PQ93821 111, 259, 381, 389<br />

PQ93943 190<br />

PQ9414 381<br />

PQ94147 389<br />

436 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

PQ94303 381<br />

PQ94793 389<br />

PQ94822 190, 381<br />

PQ94872 158, 163, 365, 381<br />

PQ94923 381<br />

PQ95164 221, 225, 381<br />

PQ95881 304, 381<br />

PQ95989 365<br />

PQ96189 213, 381<br />

PQ96628 382, 389<br />

PQ96772 143, 152, 382<br />

PQ96956 262, 268, 382<br />

PQ97794 382<br />

PQ99181 380<br />

PQ99482 39<br />

PQ99524 382, 389<br />

PQ99608 382<br />

PQ99658 xxii, 382, 389<br />

PQ99707 xxii, 313, 382<br />

PQTY 228<br />

PRECISION 68<br />

Precompiler 23, 354<br />

NEWFUN 23, 354<br />

PREFETCH 12, 158, 160, 170, 221, 225, 229, 319, 321,<br />

324, 333, 395, 400, 402, 405, 412<br />

Print Log Map utility 283<br />

PRIQTY 226, 228–229<br />

Private Protocol 284<br />

PT 143<br />

Q<br />

Q3STHWCT 205<br />

Q3STHWIB 205<br />

Q3STHWIF 205<br />

QMF 212, 408<br />

QMF <strong>for</strong> TSO/CICS 8.1 39<br />

Qualified partitions 256<br />

QUALIFIER 259, 408<br />

QUERY 219<br />

Query parallelism 29, 78, 254, 413<br />

QUERYNO 50, 400, 402, 405, 410, 415–416<br />

QUIESCE 263, 327, 331, 370<br />

Quotation mark 272<br />

R<br />

RACF 26, 139, 191–198<br />

RACROUTE 26<br />

RBA 256, 358<br />

RBDP 231–232, 236<br />

RBLP 220<br />

RDS 158, 160, 164, 395<br />

RDS sort 144<br />

Read For Castout Multiple 321<br />

READS interface 211<br />

Read-up 194<br />

Real contention 329<br />

Real memory 18, 153, 165<br />

Real storage 3, 9, 11, 13, 17, 19, 21, 65, 97, 127, 129,<br />

138, 142, 148, 153–154, 156–158, 165, 169–171, 174,


201, 320, 339, 365, 397<br />

REBALANCE 245<br />

Rebalance partitions 3, 233<br />

REBUILD INDEX 132, 202, 235, 237–238, 242, 249,<br />

252, 263<br />

Rebuild pending 231–232<br />

RECOVER 4, 21, 133, 183, 217–221, 233, 257, 320,<br />

336, 367<br />

Recovery base log point 220<br />

Recursive SQL 6<br />

Common table expressions 6<br />

<strong>Redbooks</strong> Web site 427<br />

Contact us xxviii<br />

Reduced lock contention 7<br />

REFRESH DEFERRED 40<br />

refresh MQTs 41<br />

REFRESH TABLE 40–42, 53, 124<br />

REGION 142, 158, 161, 173, 396<br />

REMARKS 412<br />

REORG 4, 8, 11, 132, 197, 202, 226, 230–231, 233–235,<br />

240, 242, 244–245, 247–248, 255, 258, 264, 268–269,<br />

354, 356, 359, 371<br />

Clustering order 268<br />

DISCARD 5, 197<br />

Implicit clustering index 247<br />

REBALANCE 244–245<br />

REORG INDEX 133<br />

REORG TABLESPACE 197, 233<br />

REBALANCE 233<br />

REORG utility enhancements 5<br />

REORP 233<br />

REPORT 7, 73–74, 116, 118, 122–123, 149, 162, 164,<br />

166, 207, 213, 258, 276, 328–330, 334, 365, 394<br />

Requester database ALIAS 281, 283<br />

RESET 16, 209, 236<br />

Residual predicates 66<br />

Resource<br />

Security label 192–193<br />

RESTART 218, 221, 256, 326–327, 331, 337<br />

Restart light enhancements 320, 337<br />

RESTART WITH 221<br />

RESTORE 4, 261, 367<br />

RESTORE SYSTEM 4, 21, 217–218, 220–221, 224–226<br />

RESTRICT 94<br />

Retained locks 172, 325, 337<br />

RETVLCFK 232<br />

Reverse dominance 194<br />

RFCOM 321–322<br />

RID 402, 404<br />

RID Pool 3, 17, 140, 144, 148–149, 153, 158, 160,<br />

394–395<br />

RIDBLOCK 145<br />

RIDLIST 145<br />

RIDLISTs 144<br />

RIDMAP 145<br />

RIDs 73, 115, 145<br />

RMF 26, 148, 166, 322, 324, 328–329<br />

ROLLBACK 206, 332, 368<br />

ROWID 5<br />

Rowset 29, 31, 33, 92, 94, 103, 105, 288–290, 292<br />

Rowsets 31, 33, 288–289<br />

RQRIOBLK 285<br />

RRSAF 8, 208, 296<br />

RUNSTATS 7, 53, 71, 73, 76, 110–111, 115–117,<br />

122–124, 132, 231, 238, 240, 242, 246, 248, 253, 273,<br />

275–278, 280, 401–403, 405<br />

RUNSTATS enhancement 272<br />

S<br />

SBCS 22, 174, 180, 185–186, 342–343, 414<br />

SCA 220, 320, 336<br />

Scalability xxv, 3, 9, 12, 20, 128–129, 212<br />

SCHEMA 54, 65, 217, 230, 233, 259, 353, 416<br />

Schema changes 230<br />

Schema evolution xxv, 3–4, 217, 230, 261<br />

SECDATA 192<br />

SECLABEL 192–193, 195–198, 212<br />

SECLEVEL 192, 198<br />

secondary AUTHIDs 260<br />

Secondary authorization ID in<strong>for</strong>mation 212<br />

Secondary index 4, 247–248, 274<br />

Clustering index 247<br />

SECQTY 226, 229<br />

secure key 189<br />

Security<br />

Object 192<br />

Security category 192<br />

Security label 192–194, 198, 212<br />

Security labels 192–194, 198<br />

Assigning 193<br />

Defining 192<br />

Security level 192, 194<br />

Security policy 191<br />

Security Server 191–192, 212<br />

SENSITIVE DYNAMIC 94, 96, 101, 105<br />

SENSITIVE STATIC 93–94, 100, 104<br />

Separation of partitioning and clustering 4<br />

Serialized profile 300<br />

Server location ALIAS 281, 283<br />

service time 9<br />

SET 34, 172, 226<br />

SET clause in the SQL UPDATE 199<br />

SET CURRENT REFRESH AGE ANY 42<br />

SET DPTDPTSZ 87<br />

SET ENCRYPTION PASSWORD 188<br />

SET QUERYNO 50<br />

-SET SYSPARM 256<br />

Shift-in 185, 344<br />

Shift-out 185, 344<br />

short prepare 146<br />

SIGNON 206, 260<br />

SJMXPOOL 54, 57, 65<br />

SKCT 143<br />

SKPT 143, 357<br />

SMF 26, 128, 136, 213, 351<br />

SMF89 213–214<br />

SMFSTST 26<br />

SMS-managed data sets 218<br />

Sort pool 3, 17, 144, 148–149, 153, 156<br />

SORT pools 144<br />

Index 437


Sort tree nodes 144<br />

SORTDATA 268<br />

SORTDEVT 74, 263, 274<br />

SORTKEYS 261, 268–269<br />

SORTNUM 74, 263, 274<br />

Sparse index <strong>for</strong> star join 6, 59<br />

Special register 42, 189, 256, 352<br />

Special registers 41–42, 124, 352<br />

SPRMCTH 146<br />

SPRMINT 25<br />

SPRMSTH 146<br />

SPUFI 359, 408<br />

SQL statement 2 MB long 5<br />

SQL statement text 8, 211<br />

SQL statements 2 MB long 5<br />

SQL/XML publishing functions 281, 307<br />

SQLCA 33<br />

SQLCODE 96, 209, 229, 259<br />

SQLDA 343<br />

SQLExtendedFetch 285, 291<br />

SQLJ 150–151, 154, 179, 181, 292, 297–298<br />

Static SQL 181, 297–298, 300<br />

SQLJ applications 293<br />

SQLSTATE 259<br />

SRB time 16<br />

SRTPOOL 144<br />

Stack Storage 141<br />

Stage 1 65–67, 69–71, 115, 195, 304, 400–402, 404, 406<br />

Stage 2 29, 65–67, 69, 115, 400, 403<br />

Star join<br />

in memory workfile 56<br />

Star schema 6, 53–55, 65<br />

Data model 53<br />

STARJOIN 54<br />

START DATABASE 257, 336<br />

START WITH 229, 247<br />

Static scrollable cursors 30, 92–93, 95, 97, 100, 107<br />

STMT 158, 161, 361, 395<br />

STMTTOKEN 414<br />

STOGROUP 227<br />

storage per thread 168<br />

Striping 6, 200<br />

Subject 87, 193<br />

SUBSTRING 24<br />

SUM 109<br />

SYSADM 40, 259, 304<br />

SYSALTER 345<br />

SYSCOLDIST 280, 355<br />

SYSCOLDISTSTATS 355<br />

SYSCOLUMNS 355<br />

SYSCOPY 233, 354–355, 359<br />

SYSCTRL 40<br />

SYSHIGH 193<br />

SYS<strong>IBM</strong>.IPLIST 283, 345<br />

SYS<strong>IBM</strong>.SQLCAMESSAGE 112<br />

SYS<strong>IBM</strong>.SYSCOLDIST 279<br />

SYS<strong>IBM</strong>.SYSCOLUMNS 360<br />

SYS<strong>IBM</strong>.SYSDUMMY1 345<br />

SYS<strong>IBM</strong>.SYSOBDS 345<br />

SYS<strong>IBM</strong>.SYSPACKSTMT 400<br />

438 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

SYS<strong>IBM</strong>.SYSROUTINES 83<br />

SYS<strong>IBM</strong>.SYSSTMT 361<br />

SYS<strong>IBM</strong>.SYSSTRINGS 175, 184–185, 342<br />

SYS<strong>IBM</strong>.SYSTABLES 72–73, 360<br />

SYS<strong>IBM</strong>.SYSTABLESPACE 72–73, 360<br />

SYSIN 264, 276, 347<br />

SYSLGRNX 233, 354, 359<br />

SYSLOW 193<br />

SYSMULTI 193<br />

SYSNONE 193<br />

SYSOBDS 345<br />

SYSPACKSTMT 355, 400<br />

SYSPITR CRCR 220<br />

sysplex workload balancing 299<br />

SYSPLOGD 26<br />

SYSPRINT 263, 347<br />

SYSSTMT 355, 361<br />

SYSTABLEPART<br />

LOGICAL_PART 233<br />

System checkpoints 212, 256, 258<br />

System level point-in-time recovery 4, 219<br />

System-generated DDNAMEs 213<br />

T<br />

Table UDF<br />

Block fetch 84<br />

Table UDF cardinality 6, 86<br />

Table-based partitioning 233<br />

Table-controlled partitioning 246–247<br />

Clustering 246–247<br />

TCB time 16, 333<br />

TCP/IP 25, 27, 112, 281, 283, 292, 295<br />

TCPKPALV 25<br />

TEMP database 211<br />

TEXT 8, 38, 69, 72, 84, 175, 183, 187, 211, 259, 271,<br />

342, 360, 378, 386, 390, 406, 417<br />

Text extender 84<br />

Thanks xxvii<br />

Thread-related storage 12, 129, 144<br />

thread-related storage 167<br />

TIME 218<br />

TIMESTAMP 41–42, 115, 395, 412–413, 415–416<br />

Tivoli OMEGAMON XE <strong>for</strong> <strong>DB2</strong> on z/<strong>OS</strong> 366<br />

Transient data type 308<br />

Transition variables 86<br />

translation instructions 180<br />

Trigger<br />

WHEN condition 30<br />

Trigger body 87<br />

TROO 186<br />

TROT 186<br />

TRTO 186<br />

TRTT 186<br />

TSQTY 228<br />

Two-phase commit 303<br />

Type 1 292, 353<br />

Type 2 7, 179–182, 285, 292–294, 296, 299, 303, 305,<br />

353<br />

Type 3 292, 294, 299<br />

Type 4 179, 181, 187, 285, 293–294, 296–299


U<br />

UA05789 184, 186<br />

UA08703 390<br />

UA11154 390<br />

UA11478 390<br />

UA15188 390<br />

UA15189 313, 390<br />

UA15456 313, 390<br />

UA15677 390<br />

UA22388 390<br />

UA27812 391<br />

UA34634 391<br />

UK00049 381<br />

UK00295 389<br />

UK00296 279, 381<br />

UK00314 382<br />

UK00991 152, 382<br />

UK01174 389<br />

UK01175 382<br />

UK01429 382, 389<br />

UK01467 382<br />

UK01844 382<br />

UK03058 313, 382<br />

UK03176 382<br />

UK03226 389<br />

UK03227 380<br />

UK03490 382<br />

UK03835 313, 381<br />

UK03983 269, 382<br />

UK04036 382<br />

UK04393 382, 389<br />

UK04394 382<br />

UK04683 262, 381<br />

UK04743 382<br />

UK05785 390<br />

UK05786 382<br />

UK06418 382<br />

UK06505 382<br />

UK06754 379, 388<br />

UK06848 39<br />

UK06883 381<br />

UK07167 383<br />

UK07192 383<br />

UK08497 383<br />

UK08561 382<br />

UK08807 230, 382<br />

UK09097 383<br />

UK09343 383<br />

UK10002 383<br />

UK10819 383<br />

UK12124 383<br />

UK12253 383–384<br />

UK12328 383<br />

UK12821 383<br />

UK13636 383<br />

UK13671 384<br />

UK13721 383–384<br />

UK14058 383, 390<br />

UK14283 150, 383<br />

UK14326 384<br />

UK14343 383<br />

UK14370 384<br />

UK14540 384<br />

UK14634 384<br />

UK15036 390<br />

UK15037 384<br />

UK15150 384<br />

UK15285 384<br />

UK15493 384<br />

UK15499 383<br />

UK15650 384, 390<br />

UK15814 383<br />

UK15904 384<br />

UK15958 384<br />

UK16124 379<br />

UK16191 385<br />

UK16616 385<br />

UK17089 385<br />

UK17220 385<br />

UK17312 385<br />

UK17364 384<br />

UK17369 385<br />

UK17805 385<br />

UK18020 385<br />

UK18090 385<br />

UK18201 385<br />

UK18276 385<br />

UK18503 384<br />

UK18547 384<br />

UK19282 385<br />

UK19776 385<br />

UK19777 385<br />

UK20497 382<br />

UK21175 385<br />

UK21950 385<br />

UK22021 385<br />

UK23708 385<br />

UK24197 385<br />

UK25044 385<br />

UK25290 385<br />

UK26761 383<br />

UK27593 386, 390<br />

UK27594 386, 390<br />

UK28485 386<br />

UK9531 382<br />

Unicode xxv, 3, 8, 11, 13, 23, 127, 129, 135, 144, 152,<br />

175–180, 183–187, 205, 261, 304, 306, 342–345,<br />

350–351, 353, 357–358, 369, 414–415<br />

Catalog and directory 11<br />

Collating sequence 23, 183<br />

DBRMs 369<br />

Moving to 184, 351<br />

Precompiler 23<br />

Unicode parser 22<br />

UNION ALL 95, 99<br />

UNIQUE 52, 107, 137, 219, 231–232, 236, 247, 255,<br />

334, 354, 357, 400–401, 403–405<br />

UNIQUE WHERE NOT NULL 231, 248, 405<br />

Universal Client 305<br />

Universal Driver 179, 181, 187, 292, 294–295, 300, 304,<br />

Index 439


306<br />

Universal Driver <strong>for</strong> SQLJ and JDBC 3, 281, 285,<br />

293–294<br />

UNLOAD 133, 371–372<br />

DELIMITED 271–272, 371<br />

Delimited output 376<br />

UNLOAD DELIMITED 270–272<br />

UPDATE NONE 7<br />

UQ57177 212<br />

UQ57178 212, 386<br />

UQ61237 67<br />

UQ61327 386<br />

UQ67433 386<br />

UQ72083 386<br />

UQ74866 338, 386–387<br />

UQ75848 387<br />

UQ77215 387<br />

UQ77421 387<br />

UQ79020 387<br />

UQ79775 386<br />

UQ81754 387<br />

UQ83466 387<br />

UQ84631 387<br />

UQ85042 362<br />

UQ85043 362, 387<br />

UQ85607 285<br />

UQ86458 388<br />

UQ86831 379<br />

UQ86868 388<br />

UQ86872 379<br />

UQ87013 378<br />

UQ87049 305, 379<br />

UQ87093 387<br />

UQ87321 388<br />

UQ87443 378<br />

UQ87591 379<br />

UQ87633 305, 379<br />

UQ87760 379<br />

UQ87903 379<br />

UQ886790 388<br />

UQ88680 379<br />

UQ88734 388<br />

UQ88754 275, 380<br />

UQ88970 388<br />

UQ88971 305, 379<br />

UQ89026 388<br />

UQ89190 389<br />

UQ89194 380<br />

UQ89372 379, 417<br />

UQ89517 229, 380<br />

UQ89850 389<br />

UQ89852 380<br />

UQ90022 381<br />

UQ90143 368, 380<br />

UQ90158 387<br />

UQ90159 378<br />

UQ90464 39, 380–381, 389<br />

UQ90653 388<br />

UQ90654 379<br />

UQ90701 353, 380<br />

440 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

UQ90726 365<br />

UQ90755 210<br />

UQ90756 210, 379<br />

UQ90793 387<br />

UQ90794 378<br />

UQ91022 379<br />

UQ91099 275, 379<br />

UQ91257 307, 380<br />

UQ91416 280, 387<br />

UQ91422 280, 378<br />

UQ91466 381<br />

UQ91470 380<br />

UQ91968 380, 388<br />

UQ92066 388<br />

UQ92067 380<br />

UQ92322 259, 389<br />

UQ92323 380<br />

UQ92475 379, 388<br />

UQ92546 39, 381<br />

UQ92692 39, 379<br />

UQ92698 260, 380<br />

UQ93079 381<br />

UQ93177 275, 380<br />

UQ93207 365<br />

UQ93407 389<br />

UQ93893 389<br />

UQ93972 254, 381<br />

UQ94429 285<br />

UQ94430 285<br />

UQ94797 380<br />

UQ95032 380<br />

UQ95553 381<br />

UQ95694 365<br />

UQ96157 381<br />

UQ96302 381<br />

UQ96531 382<br />

UQ96567 39, 381<br />

UQ96862 213, 381<br />

URL 304, 363, 371<br />

URL syntax 293<br />

USER 371<br />

User-defined functions 89, 307<br />

User-defined objects 199<br />

USING VCAT 199<br />

UTF-16 175, 177, 179–180, 182, 185–187, 343–344<br />

UTF-8 22, 175, 179, 181–182, 184–187, 343–344<br />

Utility<br />

RESTART 21, 220, 262, 367<br />

SORTDATA 268<br />

SORTKEYS 268<br />

V<br />

VALUES 6–7, 24–25, 32, 42, 44, 68, 73–74, 93, 172,<br />

195, 198, 217, 220, 226, 228–229, 233, 257, 273–275,<br />

304, 308, 322, 345, 352, 405–406, 410, 412, 414–416<br />

VARCHAR<br />

NOT PADDED 11, 14, 232, 237, 345, 401<br />

VARGRAPHIC 68–69, 183, 231<br />

VARIABLE 371<br />

Variable pools 141


VDWQT 25, 345<br />

VE 117, 124<br />

VERSION 412<br />

<strong>Version</strong>ing 369<br />

Virtual storage constraint 9, 12, 17, 19, 127, 129,<br />

139–140, 145, 156, 213<br />

Visual Explain 72–73, 77, 110, 112, 114–115, 123–125,<br />

259<br />

Access plan 111<br />

Maintain 111<br />

Tune SQL 111, 123<br />

VOLATILE 8<br />

Volatile table 217, 246<br />

volatile tables 7, 246, 369<br />

Volume-level backups 218<br />

VPSIZE 142<br />

VSAM<br />

Striping 201–202<br />

VSAM CI size 199–201<br />

W<br />

WARM 321–322<br />

WebSphere 26, 172, 174, 281–282, 294, 297–299, 304,<br />

316<br />

WebSphere Application Server 295, 303, 314<br />

WLM 26, 117, 209, 308, 312, 350<br />

WLM enclave 209<br />

WLM priority 258<br />

workfile 30, 56, 58–59, 65, 70, 77, 84, 86, 90, 115, 211,<br />

255, 268<br />

Write And Register Multiple 321<br />

WRITE CLAIM 264, 337<br />

Write down 191, 194<br />

write-down 194, 197–198<br />

Write-down control 196<br />

Write-down privilege 196–197<br />

X<br />

XA 303<br />

XES 319, 325–327, 329, 331<br />

XES contention 173, 325, 328–330, 332<br />

XML 111, 281, 307–309<br />

Built-in functions 281, 308<br />

XML composition 311<br />

XML data type 308–309<br />

XML documents 307, 311–312<br />

XML extender 281, 307–309, 311–312<br />

XML file 111<br />

XML publishing functions 281, 307–309, 311–312<br />

XML2CLOB 309–310<br />

XMLAGG 309–310<br />

XMLATTRIBUTES 309–310<br />

XMLCONCAT 309–310<br />

XMLELEMENT 309–310<br />

XMLFOREST 309–310<br />

XMLNAMESPACES 309<br />

Z<br />

z/Architecture 13, 139, 153, 157, 171<br />

z/<strong>OS</strong> APARs 390<br />

z800 27<br />

z900 27, 129, 188, 284<br />

z990 26–27, 129, 185, 187–188, 190, 308<br />

zSeries xxv, 2, 9, 13, 27, 97, 174, 178, 180, 183–186,<br />

189, 213, 221, 233, 248, 309, 342, 344<br />

Index 441


442 <strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong>


<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8 Per<strong>for</strong>mance <strong>Topics</strong><br />

(1.0” spine)<br />

0.875”1.498”<br />

460 788 pages<br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong>


<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong><br />

<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong>


<strong>DB2</strong> <strong>UDB</strong> <strong>for</strong> z/<strong>OS</strong><br />

<strong>Version</strong> 8<br />

Per<strong>for</strong>mance <strong>Topics</strong><br />

Evaluate the<br />

per<strong>for</strong>mance impact<br />

of major new<br />

functions<br />

Find out the<br />

compatibility mode<br />

per<strong>for</strong>mance<br />

implications<br />

Understand<br />

per<strong>for</strong>mance and<br />

availability functions<br />

Back cover<br />

<strong>IBM</strong> DATABASE 2 Universal Database Server <strong>for</strong> z/<strong>OS</strong> <strong>Version</strong> 8<br />

(<strong>DB2</strong> V8 or V8 throughout this book) is the twelfth and largest<br />

release of <strong>DB2</strong> <strong>for</strong> MVS. It brings synergy with the zSeries<br />

hardware and exploits the z/<strong>OS</strong> 64-bit virtual addressing<br />

capabilities. <strong>DB2</strong> V8 offers data support, application<br />

development, and query functionality enhancements <strong>for</strong><br />

e-business, while building upon the traditional characteristics of<br />

availability, exceptional scalability, and per<strong>for</strong>mance <strong>for</strong> the<br />

enterprise of choice.<br />

Key improvements enhance scalability, application porting,<br />

security architecture, and continuous availability. Management<br />

<strong>for</strong> very large databases is made much easier, while 64-bit virtual<br />

storage support makes management simpler and improves<br />

scalability and availability. This new version breaks through many<br />

old limitations in the definition of <strong>DB2</strong> objects, including SQL<br />

improvements, schema evolution, longer names <strong>for</strong> tables and<br />

columns, longer SQL statements, enhanced Java and Unicode<br />

support, enhanced utilities, and more log data sets.<br />

This book introduces the major per<strong>for</strong>mance and availability<br />

changes as well as the per<strong>for</strong>mance characteristics of many new<br />

functions. It helps you understand the per<strong>for</strong>mance implications<br />

of migrating to <strong>DB2</strong> V8 with considerations based on laboratory<br />

measurements. It provides the type of in<strong>for</strong>mation needed to start<br />

evaluating the per<strong>for</strong>mance impact of <strong>DB2</strong> V8 and its capacity<br />

planning needs.<br />

SG24-6465-00 ISBN 0738492493<br />

INTERNATIONAL<br />

TECHNICAL<br />

SUPPORT<br />

ORGANIZATION<br />

®<br />

BUILDING TECHNICAL<br />

INFORMATION BASED ON<br />

PRACTICAL EXPERIENCE<br />

<strong>IBM</strong> <strong>Redbooks</strong> are developed<br />

by the <strong>IBM</strong> International<br />

Technical Support<br />

Organization. Experts from<br />

<strong>IBM</strong>, Customers and Partners<br />

from around the world create<br />

timely technical in<strong>for</strong>mation<br />

based on realistic scenarios.<br />

Specific recommendations<br />

are provided to help you<br />

implement IT solutions more<br />

effectively in your<br />

environment.<br />

For more in<strong>for</strong>mation:<br />

ibm.com/redbooks

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!