基本的Sql编写注意事项

  • 尽量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替。
  • 不用NOT IN操作符,可以用NOT EXISTS或者外连接+替代。
  • Oracle在执行IN子查询时,首先执行子查询,将查询结果放入临时表再执行主查询。而EXIST则是首先检查主查询,然后运行子查询直到找到第一个匹配项。NOT EXISTS比NOT IN效率稍高。但具体在选择IN或EXIST操作时,要根据主子表数据量大小来具体考虑。
  • 不用“<>”或者“!=”操作符。对不等于操作符的处理会造成全表扫描,可以用“<” or “>”代替。
  • Where子句中出现IS NULL或者IS NOT NULL时,Oracle会停止使用索引而执行全表扫描。可以考虑在设计表时,对索引列设置为NOT NULL。这样就可以用其他操作来取代判断NULL的操作。
  • 当通配符“%”或者“_”作为查询字符串的第一
    • 个字符时,索引不会被使用。
    • 对于有连接的列“||”,最后一个连接列索引会无效。尽量避免连接,可以分开连接或者使用不作用在列上的函数替代。
    • 如果索引不是基于函数的,那么当在Where子句中对索引列使用函数时,索引不再起作用。
    • Where子句中避免在索引列上使用计算,否则将导致索引失效而进行全表扫描。
    • 对数据类型不同的列进行比较时,会使索引失效。
    • 用“>=”替代“>”。
    • UNION操作符会对结果进行筛选,消除重复,数据量大的情况下可能会引起磁盘排序。如果不需要删除重复记录,应该使用UNION ALL。
    • Oracle从下到上处理Where子句中多个查询条件,所以表连接语句应写在其他Where条件前,可以过滤掉最大数量记录的条件必须写在Where子句的末尾。
    • Oracle从右到左处理From子句中的表名,所以在From子句中包含多个表的情况下,将记录最少的表放在最后。(只在采用RBO优化时有效,下文详述)
    • Order By语句中的非索引列会降低性能,可以通过添加索引的方式处理。严格控制在Order By语句中使用表达式。
    • 不同区域出现的相同的Sql语句,要保证查询字符完全相同,以利用SGA共享池,防止相同的Sql语句被多次分析。
    • 多利用内部函数提高Sql效率。
    • 当在Sql语句中连接多个表时,使用表的别名,并将之作为每列的前缀。这样可以减少解析时间。

    需要注意的是,随着Oracle的升级,查询优化器会自动对Sql语句进行优化,某些限制可能在新版本的Oracle下不再是问题。尤其是采用CBO(Cost-Based Optimization,基于代价的优化方式)时。

    我们可以总结一下可能引起全表扫描的操作:

    • 在索引列上使用NOT或者“<>”;
    • 对索引列使用函数或者计算;
    • NOT IN操作;
    • 通配符位于查询字符串的第一个字符;
    • IS NULL或者IS NOT NULL;
    • 多列索引,但它的第一个列并没有被Where子句引用;

    Oracle优化器

    Oracle优化器(Optimizer)是Oracle在执行SQL之前分析语句的工具。
    Oracle的优化器有两种优化方式:基于规则的(RBO)和基于代价的(CBO)。

    • RBO:优化器遵循Oracle内部预定的规则。
    • CBO:依据语句执行的代价,主要指对CPU和内存的占用。优化器在判断是否使用CBO时,要参照表和索引的统计信息。统计信息要在对表做analyze后才会有。Oracle8及以后版本,推荐用CBO方式。

    Oracle优化器的优化模式主要有四种:

    • Rule:基于规则;
    • Choose:默认模式。根据表或索引的统计信息,如果有统计信息,则使用CBO方式;如果没有统计信息,相应列有索引,则使用RBO方式。
    • First rows:与Choose类似。不同的是如果表有统计信息,它将以最快的方式返回查询的前几行,以获得最佳响应时间。
    • All rows:即完全基于Cost的模式。当一个表有统计信息时,以最快方式返回表所有行,以获得最大吞吐量。没有统计信息则使用RBO方式。

    设定优化模式的方式

    • Instance级别:在init<SID>.ora文件中设定OPTIMIZER_MODE;
    • Session级别:通过SQL> ALTER SESSION SET OPTIMIZER_MODE=;来设定。
    • 语句级别:通过SQL> SELECT /*+ALL+_ROWS*/
      ……;来设定。可用的HINT包括/*+ALL_ROWS*/、/*+FIRST_ROWS*/、/*+CHOOSE*/、/*+RULE*/ 等。

    要注意的是,如果表有统计信息,则可能造成语句不走索引的结果。可以用SQL>ANALYZE TABLE table_name DELETE
    STATISTICS; 删除索引。
    对列和索引更新统计信息的SQL:
    SQL> ANALYZE TABLE table_name
    COMPUTE STATISTICS;
    SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS;

