What are examples of SQL Server Query features/clauses that should be avoided?
Recently I got to know that the NOT IN clause degrades performance badly.
Do you have more examples?
What are examples of SQL Server Query features/clauses that should be avoided?
Recently I got to know that the NOT IN clause degrades performance badly.
Do you have more examples?
The reason to avoid NOT IN
isn't really performance, it's that it has really surprising behaviour when the set contains a null. For example:
select 1
where 1 not in (2,null)
This won't return any rows, because the where
is interpreted like:
where 1 <> 2 and 1 <> null
First 1 <> null
evaluates to unknown. Then 1 <> 2 and unknown
evaluates to unknown. So you won't receive any rows.
I Recently changed a view from
Select Row1, Row2 FROM table Where blahID = FKblahID
UNION
Select Row1, Row2 FROM table2 Where blah2ID = FKblahID
to just
Select Row1, Row2 FROM table Where blahID = FKblahID
and saw a query that was taking ~8 mins run now only took ~20 secs not 100% sure why such a big change.
The second union was only returning about 200 records also, while the first was returning a couple thousand.
I avoid correlated subqueries (noncorrelated subqueries and derived tables are OK) and any cursors that I can avoid. Also avoid while loops if you can. Think in terms of sets of data not row-by-row processing.
If you are using a UNION, check to see if UNION ALL will work instead. There is a potential results difference, so make sure before you make the change.
I always look at the word DISTINCT as a clue to see if there is a better way to present the data. DISTINCT is costly compared to using a derived table or some other method to avoid it's use.
Avoid the implied join syntax to avoid getting an accidental cross join (which people often fix, shudder, with distinct). (Generating a list of 4 million records and then distincting to get the three you want is costly.)
Avoid views that call other views! We have some folks who designed one whole client database that way and performance is HORRIBLE! Do not go down that path.
Avoid syntax like WHERE MyField Like "%test%'
That and other non-saragable where clauses can keep the optimizer from using indexes.
Avoid
CURSOR - use set based ops
SELECT * - name you columns explicitly
EXEC(@dynamic_sql_with_input_parms) - use sp_executesql with input paramters.