There are three main reasons for this. Variables are moved, not just from the input record to the output record, but from input, to an intermediate work area, and then to the output record. When an external subprogram is called, this technique has the programmer move all of the parameters to one parameter block. All of these record structures result in a lot of moves and very many variables. A second reason for large data divisions is the use of copy statements for record structures.
Reusable code is a good thing.
The unfortunate side effect of this code reuse is that a large number of the variables in a record structure that is copied into several programs are not used by some of those programs. Put another way, a program that has copy statements for six or eight record structures may reference less than half of the variables generated by them. The procedure division is usually nicely modularized. Programmers who have been exposed to block structured languages will probably see the problem quickly. For many problems, debugging involves tracing one variable through a program to see how it gets changed and why.