Professional Documents
Culture Documents
Performance Tuning Mainframe Apps Compuware
Performance Tuning Mainframe Apps Compuware
Performance Tuning Mainframe Apps Compuware
Mainframe
Applications
“It’s Not So Hard”
Tony Shediak
Ampdev Pty Ltd
Tony.Shediak@ampdev.com
vs Subscripts
The Usual Suspects
• Inefficient use of the programming language data types
• Data conversions caused by mixing data types unnecessarily
• Inefficient compiler options
• Inefficient initialisation of large structures/groups
• Over-Use of built-in functions or program language constructs
that generate subroutine calls
• Inadequate VSAM buffering for the required function
• Long-running jobs processing several large databases randomly
in a single step
• Inefficient Date/Time processing
• Using SQL to process tables like files, record by record
• Using overly complex or inefficient SQL
• Over-qualifying IMS DL/I calls
• Inefficient file block size for the device
• PL/I Onkey condition – this is very expensive since Language
Environment because the condition handling architecture
employed by LE. A Cobol “key not found” condition is about 7
times faster than a PL/I one.
• Re-reading small files/databases/reference data over and over
rather than loading into program storage. Don’t be afraid to use
storage – Ent COBOL 3.4+ has extended WS limit to 134MB.
• Not using the most optimal utility for the job, e.g. SORT COPY
vs REPRO.
Programming Efficiently
• Understanding Data Types
• Binary – integers, loop control, subscripts etc - fast.
• Packed Decimal – fractions, money
• Floating point – large range of numbers
• Subscripting Tables/Arrays - If a subscript is not binary then it
will be converted to binary whether you like it or not.
• COBOL Indexes – optimised sequential array processing. But
how many programmers actually understand this ?
• Use optimal compiler options as much as possible
• Utilise the “LIST” compile option and browse the assembler
• Avoid heavy INITIALIZE as it does it one element at a time
Compile with “LIST”
• Utilise the “LIST” compile option and browse the assembler and
*
* Change ALL ‘*’ to SPACE and leave everything else as is
*
INSPECT AAA CONVERTING ‘*’ TO SPACE. This code is 90% more efficient
than ‘Do it Yourself’
*
* Do it yourself
*
PERFORM VARYING I FROM 1 BY 1 UNTIL I > LENGTH OF AAA
IF AAA(I : 1) = ‘*’
MOVE SPACE TO AAA(I : 1)
END-IF
END-PERFORM.
VSAM Buffering
• NSR - Good for Sequential access
• Read ahead
• One set of buffers per file
• LSR – Good for Random access
• No read ahead
• Buffers can be shared by several files
• SMB – System Managed Buffering Good Redbook –
• Enabled by SMS Dataclas “Vsam Demystified”
Performance
problems identified: Using PIC 999 display data for arithmetic operations and array subscripts.
Compiled with SSRANGE and TRUNC(BIN) - Pre COBOL V2.2
Tuning applied: Change all display data to BINARY, as all are integer.
Compile with NOSSRANGE and TRUNC(OPT)
Performance
improvement: 70% CPU reduction
Example 2 – Lots of Logical I/O
Description: Program performing account range validation via a VSAM(IAM) ksds by
checking the range on each record against all subsequent records
Language: PL/I
Performance
problems identified: Program issuing over 300M logical I/O’s even though file contains
30,000 records only
Tuning applied: load file into an array allocated above the 16M line to eliminate further I/O’s.
re-work checking algorithm to eliminate multiple passes through each entry
Performance
improvement: 99.97% CPU reduction. Cpu secs dropped from 2000 to 0.5
Example 3 – High Hit Static Reference Data
Description: Expensive CICS Tran used to create web drop-down list
Language: COBOL
Performance
problems identified: DB2 Table containing relatively static reference data has a very high hit rate
Performance
improvement: 99% CPU reduction.
Example 4 – Record Oriented SQL
Description: DB2 Program performing rate reporting
Language: PL/I
Performance
problems identified: SQL used in a record-oriented approach e.g.
Open Cursor A
For every A row
Open Cursor B
For every B row
Open Cursor C
…etc
End
Close Cursor B
End
Close Cursor A
How identified: STROBE report and eyeballing the source
Tuning applied: Rewrite SQL to utilise table JOINS (specifically Left outer join in this case)
and create and process a single cursor, so DB2 does the work once
Effort required: 2 days
Performance
improvement: Elapsed time dropped from 12 hours to 3 mins
Example 5 – VSAM Buffering and SMB
Description: Program performing specialised data extract across VSAM files
Language: COBOL
Performance
problems identified: using default buffering (2 data and 1 index).
using NSR but most of the processing is random
Performance
improvement: 86% CPU reduction. 95% Elapsed time reduction
Example 6 – Compiler Generated Subroutine Calls
Description: Subroutine performing name and address compression into a
cross-reference key
Language: COBOL
Performance
problems identified: using complex INSPECT, STRING extensively
Tuning applied: Total rewrite of code eliminating ALL STRING and INSPECT functions
and replacing them with simple iterative search loops and sub-string
manipulations
Performance
improvement: 75% CPU reduction
Example 7 – Data Conversions
Description: Program performing specialised data extract
Language: PL/I
Performance
problems identified: many compiler generated subroutine calls due to manipulation
of UNALIGNED bit strings in a STRUCTURE and various data
conversions caused by mixing data types
Tuning applied: Changed all unaligned bit strings within STRUCTURES to aligned.
Eliminated all other data conversions requiring subroutine calls.
70 compiler generated subroutine calls were eliminated from the object
code
Effort required: 1 day
Performance
improvement: 65% CPU reduction
Example 8 – Bad SQL - 1
Description: DB2 Program performing Online Query
Language: COBOL
Performance
problems identified: SQL NOT utilising Table Index in Join because of mis-matching data types
hence causing Tablespace Scan:
SELECT P.PROD_CD
.
.
FROM (SELECT A.PARAMETER_NUM_WHLE
AS PROD_CD
. DEC(15)
.
) AS P
INNER JOIN P.SD700T00 AS S DEC(4)
ON S.SD700_PRODUCT_CODE = P.PROD_CD
SELECT P.PROD_CD
.
.
FROM (SELECT CAST(A.PARAMETER_NUM_WHLE AS DECIMAL(4))
AS PROD_CD
.
.
) AS P
INNER JOIN P.SD700T00 AS S
ON S.SD700_PRODUCT_CODE = P.PROD_CD
Performance
improvement: 50% CPU reduction
Example 9 – Bad SQL - 1
Description: DB2 Program performing Batch Query
Language: COBOL
Performance
problems identified: SQL performing entire Index Scan and minor sort unnecessarily:
Tuning applied: Understand the data and hence eliminate Index Scan by searching for only valid
combinations:
ASTER-LM135-RACFID = ‘*’ || LM135-RACFID
SELECT 1
FROM LM135T00
WHERE LM135_RACFID IN (:LM135-RACFID,
:ASTER-LM135-RACFID)
FETCH FIRST 1 ROW ONLY
Performance
improvement: 98% CPU reduction
Example 10 – Initialising a Large Table
Language: COBOL
Performance
problems identified: High volume initialisation of large table
Tuning applied: Removed initialisation as it was not really required, the program was already
keeping track of the number of elements via a counter anyway
Performance
improvement: 30% CPU reduction
The AAPT Story – From 650 to 400
MIPS in 15 Months
• 35 initiatives implemented
• Mostly Bad SQL or COBOL or both. Lots of code changed
• Some quick wins – Package REBINDs, Modifying or
adding Index, using IEBGENER (SORT COPY) instead of
REPRO, Changing Job schedules to run less often, and
Web front-end bug initiating CICS Tran too many times
• CICS Threadsafe implemented with 15% CPU savings
across Region. Programs targeted by heavy SQL execution.
• Upgraded DASD sub-system significantly helped I/O and
gave more room to reduce MIPS
• Test Smart vs Test Hard, e.g. if only SQL was changed
then only SQL was tested
•
Make Performance Part of the Culture
• Training, training and more training (can be internal)
• Establish mentoring programs
• Implement Practice leadership for your key technical areas,