It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened,
visit the help center.
Closed 7 years ago.
There is a query which runs more slowly than I would like, but I cannot share the details. The query returns the correct results already, and I have refactored it, but I cannot get it to run quickly enough. The predicates are already Sarg-able where possible. It is already properly using joins, requests no extra tables, and does not unnecessarily replicate rows or use nested subqueries in ways that would slow it down.
I’m not a DBA, and I don’t already know how to pick a good index to make my query faster. I can alter the table structures; there is no DBA in charge of the database, and I have the permissions on the database server to do so.
What are the steps I should take to optimize my SQL Query?
Intro: There is a lot to talk about here, and because of the complexity of SQL, it's going to be impossible for anyone to help with your query fully – it matters what your Query is, how large the tables are, and what the database system being used is. If you don’t know what indexes are, or how to use them, see here: How does database indexing work?.
Precaution: Again, if you have a DBA for your system, check with them before indexing anything, especially on a live system. They can even help, if you're nice to them. If the system is used by many others, be careful before changing anything like indexes. If the data is being used for multiple query types, make sure you aren't creating tons of indexes on them that conflict or overlap.
Syntax. The standard (SQL92) uses: CREATE INDEX [index name] ON [table name] ( [column name] )
. This syntax should work on almost any system. If you need only one index on the table, and there is not already a clustered index, you can use: CREATE [Unique] Clustered INDEX [index name] ON [table name] ( [column name] )
- it should be unique if there cannot be multiple items with the same values. If you can't get this to work, see this post for more details: How do I index a database column.
Which tables should be indexed? Any table that is being used for querying, especially if the data is static or only gets new values, is a great candidate. If the table is in your query, and has a join statement, you probably want to have an index on the column(s) being joined.
What columns should be indexed? There are full books written on choosing the best indexes, and how to properly index a database. A basic rule of thumb for indexing, if you don't want to dive deep into the problem, is: index by the following, in this order:
- Join predicates (
on Table1.columnA=Table2.ColumnA and Table1.columnB=Table2.ColumnQ
)
- Filtered columns (
where Table1.columnN=’Bob’ and Table1.columnS<20
)
- Order by / Group By / etc. (any column which is used for the order/grouping should be in the index, if possible.)
Also:
- Use data types that make sense - store nothing as varchar if it's an integer or date. (Column width matters. Use the smallest data type you can, if possible.)
- Make sure your joins are the same data type - int to int, varchar to varchar, and so on.
- If possible, use unique, non-null indexes on each join predicate in each tables.
Make sure whatever columns possible are non-null. (If they cannot contain null values, you can use the following syntax.
Alter table Table1
alter column columnN int not null
Do all of this, and you'll be well on your way. But if you need this stuff regularly, learn it! Buy a book, read online, find the information. There is a lot of information out there, and it is a deep topic, but you can make queries MUCH better if you know what you are doing.