1. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  2. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0
  3. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
  4. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num=10 or num=20
    可以这样查询:
    select id from t where num=10 union all select id from t where num=20
  5. in 和 not in 子查询也要慎用,因为在一些情况下索引更改或者统计信息不充分情况造容易成执行计划改变,比方 >=或者 <= any,如果是连续的数值,最好能用 between 就不要用 in :
    select id from t where num between 1 and 3
  6. 下面的查询也将导致全表扫描:
    select id from t where name like '%abc%'
    若要提高效率,可以考虑全文检索。
  7. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
    select id from t where num=@num
    可以改为强制查询使用索引:
    select id from t with(index(索引名)) where num=@num
  8. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where num/2=100
    应改为:
    select id from t where num=100*2
  9. 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where substring(name,1,3)='abc'
    -- name以abc开头的id
    select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
    应改为:
    select id from t where name like 'abc%'
    select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
  10. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
  11. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
  12. 不要写一些没有意义的查询,如需要生成一个空表结构:
    select col1,col2 into #t from t where 1=0
    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
    create table #t(...)
  13. 很多时候用 exists 代替 in 是一个好的选择:
    select num from a where num in (select num from b)
    用下面的语句替换:
    select num from a where exists(select 1 from b where num=a.num)
  14. 并不是所有索引对查询都有效,low cadinality有时候全表比走索引有效。

主要判断还是使用查询时,根据读索引块和数据块的多少,如果表是瘦表且数据块存放比较有序,但索引块随机,在这种情况下,相比到20%的查询用索引块还不如把表全扫描块下来的有效。参考聚簇因子

  1. 尽量避免单表上建过多索引(通常B树),不能往往只考虑查询,大量的DML产生造成enq: TX - index contention等待,索引块分裂也不能充分利用索引块,同时索引本身会占用大量空间,甚至有时候比表还大,维护成本高。在批量的插入、删除或者更新操作之前,考虑先删除该表上的索引,在操作完毕之后在重新建立,这样有助于提高批量操作的整体速度,并且保证B树索引在操作之后有良好的性能。

  2. 应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

  3. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

  4. 尽可能的使用 varchar/varchar2 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,char类型虽然适合字符固定的字段,但谁也不能保证业务变化,会造成类似字符比较时空格填充等问题,排查困难。

  5. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段,因为这些语句不会绑定变量,造成硬解析。

  6. 避免频繁创建和删除临时表,mysql或者sqlserver注意尽量使用表变量来代替临时表的适用情况;如果表变量包含大量数据,通常临时表的速度反而更快,但对于一次性事件,最好使用导出表。

  7. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 insert /* + appand */ into +nologging,避免生成不必要的undo和redo,以提高速度。

  8. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

  9. 尽量避免使用游标,因为游标的效率较差,多半是语句和解析问题,如果出现像pin S wait on X 等待事件,那么就应该考虑改写。

  10. 使用基于游标的方法或临时表方法之前,应先寻找collect into等批量方式来解决问题。

  11. 与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

  12. 尽量避免大事务操作,提高系统并发能力。

  13. 尽量避免长事务,非计划性的长事务会造成大量回滚信息和锁,对此最好有指标监控,涉及到业务逻辑问题应该及时调整。其中非计划性问题可能涉及但不全包括:
    存储过程事务或者作业未提交
    dblink或者客户端rpc调用未设置timeout
    sqlnet.ora格式问题:sqlnet.expire_time前面不能有空格或者tab键
    程序事务控制部分未设置超时时间,及时提交,超时或异常回滚
    连接池配置不合理

  14. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理,比方通过线下或者查询库。

