The following sections cover some simple techniques to optimize performance in Access. Included are tricks dealing with relationships, indexes, whole database structures, and performance tuning.
To be certain that Access has the greatest possible choice when determining indexes to use, you should create relationships between tables that will be joined. When you set up relationships in Access, not only are you defining referential integrity and cascading operations, but you're also creating indexes on the tables.
Some indexes are exposed when the indexes collection for a table is viewed. The Foreign property indicates an index that was created because of a relationship defined in the database. Other internal indexes are created when tables are joined and can be found by searching MSysObjects (the hidden system table where Access stores information on its objects) for type 8 objects, or by looking at MSysRelationships.
Tip
Giving Access a wide choice of indexes to resolve query operations increases the chance that Access will choose an index that can provide good performance on large amounts of data.
Indexing every field might seem like a good idea, but keep in mind the drawbacks to this approach:
Adding new records becomes increasingly slower as you add indexes to your table, especially when your table has large numbers of records. This also means more index locks and more multiuser locking issues for the database to manage. As a result, performance will suffer.
The size of your database grows for each index. With large Access databases, this growth can sometimes be a problem when disk space is limited.
Creating unnecessary indexes can fragment your base table data more than necessary. The rule of thumb here is to add indexes when they solve an optimization problem. Don't just add indexes to every field and call it an optimization pass.
You can have only 32 indexes on a table, so use them wisely. In practice, this isn't much of a drawback; only in rare cases should you find the need for more than 32 indexes.
With these restrictions in mind, begin optimization by looking at some preliminary points that set the foundation for optimizing individual queries:
Customer=100
InvoiceDate > #1/1/95
Customer=100 And InvoiceDate > #1/1/95#
Note
If a compound index is used, the second restriction (InvoiceDate > #1/1/95#) can't be optimized.
On one of my projects, an Access database served as a referral list to be searched by many different desktops. A main record was linked to more than 15 child tables by using an integer as the join field, and data was displayed from all 15 child tables on forms after the query ran. Some child tables consisted of 10,000 records of detail. A mainframe supplied the data, and users would never be updating the information directly.
The main requirement was to make the system fast. My first version had a completely normalized schema and was perfect in all ways. The queries ran well, but too many tables were involved in most joins, and I was summarizing the same base table information repeatedly. The users wanted to see detail and were selecting summary information.
After some serious soul-searching, I summarized many of the tables into two main tables that were built as the data was downloaded from the mainframe. Now, most queries could be answered by joining only two or three tables, which increased the performance dramatically. But when query performance was increased, the customers began complaining about the display performance.
Summarizing was taken one step further, and almost all the display data was stored in the main referral record. This meant creating large memo fields with imbedded carriage returns so that the data could be displayed in text boxes instead of subforms that were linked to the child tables.
After I implemented the changes, the final data display didn't require the links to so many tables and therefore ran much faster when users navigated from one record to another in the results list.
The moral of this story is not to overlook changing the structure of the database when you're looking for ways to optimize query performance. In this case, the relational design was nearly abandoned in the name of better performance.
Join performance can vary widely based on the types and numbers of fields used in the join. Access works best when it can join on small numeric fields. It's also wise to join on fields that have the same data type to avoid data conversion during the join operation.
18.191.239.123