How to Write Optimal SQL Queries
- Views are macros, not magic
- EXISTs and NOT EXISTs work best usually
- Functions on columns (see Joel C's answers)
- Beware implicit conversion (eg smallint column compared to int parameter)
- Understand covering indexes
- Denormalise after you see issues
- Understand aggregates: stop thinking of loops
- ...
Edit, Feb 2012:
Avoid these "Ten Common SQL Programming Mistakes"
My list is SQL Server specific (I'm sure that are lots more):
Use sargable where clauses - that means no functions especially scalar UDFs in where clauses among other things
WHERE NOT EXISTS tends to be the faster choice than a left join with a where id is null structure when you are looking for those rows which don't match a second table.
Correlated subqueries tend to run row by row and are horribly slow.
Views that call other views can't be indexed and become very slow especially if you get several levels in on large tables.
Select * is to be avoided espcially when you have a join as at least one column is sent twice which is wasteful of server and database and network resources.
Cursors can usually be replaced with much faster performing set-based logic When you store data in the correct way, you can avoid alot of on-the-fly transformations.
When updating, make sure you add a where clause so that you don't update rows where the new value and the old value are the same. This could be the differnce between updating 10,000,000 rows and updating 15. Sample (Tsql Update structure, if you use another db, you may have to lookup the correct syntax, but it should give you the idea.):
Update t
set field1 = t2.field2
from table1 t
join table2 t2 on t.tid = t2.tid
Where t.field1 <> t2.field2
Or
Update t
set field1 = @variable
from table1 t
Where t.field1 <> @variable
Check your indexing. SQL Seerver does not automatically index foreign keys. If they are used in a join, they generally need to be indexed.
If you are constantly using functions on a field, you are probably not storing it correctly (or you should have a persisted calculated field and do the transformation only once not every time you select the column.)
You best bet is to get a good performance tuning book for your database of choice (what wokrs best is very database specific) and read the chapters concerning writing queries.