基本的Sql编写注意事项的更多相关文章

  1. Oracle SQL编写注意事项

    1.SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行. 2.数据表最好起别名;因为便于sql优化器快速分析. 3.尽量不要使用 insert into tabl ...

  2. mybatis动态注解sql编写注意事项

    最近在编写mybatis的动态注解sql遇到了不少的坑,在网上看到一篇讲的比较详细的文章,记录一下: https://mbd.baidu.com/newspage/data/landingshare? ...

  3. Oracle数据库编程:使用PL/SQL编写触发器

    8.使用PL/SQL编写触发器: 触发器存放在数据缓冲区中.        触发器加序列能够实现自动增长.        在触发器中不能使用connit和rollback.        DML触发器 ...

  4. mysql删除sql表添加别名及删除sql的注意事项

    本文为博主原创,未经允许不得转载: 根据平常的习惯,个人会将操作的表后面添加一个别名,无论是使用还是不使用的时候,均是为了 修改还是扩展sql的时候更加安全,方便,快捷. 今天在写删除的sql时,对表 ...

  5. SQL优化的一些总结 SQL编写一般要求

    SQL编写一般要求---SQL语句尽可能简单---分解联接保证高并发---同数据类型的列值比较---不在索引列做运算---禁止使用SELECT *---避免负向查询和%前缀模糊查询---保持事务(连接 ...

  6. 常见的SQL编写和优化

    目录 常见SQL编写和优化 常见的SQL优化方式 常见SQL编写和优化 常见的SQL优化方式 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by 涉及的列上建立索引. 应尽量 ...

  7. Python爬虫开发:反爬虫措施以及爬虫编写注意事项

  8. 编写高性能SQL的注意事项

    在数据库部分,对数据库应用性能改进来说,需要重点关注应用程序,在查询设计和索引策略等方面进行优化,甚至可以把数据库查询效率提高数百倍,在其他方面的优化努力,其效果就没有这么明显(见下图).本文重点描述 ...

  9. SQL优化注意事项

    sql语句优化 性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的 ...

随机推荐

  1. global.fun.php

    <?php /**   所有公共函数文件*/ /**    序列化*/function _serialize($obj){    return base64_encode(gzcompress( ...

  2. Spring事务传播行为详解

    前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.这是Spring ...

  3. java并发系列(二)-----线程之间的协作(wait、notify、join、CountDownLatch、CyclicBarrier)

    在java中,线程之间的切换是由操作系统说了算的,操作系统会给每个线程分配一个时间片,在时间片到期之后,线程让出cpu资源,由其他线程一起抢夺,那么如果开发想自己去在一定程度上(因为没办法100%控制 ...

  4. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

  5. nginx链接末尾自动补全斜杠

    放在locaation里边就行 if (-d $request_filename){ rewrite ^(.*[^/])$ $/ permanent;#加斜杠 } 这样,nginx就会进行判断了,如果 ...

  6. 2019.10.21 csp-s模拟测试81 反思总结

    T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法 ...

  7. oracle习题练习-表空间-用户-表-约束

    题一 1.       创建名字为hy_tablespace的表空间,默认大小为10M;@@ 2.       创建一个用户,用户名以自己名字命名,并指定命名空间为hy_tablespace;@@@@ ...

  8. LINUX普通猫的拔号工具介绍

    普通猫分为串口和PCI的,请查看 <关于网络设备概述 > 普通猫的拔号工具主要有kppp和wvdial:在Redhat/Fedora中,用system-config-network 或re ...

  9. Sublime Text Version 3.2.1(Build 3207)注册

    Sublime Text Version 3.2.1, Build 3207 一. host添加地址 C:\Windows\System32\drivers\etc\hosts 127.0.0.1 l ...

  10. CSS-DOM的小知识(二)

    上篇文章说到,通过element.style.property可以获得元素的样式,但是style属性只能够返回内嵌样式,对于外部样式表的样式和head中的style样式都无法获取,这就限制了此方法的使 ...