2010-09-27 142 views
2

Postgres/PGSQL和oracle中查询优化的基本原理是什么?SQL查询优化

+1

这是广泛的,然后再考虑多个数据库供应商 – 2010-09-27 04:55:57

+0

可能重复的[你最常见的SQL优化?](http://stackoverflow.com/questions/1332778/what-are-your-most-common- sql-optimizations) – Thilo 2010-09-27 04:57:51

回答

0

也许创造适当的指标,并适当缩进您的疑问,是建议最好的一块,我可以给你

+0

缩进与优化有什么关系?可读性是,优化否。 – 2010-09-27 04:58:54

+0

关键是:“适当的”指数。查看所有查询,他们目前使用的访问路径以及如何改进。不要随意添加索引。 – Thilo 2010-09-27 04:59:07

8

我遵循以下optimization技术

1)如果使用SQL查询变快SELECT语句中的实际列名称而不是'*'。

对于实施例:写查询作为

SELECT id, first_name, last_name, age, subject FROM student_details; 

代替:

SELECT * FROM student_details; 

2)HAVING子句用于选择了所有行之后过滤行。它就像一个过滤器。不要将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 employee 
WHERE salary = (SELECT MAX(salary) FROM employee_details) 
AND age = (SELECT MAX(age) FROM employee_details) 
AND emp_dept = 'Electronics'; 

4)使用运营商存在,且表中查询相应的联接。 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(位置, '班加罗尔',ID,NULL)ID FROM雇员 WHERE名称LIKE '%拉梅什';

9)要存储较大的二进制对象,首先将它们放置在文件系统中并在数据库中添加文件路径。

10)要编写能够提供高效性能的查询,请遵循一般的SQL标准规则。

a)使用单个情况下对所有SQL动词

b)中开始的所有SQL动词在新的一行

c)中分离为单个空格

d)向右或向左对准的所有字最初的SQL动词

+3

这是你给出的建议的混合包:有好的(如#5),很多规则不会加快查询速度超过2%,错误的(因为它们完全改变结果,就像#7的第一个例子)和愚蠢的(#8比较慢并且返回不同的结果,#9是基本的架构决定,#10对性能没有影响)。 – Codo 2010-09-27 17:42:20

2

一个非常通用的方法中的动词是:

  1. 的ident IFY其查询的一部分是花费大部分时间
  2. 重写,在以不同的方式,导致了同样的结果
  3. 措施查询的一部分再次
  4. 去#1再次,如果不提高查询或你想进一步优化

如果重写查询没有帮助,你应该考虑添加一个索引,以便数据库不需要读全表。但是测量,再次改变和测量的方法仍然是一样的。

为了识别查询中代价高昂的部分,您可以在Oracle中使用“解释计划”或“Autotrace”。你可以在SQL Developer或TOAD等工具中找到它。他们会告诉你如何执行你的查询(执行计划)以及计划的一部分是多么昂贵。

如果您的数据库具有相当大的规模,您主要需要在执行计划中观察全表扫描。他们是优化的首要目标。