Previous Page | Next Page

Programming with the SQL Procedure

Improving Query Performance

There are several ways to improve query performance, including the following:


Using Indexes to Improve Performance

Indexes are created with the CREATE INDEX statement in PROC SQL or with the MODIFY and INDEX CREATE statements in the DATASETS procedure. Indexes are stored in specialized members of a SAS library and have a SAS member type of INDEX. The values that are stored in an index are automatically updated if you make a change to the underlying data.

Indexes can improve the performance of certain classes of retrievals. For example, if an indexed column is compared to a constant value in a WHERE expression, then the index will likely improve the query's performance. Indexing the column that is specified in a correlated reference to an outer table also improves a subquery's (and hence, query's) performance. Composite indexes can improve the performance of queries that compare the columns that are named in the composite index with constant values that are linked using the AND operator. For example, if you have a compound index in the columns CITY and STATE, and the WHERE expression is specified as WHERE CITY='xxx' AND STATE='yy', then the index can be used to select that subset of rows more efficiently. Indexes can also benefit queries that have a WHERE clause in this form:

... where var1 in (select item1 from table1) ...

The values of VAR1 from the outer query are found in the inner query by using the index. An index can improve the processing of a table join, if the columns that participate in the join are indexed in one of the tables. This optimization can be done for equijoin queries only--that is, when the WHERE expression specifies that table1.X=table2.Y.


Using the Keyword ALL in Set Operations

Set operators such as UNION, OUTER UNION, EXCEPT, and INTERSECT can be used to combine queries. Specifying the optional ALL keyword prevents the final process that eliminates duplicate rows from the result table. You should use the ALL form when you know that there are no duplicate rows or when it does not matter whether the duplicate rows remain in the result table.


Omitting the ORDER BY Clause When Creating Tables and Views

If you specify the ORDER BY clause when a table or view is created, then the data is always displayed in that order unless you specify another ORDER BY clause in a query that references that table or view. As with any sorting procedure, using ORDER BY when retrieving data has certain performance costs, especially on large tables. If the order of your output is not important for your results, then your queries will typically run faster without an ORDER BY clause.


Using In-Line Views versus Temporary Tables

It is often helpful when you are exploring a problem to break a query down into several steps and create temporary tables to hold the intermediate results. After you have worked through the problem, combining the queries into one query by using in-line views can be more efficient. However, under certain circumstances it is more efficient to use temporary tables. You should try both methods to determine which is more efficient for your case.


Comparing Subqueries with Joins

Many subqueries can also be expressed as joins. Generally, a join is processed at least as efficiently as the subquery. PROC SQL stores the result values for each unique set of correlation columns temporarily, thereby eliminating the need to calculate the subquery more than once.


Using WHERE Expressions with Joins

When joining tables, you should specify a WHERE expression. Joins without WHERE expressions are often time-consuming to evaluate because of the multiplier effect of the Cartesian product. For example, joining two tables of 1,000 rows each without specifying a WHERE expression or an ON clause, produces a result table with one million rows.

PROC SQL executes and obtains the correct results in unbalanced WHERE expressions (or ON join expressions) in an equijoin, as shown here, but handles them inefficiently:

where table1.columnA-table2.columnB=0

It is more efficient to rewrite this clause to balance the expression so that columns from each table are on alternate sides of the equals condition:

where table1.columnA=table2.columnB

PROC SQL sequentially processes joins that do not have an equijoin condition evaluating each row against the WHERE expression: that is, joins without an equijoin condition are not evaluated using sort-merge or index-lookup techniques. Evaluating left and right outer joins is generally comparable to, or only slightly slower than, a standard inner join. A full outer join usually requires two passes over both tables in the join, although PROC SQL tries to store as much data as possible in buffers. Thus for small tables, an outer join might be processed with only one physical read of the data.


Optimizing the PUT Function


Reducing the PUT Function

There are several ways you can improve the performance of queries for formatted data by optimizing the PUT functions. If you reference tables in a database, eliminating references to PUT functions can enable more of the query to be passed down to the database. It can also simplify WHERE clause evaluation for the default Base SAS engine.

For more information, see the REDUCEPUT=, REDUCEPUTOBS=, and REDUCEPUTVALUES= options in the Base SAS Procedures Guide, and the SQLREDUCEPUT= , SQLREDUCEPUTOBS=, and SQLREDUCEPUTVALUES= system options in SAS Language Reference: Dictionary.

Note:   PROC SQL can consider both the REDUCEPUTOBS= and the REDUCEPUTVALUES= options (or SQLREDUCEPUTOBS= and SQLREDUCEPUTVALUES= system options) when trying to determine whether to optimize the PUT function.  [cautionend]


Deploying the PUT Function and SAS Formats inside Teradata

In SAS 9.2 Phase 2 and later, if you use SAS/ACCESS for Teradata, you can use %INDTD_PUBLISH_FORMATS macro to deploy, or publish, the PUT function implementation to Teradata as a function named SAS_PUT(). As with any other programming function, the SAS_PUT() function can take one or more input parameters and return an output value. After the SAS_PUT() function is deployed in Teradata and the SQLMAPPUTTO system option is set to SAS_PUT, you can use the SAS_PUT() function as you would use any standard SQL function inside the database.

In addition, the SAS_PUT() function supports the use of SAS formats in SQL queries that are submitted to Teradata. You also use the %INDTD_PUBLISH_FORMATS macro to publish both the formats that are supplied by SAS and the custom formats that you create with the FORMAT procedure to Teradata.

By publishing the PUT function implementation to Teradata as the SAS_PUT() function to support the use of SAS formats, and by packaging both the formats that are supplied by SAS and the custom formats that are defined using the FORMAT procedure, the following advantages are realized:

Note:   Using both the SQLREDUCEPUT system option (or the PROC SQL REDUCEPUT= option) and the SAS_PUT() function can result in a significant performance boost.  [cautionend]

For more information about using the %INDTD_PUBLISH_FORMATS macro and the SQLMAPPUTTO system option, see SAS/ACCESS for Relational Databases: Reference.


Replacing References to the DATE, TIME, DATETIME, and TODAY Functions

When the PROC SQL CONSTDATETIME option or the SQLCONSTDATETIME system option is set, PROC SQL evaluates the DATE, TIME, DATETIME, and TODAY functions in a query once, and uses those values throughout the query. Computing these values once ensures consistent results when the functions are used multiple times in a query, or when the query executes the functions close to a date or time boundary. When referencing database tables, performance is enhanced because it allows more of the query to be passed down to the database.

For more information, see the CONSTDATETIME option in the Base SAS Procedures Guide or the SQLCONSTDATETIME system option in SAS Language Reference: Dictionary.

Note:   If you specify both the PROC SQL REDUCEPUT option or the SQLREDUCEPUT system option and the PROC SQL CONSTDATETIME option or the SQLCONSTDATETIME system option, PROC SQL replaces the DATE, TIME, DATETIME, and TODAY functions with their respective values in order to determine the PUT function value before the query executes.  [cautionend]


Disabling the Remerging of Data When Using Summary Functions

When you use a summary function in a SELECT clause or a HAVING clause, PROC SQL might remerge the data. Remerging the data involves two passes through the data. If you set the PROC SQL NOREMERGE option or the NOSQLREMERGE system option, PROC SQL will not process the remerging of data. When referencing database tables, performance is enhanced because it enables more of the query to be passed down to the database.

For more information, see the PROC SQL statement REMERGE option in the Base SAS Procedures Guide and the SQLREMERGE system option in SAS Language Reference: Dictionary.

Previous Page | Next Page | Top of Page