SQL尽量避免的情况相关推荐

  1. SQL SERVER中什么情况会导致索引查找变成索引扫描

    原文:SQL SERVER中什么情况会导致索引查找变成索引扫描 SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方 ...

  2. linux查看db2存储过程,DB2查看存储过程里SQL语句的执行情况

    动态SQL可以用snapshot查看,存储过程里SQL语句的执行情况用event monitor查看. 但是event monitor没有记录SQL语句,而是记录了package id和Section ...

  3. 应用Druid监控SQL语句的执行情况--转载

    Druid是什么? Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBo ...

  4. sql 除以_使用SQL分析游戏运营情况

    数据来源:http://www.dcjingsai.com/common/cmpt/%E6%B8%B8%E6%88%8F%E7%8E%A9%E5%AE%B6%E4%BB%98%E8%B4%B9%E9% ...

  5. SQL优化:紧急情况下提高SQL性能竟是这样实现的!(文中有惊喜)

    关注我们获得更多精彩 作者 | 黄堋 ,多年一线 Oracle DBA 经验,长期服务电信.电网.医院.政府等行业客户.擅长数据库优化.数据库迁移升级.数据库故障处理. 在某运营商的优化经历中曾经遇到 ...

  6. 应用Druid监控SQL语句的执行情况

    Druid是什么? Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBo ...

  7. SQL题:还款情况分析

    一道SQL笔试题:数据分析方向的,考察sql plan表:还款计划表(id,还款计划日期,应还余额) pay表:实际还款情况(id,还款日期,实际还款余额) 表结构如下: create table p ...

  8. sql服务器虚拟内存不足,解决SQL Server虚拟内存不足情况

    解决SQLServer虚拟内存不足情况 症状 在具有2GB或更多RAM的计算机上,除了256MB(SQLServer7.0)或384MB(SQLServer2000)虚拟地址空间之外,SQLServe ...

  9. 如何解决PL/SQL Developer过期的情况

    首先,登陆PL/SQL Developer,会出现这种情况,如图所示,就是PL/SQL Developer要到期了,或者已经到期了. 紧急处理办法是,输入指令"regedit"打开 ...

最新文章

  1. C#数据结构与算法揭秘15
  2. 计算机组装需要的硬件,组装电脑选择硬件,只要记住2个装机思路,选好硬件配置不是难题...
  3. 如何从用户体验的角度去做一个网站的页面设计
  4. 14-4-5 17 MySQL 主主同步
  5. mysql的一些初步使用!mysqlcheck mysqladmin 建立删除修改表,库,等
  6. Pandas Index 转换排序联表选取
  7. c 语言 二进制 十进制,C 语言实例 - 二进制与十进制相互转换
  8. SQLServer数据库中截取字符串的常用方法
  9. 也谈SQLite效率:Julia和CSV
  10. 软考中级软件设计师--考试准备
  11. 51定时器PWM调节
  12. 【算法】两矩形相交的判定
  13. 安装完固态硬盘后计算机里没显示,安装了双硬盘电脑却不显示新硬盘怎么办
  14. Linux 音频驱动(六) ALSA音频驱动之PCM Write数据传递过程
  15. oracle pl/sqp 连接 ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务
  16. 服务器guid怎么装系统,GUID分区模式,UEFI+PGT磁盘模式安装Ghost系统详解
  17. 错误记录----javac错误:javac不是内部或外部命令 也不是可运行的程序
  18. android ota权限,Android手机Root后不能接收OTA?
  19. Java是先难后易吗_做题先易后难,干活先难后易
  20. javax.naming.OperationNotSupportedException: Context is read only

热门文章

  1. java调色板制作源码,JS实现的在线调色板实例(附demo源码下载)
  2. 毫米波雷达识别问题分析及解决措施
  3. 基于Java日程表系统的设计与实现
  4. msxml document class EOleSysError with message '没有注册类别' 错误的解决
  5. 计算机专业开题报告论证记录如何写,开题论证记录
  6. 算法第十期——DFS(深度优先搜索)的剪枝优化
  7. npm run build打包产生的build文件夹通过nginx部署到服务器上访问(centos8)
  8. 数据可视化策略_从无见识到有见识的四种设计有影响力的数据可视化的策略
  9. 研发项目工时统计工具哪个好?9大工时管理系统盘点
  10. 理解了DirectShow播放原理