注:这是从原文翻译过来的,我看写得很好,所以就记录了下来,翻译有什么问题还请见谅,因为自己留着可能有用,有需要的看原文可能更好,原文链接:http://beginner-sql-tutorial.com/sql-query-tuning.htm SQL语句是用来从数据库中检索数据的,我们可以根据不同的SQL语句来获取到相同的结果,但是当考虑到性能的时候,最佳的查询方案是很重要的,所以基于需求你需要去对SQL进行调优,以下是对SQL优化的一些建议1) 如果你在SELECT语句中使用实际的列名称而不是"*",SQL查询会更快例如:你应该使用
SELECT id, first_name, last_name, age, subject FROM student_details;而不是:
SELECT * FROM student_details;
2) HAVING项是用来过滤已经查询出的数据行,就像一个filter过滤条件,不要使用HAVING用于任何其他目的。例如:你应该使用
SELECT subject, count(subject) FROM student_details WHERE subject != 'Science' AND subject != 'Maths' GROUP BY subject;代替:
SELECT subject, count(subject) FROM student_details GROUP BY subject HAVING subject!= 'Vancouver' AND subject!= 'Toronto';
3) 有时候在主查询中可能会存在多个子查询,尽量减少主查询中的子查询块数量例如:你应该使用
SELECT name FROM employee WHERE (salary, age ) = (SELECT MAX (salary), MAX (age) FROM employee_details) AND dept = 'Electronics';代替:
SELECT name FROM employeeWHERE salary = (SELECT MAX(salary) FROM employee_details) AND age = (SELECT MAX(age) FROM employee_details) AND emp_dept = 'Electronics';
4) 正确地在查询中使用EXISTS,IN和表关联关系a) 通常情况下IN的性能是最差的b) 当多数过滤条件是在子查询中时,IN的效率更高c) 当多数过滤条件在主查询中时,EXISTS的效率更高例如:你应该使用
Select * from product p where EXISTS (select * from order_items o where o.product_id = p.product_id)代替:
Select * from product p where product_id IN (select product_id from order_items
5) 在涉及到关联具有一对多关联关系的表的时候,使用EXISTS,而不用DISTINCT例如:你应该使用
SELECT d.dept_id, d.dept FROM dept d WHERE EXISTS ( SELECT 'X' FROM employee e WHERE e.dept = d.dept);代替:
SELECT DISTINCT d.dept_id, d.dept FROM dept d,employee e WHERE e.dept = e.dept;
6) 尽量使用UNION ALL代替UNION例如:你应该使用
SELECT id, first_name FROM student_details_class10 UNION ALL SELECT id, first_name FROM sports_team;代替:
SELECT id, first_name, subject FROM student_details_class10 UNION SELECT id, first_name FROM sports_team;
7) 注意使用WHERE过滤条件例如:你应该使用
SELECT id, first_name, age FROM student_details WHERE age > 10;代替:
SELECT id, first_name, age FROM student_details WHERE age != 10;--使用
SELECT id, first_name, age FROM student_details WHERE first_name LIKE 'Chan%';代替:
SELECT id, first_name, age FROM student_details WHERE SUBSTR(first_name,1,3) = 'Cha';--使用查询
SELECT id, first_name, age FROM student_details WHERE first_name LIKE NVL ( :name, '%');代替:
SELECT id, first_name, age FROM student_details WHERE first_name = NVL ( :name, first_name);--使用查询
SELECT product_id, product_name FROM product WHERE unit_price BETWEEN MAX(unit_price) and MIN(unit_price)代替:
SELECT product_id, product_name FROM product WHERE unit_price >= MAX(unit_price) and unit_price <= MIN(unit_price)使用查询
SELECT id, name, salary FROM employee WHERE dept = 'Electronics' AND location = 'Bangalore';代替:
SELECT id, name, salary FROM employee WHERE dept || location= 'ElectronicsBangalore';
在查询的一边使用没有列的表达式,因为这样会被更快的处理例如使用:
SELECT id, name, salary FROM employee WHERE salary < 25000;代替
SELECT id, name, salary FROM employee WHERE salary + 10000 < 35000;使用查询
SELECT id, first_name, age FROM student_details WHERE age > 10;代替:
SELECT id, first_name, age FROM student_details WHERE age NOT = 10;
8) 使用DECODE来避免重复扫描同一行或者重复关联同一个表,DECODE也可以用于Group By和Order By中例如:使用查询
SELECT id FROM employee WHERE name LIKE 'Ramesh%' and location = 'Bangalore';代替:
SELECT DECODE(location,'Bangalore',id,NULL) id FROM employee WHERE name LIKE 'Ramesh%';
9) 在存储大型的二进制对象时,将它们存储到文件系统中,只需要在数据库存储相应的路径即可
10) 编写高效率高性能的查询语句遵循的SQL标准规则:a) SQL谓词的单一使用b) 在新的一行开始SQL谓词 比如:FROM, JOIN等等c) 用单个空格将单词分隔开d) Right or left aligning verbs within the initial SQL verb(此话不知该如何翻译)