source: http://support.microsoft.com/kb/209126
Article ID | : | 209126 |
Last Review | : | November 28, 2007 |
Revision | : | 2.4 |
• | Query Optimizer for the Microsoft Jet database engine |
• | Query timing |
• | Analyzing performance |
• | Tips to improve query performance |
• | The number of records in a table |
• | The number of data pages in a table |
• | The location of the table |
• | Whether indexes are present |
• | How unique the indexes are |
• | Time to display the first screen of data |
• | Time to obtain the last record |
• | Complete the query, and then display data |
• | Display data, and then complete the query |
• | Compact your database When you compact your database you can speed up queries. When you compact your database, the records of the table are reorganized so that the records reside in adjacent database pages that are ordered by the primary key of the table. This improves the performance of the sequential scans of records in the table because only the minimum number of database pages now have to be read to retrieve the records that you want. After you compact your database, run each query to compile the query so that each query will now have the updated table statistics. |
• | Index a field Index any field that is used to set criteria for the query fields and the index fields on both sides of a join. Or, create a relationship between these fields. When you create a relationship with enforced referential integrity, the Jet database engine creates an index on the foreign key if one does not already exist. Otherwise, the Jet database engine uses the existing index. Note The Jet database engine automatically optimizes a query that joins an Access table on your hard disk and an ODBC server table if the Access table is small and if the joined fields are indexed. In this case, Access improves performance by requesting only the required records from the server. Make sure that tables you join from different sources are indexed on the join fields. |
• | Select the smallest data type that is appropriate When you define a field in a table, select the smallest data type that is appropriate for the data in the field. Also, make sure that fields that you plan to use in joins have the same data types or compatible data types, such as Autonumber and Number (if the FieldSize property is set to Long Integer). |
• | Add only the fields that you must have When you create a query, add only the fields that you must have. In fields that are used to set criteria, click to clear the Show check box if you do not want to display those fields. |
• | Save the SQL statement as a query If the RecordSource property for a form or for report is set to an SQL statement, save the SQL statement as a query and then set the RecordSource property to the name of the query. |
• | Avoid calculated fields Avoid calculated fields in subqueries. If you add a query that contains a calculated field to another query, the expression in the calculated field may slow performance in the top-level query. In the following example, query Q1 is used as the input for query Q2:
Q1: SELECT IIF([MyColumn]="Yes","Order Confirmed","Order Not Confirmed") AS X FROM MyTable;
Because the IIF expression in Q1 cannot be optimized, Q2 also cannot be optimized. If an expression that cannot be optimized is nested in a subquery, all the query cannot be optimized. Q2: SELECT * FROM Q1 WHERE X="Order Confirmed"; An alternative way to construct the query is as follows:
Q1: SELECT * FROM MyTable WHERE MyColumn = "Yes";
If expressions are required in the output, try to put the expressions in a control on a form or on report. For example, you can change the previous query to a parameter query that prompts for the value of MyColumn, and then base a form or a report on the query. On the form or on the report, you can then add a calculated control that displays "Hello" or "Goodbye," depending on the value that is in MyColumn. Construct the query as follows:
PARAMETERS [To see confirmed orders, enter Yes. To see unconfirmed orders, enter No.] Text;
In the calculated control on the form or on report, type:
SELECT * FROM MyTable WHERE MyColumn = [To see confirmed orders, enter Yes. To see unconfirmed orders, enter No.];
=IIF([MyColumn]="Yes","Order Confirmed","Order Not Confirmed")
|
• | Specify Group By When you group records by the values in a joined field, specify Group By for the field that is in the same table as the field that you are totaling (calculating an aggregate on). For example, in the Northwind.mdb sample database, if you create a query that totals the Quantity field in the Order Details table and then groups by OrderID, you can specify Group By for the OrderID field in the Order Details table. If you specify Group By for the OrderID field in the Orders table, Access must join all the records first and then perform the aggregate, instead of performing the aggregate and then joining only the required fields. For greater speed, use Group By on as few fields as possible. Alternatively, use the First function if you can. If a totals query includes a join, consider grouping the records in one query and then adding this query to a separate query that performs the join. When you do this, performance may be improved with some queries. |
• | Avoid restrictive query criteria Avoid restrictive query criteria on calculated fields and on non-indexed fields if you can. Use criteria expressions that you can optimize. |
• | Test your query performance in a field that is used in a join between tables If you use criteria to restrict the values in a field that is used in a join between tables with a one-to-many relationship, test whether the query runs faster with the criteria placed on the "one" side or on the "many" side of the join. In some queries, you may realize faster performance by adding the criteria to the field on the "one" side of the join instead of on the "many" side of the join. |
• | Index sort fields Index the fields that you use for sorting. |
• | Use make-table queries to create tables If your data seldom changes, use make-table queries to create tables from your query results. Use the resulting tables instead of queries as the basis for your forms, your reports, or your other queries. Make sure that you add indexes according to the guidelines that you read in this article. |
• | Avoid using domain aggregate functions Avoid using domain aggregate functions, such as the DLookup function to access data from a table that is not in the query. Domain aggregate functions are specific to Access, and this means that the Jet database engine cannot optimize queries that use domain aggregate functions. Instead, add the query to the table that the function was accessing or create a subquery. |
• | Use fixed column headings If you are creating a crosstab query, use fixed column headings whenever possible. |
• | Use operators Use the Between...And operator, the In operator, and the = operator on indexed fields. |
• | Optimize performance on the server For bulk update queries against ODBC data sources, optimize performance on the server by setting the FailOnError property to Yes. |