Depends dramatically on what kind of code you are using. If your application is running extensive SQL or queries, you clearly need to be looking at database and SQL tuning first. Not having proper indexes or logical files on your system for the running of efficient SQL requests is a top issue.
The single biggest performance issue encountered within long running batch jobs would be what we call "excessive initiation and termination". If you have a job that runs 500,000 SQL requests (1 for each record read), it will not perform as well as 1 request that reads 500,000 records in a single initiation and termination of SQL.
Batch processing that submits a separate job for each transaction, initiating and terminating jobs excessively, is not going to perform as well as a single job doing the same work. A single job will not function at its highest efficiency if it is opening and closing files for every transaction that is processed. This same job could be calling external programs for each transaction. If these programs are not "returning control" properly, they could be a big issue.
Any excessive initiation and termination is usually unnecessary and contributes dramatically to a jobs duration. There is significant overhead associated with the starting and stopping of a single SQL request. Minimizing the number of requests can reduce your job's duration. Opening files once at the beginning of a job and closing them once at the end will improve that job's performance. Any external calls that can be reduced or eliminated with inline subroutines can be a great help. You don't want the operating system loading a program
in and out of memory 60,000 times per minute.
It is not uncommon to see a single external program call make a batch job run for 3 hours. This program could be as simple as a stand alone "Date Conversion Routine". All it does is flip around the format of dates from MM/DD/YY to YY/MM/DD. If this RPG program does a SETON *INLR operation, we have found a culprit. Simply changing this to a RETRN operation would tell the operating system to leave the program in memory each time it is called. This 3 hour batch job could now finish in less than 10 minutes.
This might seem like an extreme example or exaggeration, it is not. We see this all the time. It will depend though on the specific job and the amount of duration that is affected by these examples. You must use the IBM commands TRCJOB or STRTRC to gather the necessary data for this type of analysis. Our Application Optimizer "trace" features can help automate this data collection and presentation process.