Tuesday, July 30, 2013

SQL Server Performance Tips

SQL Server performance tip - Do not use NOT IN clause in Subquery use LEFT OUTER JOIN instead


Do not use NOT IN clause in sub query, instead of this use LEFT OUTER JOIN shown in below example query. This will reduce the execution time and improves the performance.
To know more details with examples, create two sample tables Employees and ResginedEmployees.
CREATE TABLE Employees(EmpID INT,Name VARCHAR(50))
INSERT INTO Employees VALUES(1,'Steve')
INSERT INTO Employees VALUES(2,'Brown')
INSERT INTO Employees VALUES(3,'Smith')
INSERT INTO Employees VALUES(4,'Chris')
INSERT INTO Employees VALUES(5,'Andrew')

CREATE TABLE ResginedEmployees(EmpID INT,Date DATETIME)
insert into ResginedEmployees VALUES(3,'2008-01-01')
insert into ResginedEmployees VALUES(4,'2009-01-01')
Normal query to get all employees who are not resigned is,
SELECT * FROM Employees WHERE EmpID NOT IN (SELECT EmpID FROM ResginedEmployees)
This query execution time would degrade the performance. The best way to write the query for the same result is use LEFT OUTER JOIN and use NULL value to any column of second table in where condition as shown below.
SELECT * FROM Employees E LEFT OUTER JOIN ResginedEmployees R on E.EmpID=R.EmpID
WHERE R.EmpID is NULL
Note that you can use R.DATE is NULL (any column from second table with NULL value) in where condition for same result.
Output
Query optimization example




SQL Performance Tips


Specific Query Performance Tips
  1. Use EXPLAIN to profile the query execution plan
  2. Use Slow Query Log 
  3. Don't use DISTINCT when you have or could use GROUP BY
  4. Insert performance
    1. Batch INSERT and REPLACE
    2. Use LOAD DATA instead of INSERT
  5. LIMIT m,n may not be as fast as it sounds. Learn how to improve it and read more about Efficient Pagination Using MySQL
  6. Don't use ORDER BY RAND() if you have > ~2K records
  7. Use SQL_NO_CACHE when you are SELECTing frequently updated data or large sets of data
  8. Avoid wildcards at the start of LIKE queries
  9. Avoid correlated subqueries and in select and where clause (try to avoid in)
  10. No calculated comparisons -- isolate indexed columns
  11. ORDER BY and LIMIT work best with equalities and covered indexes
  12. Separate text/blobs from metadata, don't put text/blobs in results if you don't need them
  13. Derived tables (subqueries in the FROM clause) can be useful for retrieving BLOBs without sorting them. (Self-join can speed up a query if 1st part finds the IDs and uses then to fetch the rest)
  14. ALTER TABLE...ORDER BY can take data sorted chronologically and re-order it by a different field -- this can make queries on that field run faster (maybe this goes in indexing?)
  15. Know when to split a complex query and join smaller ones
  16. Delete small amounts at a time if you can
  17. Make similar queries consistent so cache is used
  18. Have good SQL query standards
  19. Don't use deprecated features
  20. Turning OR on multiple index fields (<5.0) into UNION may speed things up (with LIMIT), after 5.0 the index_merge should pick stuff up.
  21. Don't use COUNT * on Innodb tables for every search, do it a few times and/or summary tables, or if you need it for the total # of rows, use SQL_CALC_FOUND_ROWS and SELECT FOUND_ROWS()
  22. Use INSERT ... ON DUPLICATE KEY update (INSERT IGNORE) to avoid having to SELECT
  23. use groupwise maximum instead of subqueries
  24. Avoid using IN(...) when selecting on indexed fields, It will kill the performance of SELECT query.
  25. Prefer using UNION ALL if you don't need to merge the resul