简体   繁体   中英

Best indexes to create when a search may be on any or all of 3 fields

I am working on a new search function in our software where a user will be allowed to search on any or all of 3 possible fields A, B and C. I expect that if anything is entered for a field it will be a complete entry and not just a partial one.

So the user choices are

  • Field A, or
  • Field B, or
  • Field C, or
  • Fields A & B, or
  • Fields A & C, or
  • Fields B & C, or
  • Fields A, B & C.

My question is what indexes should be created on this table to provide maximum performance? This will be running on SQL Server 2005 and up I expect and a good user experience is essential.

Assuming searches are much more numerous, you will want to create an index on every subset of fields by which you wish to access your data. So that would be 6 indices if you wish to do it on the powerset of columns.

I would recommend this basic approach.

1) Make sure your table has a clustered index which is Unique, Ascending, and Small (ideally an INT).

2) Create the following three non-clustered indexes:

CREATE NONCLUSTERED INDEX ON dbo.YourTable(a) INCLUDE (b,c, [plus any potential output columns])
CREATE NONCLUSTERED INDEX ON dbo.YourTable(b) INCLUDE (a,c, [plus any potential output columns])
CREATE NONCLUSTERED INDEX ON dbo.YourTable(c) INCLUDE (a,b, [plus any potential output columns])

3) Use the index DMVs to compare the times each index is hit. If an index is used heavily, experiment by adding two more indexes. (Assume the index with C as a single tree node is the heavily used index.)

CREATE NONCLUSTERED INDEX ON dbo.YourTable(c,a) INCLUDE (b, [plus any potential output columns])
CREATE NONCLUSTERED INDEX ON dbo.YourTable(c,b) INCLUDE (a, [plus any potential output columns])

Compare how frequently they're used verses the single tree node index. If they're not being used infavor of the single tree node, they may be superfluous.

In summary, start with a minimal covering indexes and experiment based on usage.

this is difficult to answer without knowing your data or its usage. Hopefully A, B , and C are not long string data types. If you have minimal Insert/Update/Delete and/or will sacrifice everything for index usage, I would create an index on each of these:

A, B , C    <<<handles queries for: A, or A & B, or A, B & C
A, C        <<<handles queries for: A & C
B, C        <<<handles queries for: B, or B & C
C           <<<handles queries for: C

These should cover all combinations you have mentioned.

Also, you will also need to be careful to write a query that will actually use the index. If you have an OR in your WHERE you'll probably not use an index. In newer versions of SQL Server than you have you can use OPTION(RECOMPILE) to compile the query based on the runtime values of local variables and usually eliminate all OR and use an index. See:

Dynamic Search Conditions in T-SQL by Erland Sommarskog

you can most likely use a dynamic query where you only add the necessary conditions onto the WHERE to get optional index usage:

The Curse and Blessings of Dynamic SQL by Erland Sommarskog

You can also see this answer for more on dynamic search conditions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM