zoukankan      html  css  js  c++  java
  • sql优化

    加快检索速度,降低增删改速度
    在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
    选择性高的列上创建索引
    复合索引的主列应该是最有选择性的和where限定条件最常用的列。
    一个索引是按f1,f2,f3的次序建立的,若where子句是f2 = :var2,则因为f2不是索引的第1个字段,无法使用该索引:
    create index abc on student(sid,sname)
    create index abc1 on student(sname,sid)
    这两种索引方式是不一样的,索引abc对select * from student where sid=1;这样的查询语句更有效。
    索引abc1对select * from student where sname=‘louis’这样的查询语句更有效。
    因此建立索引的时候,字段的组合顺序是非常重要的,一般情况下,需要经常访问的字段放在组合字段的前面。
    where子句中的字段参与计算,函数等,都会导致全表扫描。
    索引和表单独存在。
    创建索引的默认类型:b数索引
    位图索引:(性别)create bitmap index student on(sex)
    管理索引:合理的索引顺序。
    t表(x,y,z),在x,y,z上分别都建立了索引(index1,index2,index3),那在查询select * from t where x=1 and y=2;的时候,会分别用到index1,index2.原理是先到index1索引表中查到符合x=1条件的记录,然后到index2索引表中查到y=2条件的记录。肯定是大于没有索引情况的全表扫描。
    如果经常查询x=?和y=?,那推荐使用组合index(x,y),这种情况下组合索引的效率是远高于两个单独的索引的。同时在用组合索引的时候,大家一定要主要一个细节:建立组合索引index(x,y,z)的时候,那在查询条件中出现x,xy,xyz都是可以用到该组合索引,但是y,yz,z是不能用到该索引的。
    删除一张表的重复记录(id是自增唯一主键,重复记录:其他字段都是一样):
    delete from t where id not in(select min(id) from t group by name,age);效率低
    delete from t al where not exists(select * from t a2 where al.id>a2.id and al.name=a2.name and a1.age = a2.age)效率高
    不等于(<> !=),a<>0对它的处理只会产生全表扫描,改为a>0 or a<0
    尽量不用通牌符“%”或者“_”作为查询字符串的第一个字符:当通配符"%"或者"_"作为查询字符串的第一个字符时,索引不会被使用。比如用T表中column1 like ‘%5400%’这个条件会产生全表扫描,如果改为column1 ‘X5400%’ or column1 like ‘B5400%’,则会利用column1的索引进行两个范围的查询。
    where子句中避免在索引列上使用计算.
    用">="代替">"
    where后面的条件顺序要求:
    where 后面的条件,表连接语句写在最前面,可以过滤掉最大数据记录的条件居后面。
    select * from zl_yhjbqk where dy_dj='1kv 一下' and xh_bz=1
    select * from zl_yhjbqk where xh_bz=1 and dy_dj='1kv 一下'
    以上两个sql中dy_dj 及xh_bz两个字段都没进行索引,多以执行的时候都是全表扫描,第一条sql的dy_dj='1kv 一下'条件在记录集内比率为99%,而xh_bz的比率只为0.5%。

    验证条件的执行顺序:
    第1条语句执行不会出错,第2条语句会提示除数不能为零。
    1.Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2;
    2.Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1;
    证明了SQL的语法分析是从右到左的。
    把能使结果集最少的条件放在最右边。
    Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。

    统一SQL语句的写法
    对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。
    select * from dual
    select * From dual
    其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行!
    用Where子句替换HAVING子句:避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。
    on是最先执行,where次之,having最后。在多表联接查询时,on比where更早起作用。
    用EXISTS替换DISTINCT:当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。
    (低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO (高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
    SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。
    union all 和union
    union和union all的区别是,union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。
    用UNION-ALL 替换UNION ( 如果有可能的话):
    or和in有时走索引,有时不走,效率差不多,少用
    用UNION替换OR (适用于索引列):
    用EXISTS替代IN、用NOT EXISTS替代NOT IN:
    >用>=代替,<用<=代替,这样可以有效的利用索引。

  • 相关阅读:
    TextBox控件
    Button控件
    WinForm调试输出数据
    使用NPIO操作Excel
    窗体类笔记
    this关键字的使用
    51job招聘.Net职位分析(关于大学生就业的一点建议)
    解决线性表的编程问题
    如何在UWP中统一处理不同设备间的页面回退逻辑
    Python带你轻松进行网页爬虫
  • 原文地址:https://www.cnblogs.com/dapeng520/p/4543844.html
Copyright © 2011-2022 走看看