--名词
-------------------------------
1)Rowid:系统自动生成的伪列,广泛(每个表都有),只读,伴随行的整个生命周期。指出了该行所在的数据文件、数据块以及行在该块中的位置。
Recursive SQL(递归SQL):
触发Recursive Call的情况:
(1)动态的分配空间:insert没有足够的空间来保存row记录时发生。
(2)修改数据字典信息:执行DDL语句时,ORACLE总是隐含的发出一些recursive SQL语句时发生。
(3)没有足够空间存储系统数据字典信息:Shared Pool过小,data dictionary cache 也相应的过小,将数据字典信息从硬盘读入内存中时发生。
在这种情况下,可以将recursive calls理解为从磁盘读取数据字典的次数。
(4)存储过程、触发器内有SQL调用时,也会产生recursive SQL。
2)Row Source(行源):查询中,上一操作返回的符合条件的行的集合(可以使全表,部分表和表连接之后的结果集)。
3)Predicate(谓词):查询中的WHERE限制条件
4)Driving Table(驱动表)/驱动行源(driving row source):该表又称为外层表(OUTER TABLE)。
一般说来,是应用查询的限制条件后,小row source表作为驱动表,行源数量较多会影响后续操作效率。
执行计划中,应该为靠上的那个row source,一般将该表称为连接操作的row source 1。
5)Probed Table(被探查表):该表又称为内层表(INNER TABLE)。
从驱动表中得到具体一行的数据后,在该表中寻找符合连接条件的行。为大row source且建立相应索引的表是效率高。
一般将该表称为连接操作的row source 2.
6)concatenated index(组合索引):由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……)
在组合索引中有一个重要的概念:引导列(leading column),在上面的例子中,col1列为引导列。当我们进行查询时可以使用“where col1 = ? ”,
也可以使用“where col1 = ? and col2 = ?”,这样的限制条件都会使用索引,但是“where col2 = ? ”查询就不会使用该索引。
所以限制条件中包含先导列时,该限制条件才会使用该组合索引。
7)selectivity(可选择性):比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。
如果该列的“唯一键的数量/表中的行数”的比值越接近1,则该列的可选择性越高,该列就越适合创建索引,同样索引的可选择性也越高。
在可选择性高的列上进行查询时,返回的数据就较少,比较适合使用索引查询。
--oracle访问数据的存取方法
--------------------------------
1) 全表扫描(Full Table Scans, FTS):读取表中所有的行,并检查每一行是否满足语句的WHERE限制条件。
优化:增加每次读取块数,减少I/O次数(db_file_multiblock_read_count参数设定)--不是经常大表走FTS不作调整,调整可能影响cbo不走索引
使用条件:在较大的表上不建议使用全表扫描,除非取出数据的比较多,超过总量的5%-10%,或使用并行查询功能。
select * from dual;
---------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)|
| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)|
---------------------------------------------------------------
2)通过ROWID的表存取(Table Access by ROWID或rowid lookup):直接访问一个数据块,Oracle存取单行数据的最快方法。
select * from tt where rowid='AAHSaUAALAAOaSAAAA';
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 1 (0)|
| 1 | TABLE ACCESS BY USER ROWID| TT | 1 | 5 | 1 (0)|
------------------------------------------------------------------------
3)索引扫描(Index Scan或index lookup):index获取->rowid值(对于非唯一索引可能返回多个rowid值)->表数据
索引内容:索引值+此值行对应的ROWID值
常识:index常用,内存中,逻辑I/O,访问快;
大表,放在磁盘中,物理I/O,访问慢;
索引中的数据已经预排序。
案例分析:
大表,取出数据的较多,超过总量的5%-10%->index获取rowid->物理I/O访问,慢;
查询的数据能全部在索引中找到,数据量无论多少,无论需不需要排序,都很快(不需要访问表数据,直接从索引取值)
分类:
(1) 索引唯一扫描(index unique scan)
通过唯一索引查找一个数值经常返回单个ROWID.如果存在UNIQUE 或PRIMARY KEY 约束(它保证了语句只存取单行)的话,Oracle经常实现唯一性扫描。
select * from bd_corp where unitcode='J001';
--create unique index I_BD_CORP_1 on BD_CORP (UNITCODE);
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 293 | 1 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| BD_CORP | 1 | 293 | 1 (0)|
| 2 | INDEX UNIQUE SCAN | I_BD_CORP_1 | 1 | | 1 (0)|
--------------------------------------------------------------------------------
(2) 索引范围扫描(index range scan)
使用一个索引存取多行数据,使用index rang scan的3种情况:
(a) 在唯一索引列上使用了range操作符(> < <> >= <= between)
(b) 在组合索引上,只使用部分列进行查询,导致查询出多行
(c) 对非唯一索引列上进行的任何查询(在非唯一索引上,谓词可能返回多行数据,所以在非唯一索引上都使用索引范围扫描)。
select * from bd_corp where begindate>'2016-01-01';
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 22 | 6446 | 9 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| BD_CORP | 22 | 6446 | 9 (0)|
| 2 | INDEX RANGE SCAN | I_BD_CORP_CT | 22 | | 1 (0)|
---------------------------------------------------------------------------------
(3)索引全扫描(index full scan)
与全表扫描对应,也有相应的全索引扫描。而且此时查询出的数据必须全部从索引中可以直接得到。
全索引扫描的例子:
select unitcode from bd_corp order by unitcode;
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 791 | 3955 | 1 (0)|
| 1 | INDEX FULL SCAN | I_BD_CORP_1 | 791 | 3955 | 1 (0)|
---------------------------------------------------------------------
(4)索引快速扫描(index fast full scan)
扫描索引中的所有的数据块,与index full scan很类似,区别是它不对查询出的数据进行排序。可以使用多块读功能增加吞吐量,也可以并行读入。
select unitname,unitcode from bd_corp order by unitname;
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 791 | 22939 | 6 (17)|
| 1 | SORT ORDER BY | | 791 | 22939 | 6 (17)|
| 2 | VIEW | index$_join$_001 | 791 | 22939 | 5 (0)|
| 3 | HASH JOIN | | | | |
| 4 | INDEX FAST FULL SCAN| I_BD_CORP_1 | 791 | 22939 | 2 (0)|
| 5 | INDEX FAST FULL SCAN| I_BD_CORP_2 | 791 | 22939 | 3 (0)|
---------------------------------------------------------------------------------
--表之间的连接/关联(JOIN)
-------------------------------
*可并行访问join的两个row source的数据,但数据读入内存形成row source后join的其它步骤一般是串行的。
1)按连接操作符分类(原理基本一样):
等值连接(如WHERE A.COL3 = B.COL4)、非等值连接(WHERE A.COL3 > B.COL4)、外连接(WHERE A.COL3 = B.COL4(+))。
2)连接类型:
(1)排序-合并连接(Sort Merge Join, SMJ):先排序,后连接
内部连接过程:<1>生成row source1,按照连接操作关联列排序
<2>生成row source2,按照连接操作关联列排序
<3>按条件连接两个行源
*<1>,<2>可并行,<3>串行
优势:若2个row source都已经预先排序,则效率较高。(预先排序包含:已被索引的列/row source在前面的步骤中已经排序)
对于非等值连接,这种连接方式的效率是比较高的。
对于将2个较大的row source做连接,该连接方法比NL连接要好一些。
劣势:sort费时、费资源,特别对于大row source。
(2)嵌套循环(Nested Loops, NL):驱动表的每一行逐一到被探查表去匹配(2层嵌套循环)。
内部连接过程(有驱动表(外部表)的概念):
Row source1的Row 1 —— Probe ->Row source 2
Row source1的Row 2 —— Probe ->Row source 2
Row source1的Row 3 —— Probe ->Row source 2
……
Row source1的Row n —— Probe ->Row source 2
优势:逐一匹配,先返回已经连接的行,响应快
驱动表较小,且被探查表上有唯一索引或高选择性非唯一索引时,则效率较高。
并行查询(硬件支持):常选择大表作为驱动表,因为大表可以充分利用并行功能。
劣势:内外表颠倒效率差。
(3)哈希连接(Hash Join)
参数: HASH_JOIN_ENABLED=TRUE,缺省情况下该参数为TRUE
hash_area_size --因为哈希连接会在该参数指定大小的内存中运行,过小的参数会减小性能。
alter session set workarea_size_policy=MANUAL;--先设置workarea_size_policy才能生效
alter session set hash_arear_size=200m;
优势:设置好参数,效率优于SMJ和NL(2个较大的row source之间连接时会取得相对较好的效率,在一个row source较小时则能取得更好的效率。)
劣势:只能用于等值连接中 只能用在CBO优化器中 需要设置合适的参数才能取得较好的性能。
(4)笛卡儿乘积(Cartesian Product):无关联关系的row source连接
通常由编写代码疏漏造成(即程序员忘了写关联条件)。笛卡尔乘积是一个表的每一行依次与另一个表中的所有行匹配。
select a.ta,b.ta from tt a ,tt1 b ;
------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 16 | 64 | 34 (0)|
| 1 | MERGE JOIN CARTESIAN| | 16 | 64 | 34 (0)|
| 2 | TABLE ACCESS FULL | TT1 | 4 | 8 | 8 (0)|
| 3 | BUFFER SORT | | 4 | 8 | 26 (0)|
| 4 | TABLE ACCESS FULL | TT | 4 | 8 | 7 (0)|
------------------------------------------------------------------
--CARTESIAN关键字指出了在2个表之间做笛卡尔乘积
在特殊情况下我们可以使用笛卡儿乘积,如在星形连接中,除此之外,我们要尽量不使用笛卡儿乘积。
--autotrace statistics 名词解释
-------------------------------
recursive calls:递归调用
db block gets:通过update/delete/select for update读的次数。在当前读模式下所读的块数,比较少和特殊,例如数据字典数据获取。
在DML中,更改或删除数据是要用到当前读模式。
consistent gets:在一致读模式下所读的快数,包括从回滚段读的快数。 即通过不带for update的select 读的次数。
physical reads:物理读(从磁盘上读取数据块的数量)。
其产生的主要原因是:1.在数据库高速缓存中不存在这些块; 2.全表扫描; 3.磁盘排序。
redo size:DML生成的redo的大小。
sorts (memory):在内存执行的排序量。
sorts (disk):在磁盘执行的排序量。
2091 bytes sent via SQL*Net to client 从SQL*Net向客户端发送了2091字节的数据
416 bytes received via SQL*Net from client 客户端向SQL*Net发送了416字节的数据。
LOGIC IO(逻辑读次数)= db block gets + consistent gets
example:
1188 recursive calls--递归调用
0 db block gets
282 consistent gets
10 physical reads
0 redo size
3222 bytes sent via SQL*Net to client
514 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
23 sorts (memory)
0 sorts (disk)
33 rows processed
- 浏览: 72148 次
- 性别:
- 来自: 济南
文章分类
- 全部博客 (131)
- 自己思考的方式 (6)
- 开发工具优化 (1)
- 框架 (1)
- myeclipse设置报错 (1)
- myelipse的设置 (3)
- 设计模式 (0)
- oracle数据库函数 (1)
- javascript函数学习 (5)
- oracle数据库 (3)
- web html页面 (1)
- javascript原生查询节点的方法 (1)
- hibernate研究 (0)
- servlet (1)
- 既可以用相对路径.相对于这个请求的路径 /绝对路径 就是在这个项目的根目录 (转发) (1)
- db2数据库 (1)
- 环境搭建 (1)
- oracle-sql调优 (2)
- java (8)
- redis (2)
- Maven (5)
- springBoot (14)
- spring (5)
- 前端服务器 (1)
- tomcat (1)
- JFinal (1)
- 编程工具 (0)
- java基础 (5)
- mybatis (1)
- idea (0)
- docker-mysql (2)
- springCloud (1)
- MQ (2)
- 电脑硬件 (1)
- linux (2)
- hystrix (1)
相关推荐
当索引选择性较差或者表较小的时候,Oracle可能会选择全表扫描而非索引扫描。全表扫描虽然能够快速获取数据,但其也会带来较大的IO负载,尤其是在大型表中。因此,对全表扫描进行优化是提高数据库性能的重要方面之一...
1. **无任何限定条件**:当查询中没有`WHERE`子句,或者`WHERE`子句中的条件无法利用任何索引时,数据库系统通常会执行全表扫描。因为没有筛选条件,系统必须检查所有行以返回结果。 2. **部分索引匹配**:如果表上...
一、全表扫描(Full Table Scan) 全表扫描是 Oracle 访问路径的一种,最基本的访问方式。它扫描整个表,检查每一行记录,以找到匹配的记录。全表扫描通常用于以下情况: * 表非常小,扫描整个表的成本较低。 * ...
索引的工作原理类似于书籍的目录,可以极大地提高查询速度,避免全表扫描。在大数据量的环境中,没有索引的查询可能会变得极其缓慢。 分块索引,又称为多级索引或多级分区索引,是一种将大型数据集划分为多个较小的...
当在查询中对联合索引的第一个字段使用范围条件时,如`name > 'LiLei'`,MySQL可能会选择不使用该索引,因为它认为范围查询会导致大量行被扫描,导致回表操作效率低下,因此可能选择全表扫描。这可以通过`EXPLAIN`...
在索引的帮助下,数据库能够更快地定位到所需的数据行,减少了全表扫描的时间。 1. **索引概述** - 索引是为加速表中元组检索而设计的存储结构,通过索引可以加快查询速度,但每次更新数据时需要同步更新索引,...
2. 查询返回大量数据:如果查询条件匹配大部分或几乎全部表记录,全表扫描可能比索引扫描更为有效。 3. 并行查询:在并行查询模式下,全表扫描是常用方法。 4. 使用`FULL`提示:在SQL语句中明确指定`FULL`提示,会...
Oracle 表的扫描方式是指 Oracle 访问表的方法,包括全表扫描、索引扫描、索引范围扫描、索引唯一扫描等。这些扫描方式的选择取决于查询的条件、索引的类型和数据的分布。 一、全表扫描(Full Table Scans, FTS) ...
8. **避免全表扫描** - 索引在WHERE子句、JOIN操作和ORDER BY子句中发挥最大作用,避免在这些地方使用不带索引的列。 9. **避免索引失效的情况** - 使用 `!=`、`<>`、`NOT IN` 或 `NOT EXISTS` 可能导致索引失效...
没有索引时,数据库系统需要全表扫描来查找数据,这在数据量较大的情况下效率极低。通过创建索引,可以大大加快查询速度。 - **普通索引**:类似于按编号排序的抽屉,可以通过索引快速定位数据。但在进行复杂查询如...
- 查询优化涉及选择最佳执行计划,避免全表扫描,利用索引。 - 使用慢查询日志找出性能瓶颈。 - 调整数据库配置参数,如缓冲池大小、最大连接数等。 - 正确设计数据库架构,如分区、分片等高级技术。 - 优化...
通过索引,MySQL可以避免全表扫描,即逐行检查每一行记录是否符合查询条件,从而大大提高了数据检索的速度。例如,在一个名为`testIndex`的表中,当执行查询`SELECT * FROM testIndex WHERE vc_Name = 'erquan';`时...
在没有索引的情况下,数据库需要进行全表扫描,即逐行检查直到找到所需数据,这在数据量庞大的时候效率极低。有了索引,数据库可以直接定位到目标数据,从而极大地提高了查询速度。 二、索引类型 1. B-Tree索引:这...
1. 小型表的索引策略:对于数据量小、数据块少的表,全表扫描可能是更优选择。但如果这样的表经常被用作表连接中的内循环,那么建立索引是必要的。 2. 中大型表的索引策略:这些表通常包含事务处理的核心数据,例如...
- **背景**:在传统的索引访问路径中,如果索引列顺序与查询条件顺序不一致,则可能导致全表扫描或全索引扫描,这将大大降低查询效率。 - **解决方案**:索引跳跃扫描通过跳过不必要的索引条目,只访问那些可能...
在以下几种条件下,MySQL就会做全表扫描: 1>数据表是在太小了,做一次全表扫描比做索引键的查找来得快多了。当表的记录总数小于10且记录长度比较短时通常这么做。 2>没有合适用于 ON 或 WHERE 分句的索引字段。 3>...
- **索引快照扫描(Index Fast Full Scan)**:当索引的大小接近或小于表的大小时,Oracle可能会选择这种方式来替代全表扫描。 #### 四、总结 综上所述,Oracle提供了多种类型的索引来满足不同场景的需求。正确地...
无索引时,数据库需进行全表扫描,这会导致大量的I/O操作,降低查询效率。而正确创建的索引能显著提高检索速度。其次,系统的内存容量也至关重要,内存不足会导致数据访问变慢。此外,一次性存取大量数据会增加内存...