159.Oracle数据库SQL开发之 SQL优化——若干
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/50186029
SQL的主要功能之一时不需要确切地告诉数据库如何获得请求的数据。只需要一个查询,指定想要的信息,然后数据库就会找到最好的方法获得它。有时候可以通过优化SQL语句改进性能。
1. 使用WHERE子句过滤行
有时候想要检索一行时,却会检索表中的所有行,非常浪费的。可以使用WHERE子句。
获取全部行命令如下: select * from customers;
改成:select * from customers where customer_id in (1,2);
2. 使用表连接而不是多个查询
从多个相关表中检索数据时,应该使用连接条件而不应该使用多个查询。
例如两个:
Select name,product_type_id from productswhere product_id=1;
Select name from product_types whereproduct_type_id=1;
使用表连接如下:
Select p.name,pt.name from productsp,product_types pt where p.product_type_id = pt.product_type_id andp.product_id = 1;
结果一样。但是执行一个查询通常比执行两个查询效率更高。
查询中必须选择连接顺序,将行较少的表连接到后面。
查询中应该避免连接复制的视图,因为这样会导致查询中首先执行的是视图,然后才是实际查询。
3. 执行连接时使用完全限定的列引用
在查询中包含表别名,并在查询中使用每列的别名(称为完全限定的列引用)。这样数据库不需要搜索查询所使用的表的每一列。
BAD如下:
Select p.name,pt.name,description,pricefrom products p,product_types pt where p.product_type_id=pt.product_type_id andp.product_id=1;
数据库必须搜索products和product_types两个表来获得description和price列。
改成如下:
Select p.name,pt.name,p.description,p.pricefrom products p,product_types pt where p.product_type_id = pt.product_type_idand p.product_id=1;
4. 使用CASE表达式而不是多个查询
当需要对一个表的相同行执行许多计算时,使用CASE表达式而不是多个查询。
如下3个查询:
Select count(*)from products where price < 13;
Select count(*)from products where price between 13 and 15;
Select count(*)from products where price > 15;
可以优化使用CASE表达式编写一个查询,如下:
Select
COUNT(CASE WHEN PRICE < 13 then 1else null end) low,
Count( case when price between 13 and15 then 1 else null end ) med,
Count(case when price > 15 then 1else null end) high
From products;
5. 添加表索引
从一个包含许多行的表中检索少数行时,只需要为一列建立一个索引。
一条成功经验是:
当当个查询检索的行数小于等于表总行数的10%时,建立索引是有用的。
位图索引一般用于数据仓库,数据仓库是包含大量数据的数据库。
6. 使用WHERE而不是HAVING
WHERE子句用于过滤行;HAVING子句用于过滤行组。因为行被分组之后HAVING才可以过滤行组,所以应该尽量使用WHERE子句过滤行。
较差的如下:
Select product_type_id,avg(price) fromproducts group by product_type_id having product_type_id in ( 1,2);
将WHERE而不是HAVING,执行如下:
SELECT product_type_id,avg(price) fromproducts where product_type_id in ( 1,2) group by product_type_id;
7. 使用UNION ALL而不是UNION
UNION ALL用于获得两个查询检索到的所有行,包括重复行。UNION用于获得查询检索到的所有不重复的行。因为UNION要删除重复行(需要一定时间),所以尽量使用UNION ALL。
8. 使用EXISTS而不是IN
IN用于检查一个值是否包含在列表中。EXIST用于检查子查询返回行的存在性。EXIST只检查行的存在性,而IN检查实际的值。在子查询中,EXISTS提供的性能通常比IN提供的性能要好。因此,应该尽量使用EXISTS而不是IN。
9. 使用EXISTS而不是DISTINCT
DISTINCT用于禁止重复行的显示;EXISTS用于检查子查询返回行的存在性。
应该使用EXISTS而不是DISTINCT,因为DISTINCT在排除重复行之前要对检索到的行排序。
10. 使用GROUPING SETS而不是CUBE
GROUPING SETS提供的性能通常比CUBE提供的性能更好。尽量使用GROUPINGSETS而不是CUBE。