I/O is one of the most important factors for optimizing performance. Most SAS jobs consist of repeated cycles of reading a particular set of data to perform various data analysis and data manipulation tasks . To improve the performance of a SAS job, you must reduce the number of times SAS accesses disk or tape devices.
To do this, you can modify your SAS programs to process only the necessary variables and observations by:
using WHERE processing
using DROP and KEEP statements
using LENGTH statements
using the OBS= and FIRSTOBS= data set options.
You can also modify your programs to reduce the number of times it processes the data internally by:
creating SAS data sets
using indexes
accessing data through views
using engines efficiently .
You can reduce the number of data accesses by processing more data each time a device is accessed by
setting the BUFNO=, BUFSIZE=, CATCACHE=, and COMPRESS= system options
using the SASFILE global statement to open a SAS data set and allocate enough buffers to hold the entire data set in memory.
Note | Sometimes you may be able to use more than one method, making your SAS job even more efficient. |
You might be able to use a WHERE statement in a procedure in order to perform the same task as a DATA step with a subsetting IF statement. The WHERE statement can eliminate extra DATA step processing when performing certain analyses because unneeded observations are not processed .
For example, the following DATA step creates a data set SEATBELT, which contains only those observations from the AUTO.SURVEY data set for which the value of SEATBELT is YES. The new data set is then printed.
libname auto '/users/autodata'; data seatbelt; set auto.survey; if seatbelt='yes'; run; proc print data=seatbelt; run;
However, you can get the same output from the PROC PRINT step without creating a data set if you use a WHERE statement in the PRINT procedure, as in the following example:
proc print data=auto.survey; where seatbelt='yes'; run;
The WHERE statement can save resources by eliminating the number of times you process the data. In this example, you might be able to use less time and memory by eliminating the DATA step. Also, you use less I/O because there is no intermediate data set. Note that you cannot use a WHERE statement in a DATA step that reads raw data.
The extent of savings that you can achieve depends on many factors, including the size of the data set. It is recommended that you test your programs to determine which is the most efficient solution. See "Deciding Whether to Use a WHERE Expression or a Subsetting IF Statement" on page 211 for more information.
Another way to improve efficiency is to use DROP and KEEP statements to reduce the size of your observations. When you create a temporary data set and include only the variables that you need, you can reduce the number of I/O operations that are required to process the data. See SAS Language Reference: Dictionary for more information on the DROP and KEEP statements.
You can also use LENGTH statements to reduce the size of your observations. When you include only the necessary storage space for each variable, you can reduce the number of I/O operations that are required to process the data. Before you change the length of a numeric variable, however, see "Specifying Variable Lengths" on page 221. See SAS Language Reference: Dictionary for more information on the LENGTH statement.
You can also use the OBS= and FIRSTOBS= data set options to reduce the number of observations processed. When you create a temporary data set and include only the necessary observations, you can reduce the number of I/O operations that are required to process the data. See SAS Language Reference: Dictionary for more information on the OBS= and FIRSTOBS= data set options.
If you process the same raw data repeatedly, it is usually more efficient to create a SAS data set. SAS can process SAS data sets more efficiently than it can process raw data files.
Another consideration involves whether you are using data sets created with previous releases of SAS. If you frequently process data sets created with previous releases, it is sometimes more efficient to convert that data set to a new one by creating it in the most recent version of SAS. See Chapter 35, "SAS 9.1 Compatibility with SAS Files From Earlier Releases," on page 587 for more information.
An index is an optional file that you can create for a SAS data file to provide direct access to specific observations. The index stores values in ascending value order for a specific variable or variables and includes information as to the location of those values within observations in the data file. In other words, an index allows you to locate an observation by the value of the indexed variable.
Without an index, SAS accesses observations sequentially in the order in which they are stored in the data file. With an index, SAS accesses the observation directly. Therefore, by creating and using an index, you can access an observation faster.
In general, SAS can use an index to improve performance in these situations:
For WHERE processing, an index can provide faster and more efficient access to a subset of data.
For BY processing, an index returns observations in the index order, which is in ascending value order, without using the SORT procedure.
For the SET and MODIFY statements, the KEY= option allows you to specify an index in a DATA step to retrieve particular observations in a data file.
Note | An index exists to improve performance. However, an index conserves some resources at the expense of others. Therefore, you must consider costs associated with creating, using, and maintaining an index. See "Understanding SAS Indexes" on page 518 for more information about indexes and deciding whether to create one. |
You can use the SQL procedure or a DATA step to create views of your data. A view is a stored set of instructions that subsets your data with fewer statements. Also, you can use a view to group data from several data sets without creating a new one, saving both processing time and disk space. See Chapter 29, "SAS Data Views," on page 541 and the Base SAS Procedures Guide for more details.
If you do not specify an engine on a LIBNAME statement, SAS must perform extra processing steps in order to determine which engine to associate with the data library. SAS must look at all of the files in the directory until it has enough information to determine which engine to use. For example, the following statement is efficient because it explicitly tells SAS to use a specific engine for the libref FRUITS:
/* Engine specified. */ libname fruits v9 '/users/myid/mydir';
The following statement does not explicitly specify an engine. In the output, notice the NOTE about mixed engine types that is generated:
/* Engine not specified. */ libname fruits '/users/myid/mydir';
NOTE: Directory for library FRUITS contains files of mixed engine types. NOTE: Libref FRUITS was successfully assigned as follows: Engine: V9 Physical Name: /users/myid/mydir
Operating Environment Information: In the z/OS operating environment, you do not need to specify an engine for certain types of libraries.
See Chapter 37, "SAS Engines," on page 601 for more information about SAS engines.
The following SAS system options can help you reduce the number of disk accesses that are needed for SAS files, though they might increase memory usage.
BUFNO=
SAS uses the BUFNO= option to adjust the number of open page buffers when it processes a SAS data set. Increasing this option's value can improve your application's performance by allowing SAS to read more data with fewer passes ; however, your memory usage increases . Experiment with different values for this option to determine the optimal value for your needs.
Note | You can also use the CBUFNO= system option to control the number of extra page buffers to allocate for each open SAS catalog. |
See system options in SAS Language Reference: Dictionary and the SAS documentation for your operating environment for more details on this option.
BUFSIZE=
When the Base SAS engine creates a data set, it uses the BUFSIZE= option to set the permanent page size for the data set. The page size is the amount of data that can be transferred for an I/O operation to one buffer. The default value for BUFSIZE= is determined by your operating environment. Note that the default is set to optimize the sequential access method. To improve performance for direct (random) access, you should change the value for BUFSIZE=.
Whether you use your operating environment's default value or specify a value, the engine always writes complete pages regardless of how full or empty those pages are.
If you know that the total amount of data is going to be small, you can set a small page size with the BUFSIZE= option, so that the total data set size remains small and you minimize the amount of wasted space on a page. In contrast, if you know that you are going to have many observations in a data set, you should optimize BUFSIZE= so that as little overhead as possible is needed. Note that each page requires some additional overhead.
Large data sets that are accessed sequentially benefit from larger page sizes because sequential access reduces the number of system calls that are required to read the data set. Note that because observations cannot span pages, typically there is unused space on a page.
"Calculating Data Set Size" on page 221 discusses how to estimate data set size. See system options in SAS Language Reference: Dictionary and the SAS documentation for your operating environment for more details on this option.
CATCACHE=
SAS uses this option to determine the number of SAS catalogs to keep open at one time. Increasing its value can use more memory, although this may be warranted if your application uses catalogs that will be needed relatively soon by other applications. (The catalogs closed by the first application are cached and can be accessed more efficiently by subsequent applications.)
See system options in SAS Language Reference: Dictionary and the SAS documentation for your operating environment for more details on this option.
COMPRESS=
One further technique that can reduce I/O processing is to store your data as compressed data sets by using the COMPRESS= data set option. However, storing your data this way means that more CPU time is needed to decompress the observations as they are made available to SAS. But if your concern is I/O, and not CPU usage, compressing your data may improve the I/O performance of your application.
See SAS Language Reference: Dictionary for more details on this option.
The SASFILE global statement opens a SAS data set and allocates enough buffers to hold the entire data set in memory. Once it is read, data is held in memory, available to subsequent DATA and PROC steps, until either a second SASFILE statement closes the file and frees the buffers or the program ends, which automatically closes the file and frees the buffers.
Using the SASFILE statement can improve performance by
reducing multiple open/close operations (including allocation and freeing of memory for buffers) to process a SAS data set to one open/close operation
reducing I/O processing by holding the data in memory.
If your SAS program consists of steps that read a SAS data set multiple times and you have an adequate amount of memory so that the entire file can be held in real memory, the program should benefit from using the SASFILE statement. Also, SASFILE is especially useful as part of a program that starts a SAS server such as a SAS/SHARE server. See SAS Language Reference: Dictionary for more information on the SASFILE global statement.