oracle索引

SQL优化技巧

北战南征 提交于 2019-11-26 21:07:53
现观察线上系统运行发现,线上某些业务查询存在等待时间长问题,后核查发现,部分问题出现在对数据库操作上Cost大部分时间,后根据网上各位前辈提供的优化技巧解决大部分问题,现写下本篇文章,一来巩固加深自己学习的优化技巧,二来方便正在为sql优化迷茫的猿友们提供一下思路和方法,共同进步,一起成长~ 1、现状描述 sql执行时间长、数据查询慢 2、问题对象 sql执行语句(特别是多表多条件关联查询数据) 3、理论知识 1、Oracle优化器 sql优化器:sql数据库中的优化器又叫查询优化器(QueryOptimizer)。它是SQL分析和执行的优化工具,它负责生成、制定SQL的执行计划。 sql优化器优化方式 基于规则的优化方式(Rule-BasedOptimization,简称为RBO) 它根据指定的规则顺序,对指定的表进行执行计划的选择。它着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的 内容怎样,也不会影响到你的“执行计划”,也就是说RB对数据不“敏感”。要求开发人员了解RBO的各项细则。在sql 10g中完全被CBO取代。 基于代价的优化方式(Cost-Based Optimization,简称为CBO)。 CBO是一种比RBO更加合理、可靠的优化器,它是从sql 8中开始引入,在sql10g中完全取代RBO。CBO是计算各种可能“执行 计划”的“代价”

用示例说明B-Tree索引性能优于BitMap索引

跟風遠走 提交于 2019-11-26 20:38:22
一、实验说明: 操作系统:rhel 5.4 x86 数据库:Oracle 11g R2 实验说明:该实验是为了说明B-Tree索引性能优于BitMap索引的情况。 二、实验操作: 首先创建一张t_btree表,并建立B-Tree索引,索引键是object_id: 1 SQL > create table t_btree as select * from dba_objects; 2 3 Table created. 4 5 SQL > create index ind_tree on t_btree( object_id ); 6 7 Index created. 执行两次下面的查询语句,并显示执行计划: 1 SQL > set autotrace traceonly; 2 SQL > select * from t_btree where object_id = 9899 ; 3 4 5 Execution Plan 6 -- -------------------------------------------------------- 7 Plan hash value: 447474086 8 9 -- --------------------------------------------------------------------------------------

Oracle 索引维护

大城市里の小女人 提交于 2019-11-26 20:35:31
一、本文说明 在浏览Dave的博客的时候发现有一篇关于索引维护的文章,感觉挺好的,自己对索引的维护了解甚少,因此在这里转载+模拟一下,如果想要看原文可以点击友情链接中的Dave在他的博客中可以找到。 二、查看系统表中的用户索引 在Oracle中,SYSTEM表空间是安装数据库时自动建立的,它包含数据库的全部数据字典,存储过程、包、函数和触发器的定义以及系统回滚段。 一般来说,应该尽量避免在SYSTEM表空间中存储非SYSTEM用户的对象。因为这样会带来数据库维护和管理的很多问题。一旦SYSTEM表空间损坏了,只能重新生成数据库。我们可以用下面的语句来检查在SYSTEM表内有没有其他用户的索引存在。 1 SQL > select * from dba_indexes where tablespace_name = ' SYSTEM ' and owner not in ( ' SYS ' , ' SYSTEM ' ); 三、索引的存储情况检查 Oracle为数据库中的所有数据分配逻辑结构空间。数据库空间的单位是block、extent和segment。 Block:是Oracle使用和分配的最小存储单位。它是由数据库建立时设置的DB_BLOCK_SIZE决定的。一旦数据库生成了,数据块的大小不能改变。要想改变只能重新建立数据库。 Extent:是由一组连续的block组成的

Oracle之虚拟索引

我只是一个虾纸丫 提交于 2019-11-26 20:32:16
一、引言 DBA在日常维护管理数据库进行低性能SQL分析时,有时候需要通过创建索引对SQL进行优化,但有些时候我们创建的索引是否能用到?这个只能创建以后才能看出效果,但是在实际工作中,特别是对大表创建索引对系统性能有很大影响,因此我们不得不避开业务高峰时段,但是有没有一种办法创建索引而不影响性能呢?有,那就是虚拟索引。 虚拟索引不是物理存在的,它并不会创建实际的索引段,只是在数据字典中加了一个索引的记录,使得优化器能够意识到一个索引的存在,从而判断是否使用该索引作为访问路径。作用仅仅是为了DBA作SQL优化时使用,DBA根据虚拟索引的优化效果决定是否创建物理索引。 二、虚拟索引类型 虚拟索引支持B-TREE索引和BIT位图索引,在CBO模式下ORACLE优化器会考虑虚拟索引,但是在RBO模式下需要添加hint才行。 三、虚拟索引创建实例 SQL > drop table t purge; 表已删除。 SQL > create table t as select * from dba_objects; 表已创建。 -- 创建虚拟索引,首先要将_use_nosegment_indexes的隐含参数设置为true SQL > alter session set "_use_nosegment_indexes" = true; 会话已更改。 -- 虚拟索引的创建语法比较简单

SQL性能优化

