1.表连接数:
- 连接的表越多,性能越差
- 可能的话,将连接拆分成若干个过程逐一执行
- 优先执行可显著减少数据量的连接,既降低了复杂度,也能够容易按照预期执行
- 外连接没有内连接效果好,因为必须对左右表进行表扫描
2.子查询效率低,尽量少用
3.避免使用null列,null列使用索引没有意义
4.模糊查询不要在首位加%,会导致无法使用索引,直接全表扫描
5.order by子句不要使用非索引列或嵌套表达式,会导致性能降低
6.not运算无法使用索引,可改为能用索引的操作(例如!=改成>或<)
7.尽量让having的过滤行为在where中就完成,因为过滤行为越早完成,传递给下一个阶段的数据越少
8.使用exists代替in
9.索引:
- 分为聚集索引和非聚集索引
- 聚集索引存储记录是物理上的连续存在(根据拼音查字在字典中的位置)
- 非聚集索存储记录是逻辑上的连续存在(根据部首查字在字典中的位置)
无索引的表查询时按照顺序存续的方法扫描每个记录来查找符合条件的记录(字典的汉字打乱,无拼音和部首查询,要查字就需要一页一页的翻)
索引可实现折半查找,缺点是需要额外空间存放索引数据,增删改会对索引更新,增加四五次的磁盘IO.所以给一些不必要使用索引的字段增加索引会降低系统性能.
哪些情况设置索引:
- 使用聚合索引及非聚合索引:外键列、主键列、经常被分组排序(Group By或Order By)
- 使用聚合索引:返回某范围内的数据、小数目的不同值
- 使用非聚合索引:大数目的不同值、频繁更新的列、频繁修改索引列
- 均不该使用:一个或极少不同值
建立索引的原则:
1)定义主键的数据列一定要建立索引。
2) 定义有外键的数据列一定要建立索引。
3) 对于经常查询的数据列最好建立索引。
4) 对于需要在指定范围内的快速或频繁查询的数据列;
5) 经常用在WHERE子句中的数据列。
6) 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。
7) 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
8) 对于定义为text、image和bit的数据类型的列不要建立索引。
9) 对于经常存取的列避免建立索引
10) 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
11) 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。
对oracle来讲,sql语句尽量大写,内部需要将小写转成大写了再执行.
不要在索引列上使用函数,会停止使用索引,进行全表扫描
– 错误
SELECT … FROM DEPT WHERE SAL * 12 > 25000;
– 正确
SELECT … FROM DEPT WHERE SAL > 25000/12;
10.使用>=替代>
– 直接定位到4的记录(推荐)
select … from … where SAL >= 4 ;
– 先定位到3,再向后找1个(不推荐)
select … from … where SAL > 3 ;
11.使用union代替or
在索引列上,可以使用union替换or操作。索引列上的or操作会造成全表扫描。
– 高效:
SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = ‘MELBOURNE’
– 低效:
SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID=10 OR REGION =‘MELBOURNE’
12.union & union all
union具有去重的操作,增加了计算时间。
union all不需要去重,但会包含相同记录。同样功能下,首选union all操作。
13.is null & is not null
如果列可空,避免使用索引。对于多个列使用的索引,起码保证至少有个列不为空。对于多列索引,只有访问了第一个列才会启用索引,如果访问后面的列则使用的是全表扫描。
– 低效: (索引失效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;
– 高效: (索引有效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;