ε祈祈猫儿з 提交于 2019-11-26 19:51:13
SQL性能优化 Oracle 优化器RBO, CBO RBO 基于规则的优化器 oracle 10g开始,已经丢弃RBO CBO 基于成本的优化器 oracle 8中开始引入的 Oracle 解析器按照从右到左的顺序处理FROM 字句中的表名,FROM 中写在最后的表(基础表, drving table)将先被处理,在FROM 子句中包含多个表的情况下,你必须选择记录条数最小的表作为基础表, 如果有3个以上的表连接查,选择交叉表(Insertection table)作为基础表,交叉表指的是被其他表锁引用的表 性能优化 SELECT语句务必指明字段名称 SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。 SQL语句中IN包含的值不应过多 MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from table_name where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了;再或者使用连接来替换。 尽量用union all代替union union和union

SQL优化34条

南笙酒味 提交于 2019-11-26 19:22:12
我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习、摘录、并汇总部分资料与大家分享! (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. (2) WHERE子句中的连接顺序.: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. (3) SELECT子句中避免使用 ‘ * ‘: ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间 (4) 减少访问数据库的次数: ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等; (5) 在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200

数据库分区表常用命令

旧巷老猫 提交于 2019-11-26 17:35:46
一、Oracle分区简介 ORACLE的分区是一种处理超大型表、索引等的技术。分区是一种“分而治之”的技术,通过将大表和索引分成可以管理的小块,从而避免了对每个表作为一个大的、单独的对象进行管理,为大量数据提供了可伸缩的性能。分区通过将操作分配给更小的存储单元,减少了需要进行管理操作的时间,并通过增强的并行处理提高了性能,通过屏蔽故障数据的分区,还增加了可用性。 二、Oracle分区优缺点 ? 优点: 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用; 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可; 均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能; 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 ? 缺点: 分区表相关:已经存在的表没有方法可以直接转化为分区表。不过 Oracle 提供了在线重定义表的功能。 三、Oracle分区方法 ? 范围分区: 范围分区就是对数据表中的某个值的范围进行分区,根据某个值的范围,决定将该数据存储在哪个分区上。如根据序号分区,根据业务记录的创建日期进行分区等。 ? Hash分区(散列分区): 散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区,使得这些分区大小一致。 ? List分区(列表分区):

Oracle直方图导致SQL不走索引.

北城以北 提交于 2019-11-26 16:28:31
在ITPUB 上看到一个帖子 http://www.itpub.net/thread-1875212-1-1.html 同一条SQL语句,只有查询条件不一样,查询返回的结果集都为0,一个走了全表扫描,一个走索引。查看全表扫描的SQL语句: SQL走全表,产生了2422609个逻辑读,cost为535K SQL> SELECT URL,YHZH,HFRZY,HFLR,SPURL,TPURL,YPURL,SCSJ,LY,JCSJ FROM YHXX_HFXX T 2 WHERE T.URL='http://club.kdnet.net/dispbbs.asp?id=10165509_boardid=1' 3 / no rows selected Execution Plan ---------------------------------------------------------- Plan hash value: 2068618995 ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------

order by与索引

别等时光非礼了梦想. 提交于 2019-11-26 16:28:19
ORDER BY 通常会有两种实现方法,一个是利用有序索引自动实现,也就是说利用有序索引的有序性就不再另做排序操作了。另一个是把结果选好之后再排序。 用有序索引这种,当然是最快的,不过有一些限制条件,来看下面的测试。 测试数据:student表有两个字段id ,sid ,id是主键。一共有20W条记录,id从1到200000,sid也是从1到200000的数据。 第一种情况 : order by的字段不在where条件也不在select中 select sid from zhuyuehua.student where sid < 50000 order by id; 第二种情况 : order by的字段不在where条件但在select中。 select id,sid from zhuyuehua.student where sid < 50000 order by id; 第三种情况 : order by的字段在where条件但不在select中。 select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id; 第四种情况 : order by的字段在where条件但不在select中。倒序排列 select sid from zhuyuehua.student where sid

惊!史上最全的select加锁分析(Mysql)

狂风中的少年 提交于 2019-11-26 16:12:06
引言 大家在面试中有没遇到面试官问你下面六句Sql的区别呢 select * from table where id = ? select * from table where id < ? select * from table where id = ? lock in share mode select * from table where id < ? lock in share mode select * from table where id = ? for update select * from table where id < ? for update 如果你能清楚的说出,这六句sql在不同的事务隔离级别下,是否加锁,加的是共享锁还是排他锁,是否存在间隙锁,那这篇文章就没有看的意义了。 之所以写这篇文章是因为目前为止网上这方面的文章太片面,都只说了一半,且大多没指明隔离级别,以及 where 后跟的是否为索引条件列。在此,我就不一一列举那些有误的文章了,大家可以自行百度一下,大多都是讲不清楚。 OK,要回答这个问题,先问自己三个问题 当前事务隔离级别是什么 id列是否存在索引 如果存在索引是聚簇索引还是非聚簇索引呢? OK,开始回答 正文 innodb一定存在聚簇索引,默认以主键作为聚簇索引 有几个索引,就有几棵B+树(不考虑hash索引的情形)