- 浏览: 126439 次
- 来自: ...
最近访客 更多访客>>
文章分类
最新评论
-
dwangel:
给messageSource设置属性
<property ...
Spring i18n的better practice(相对于appfuse) -
dwangel:
spring 的message tag有一个属性text,可以 ...
Spring i18n的better practice(相对于appfuse) -
sn201:
awk高级篇
有问题啊!有问题!有问题!有问题!有问题!
i ...
awk文本处理总结(入门,中级,高级) -
happy_javaboy:
...
Log4j日志管理系统简单使用说明
转自:http://tb.blog.csdn.net/TrackBack.aspx?PostId=1729625
1、各种索引的创建方法
(1)*tree索引
create index indexname on tablename(columnname);
(2)反向索引
create index indexname on tablename(columnname) reverse;
(3)降序索引
create index indexname on tablename(columnname DESC);
(4)位图索引
create BITMAP index indexname on tablename(columnname);
(5)函数索引
create index indexname on tablename(functionname(columnname));
创建索引后要分析才能使用
analyze table test compute statistics for table for all indexed columns for all indexes;
analyze index test validate structure;
select name,lf_rows from index_stats;用这条语句可以查询保存了多少条索引
analyze index test compute statistics;
从字面理解validate structure 主要在于校验对象的有效性. compute statistics在于统计相关的信息..
查询索引
select index_name,index_type from user_indexes where table_name='TEST';
2、打开autotrace功能
执行$ORACLE_HOME/rdbms/admin/utlxplan.sql和$ORACLE_HOME/sqlplus/admin/plustrce.sql
然后给相关用户授予plustrace角色,然后这些用户就可以使用autotrace功能了
3、无效索引
(1)类型不匹配
create table test(a varchar(2),b number);
insert into test values('1',1);
create index test_index on test(a);
analyze table test compute statistics for table for all indexed columns for all indexes;
set autotrace on;
类型匹配的情况
select /*+ RULE */ * from test where a='1';
A B
-- ----------
1 1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX' (NON-UNIQUE) 使用了索引
类型不匹配的情况
select /*+ RULE */ * from test where a=1;
A B
-- ----------
1 1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (FULL) OF 'TEST' 选择了全表扫描
(2)条件包含函数但没有创建函数索引
alter system set QUERY_REWRITE_ENABLED=true;
alter system set query_rewrite_integrity=enforced;
insert into test values('a',2);
select /*+ RULE */ * from test where upper(a) = 'A';
A B
-- ----------
a 2
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (FULL) OF 'TEST'
由于没有创建函数索引,所以选择全表扫描
create index test_index_fun on test(upper(a));
analyze table test compute statistics for table for all indexed columns for all indexes;
select /*+ RULE */ * from test where upper(a) = 'A';
A B
-------------------------------------------------- ----------
a 2
a 3
a 4
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (FULL) OF 'TEST'
虽然创建了函数索引,但由于工作于RBO模式,所以函数索引没用,选择了全表扫描
select * from test where upper(a) = 'A';
A B
-------------------------------------------------- ----------
a 2
a 3
a 4
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=9)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=1 Byt
es=9)
2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX_FUN' (NON-UNIQUE) (Cos
t=1 Card=1)
当函数索引工作于CBO模式下,选择了基于函数的索引,上面创建的索引函数TEST_INDEX_FUN已经用到
(3)符合索引中的前导列没有被作为查询条件
create index test_index_com on test(a,b);
select /*+ RULE */ * from test where a = '1';
A B
-- ----------
1 1
前导列a作为了查询条件,但由于之前创建了a的索引,所以使用了TEST_INDEX而没有使用test_index_com
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX' (NON-UNIQUE)
select /*+ RULE */ * from test where b = '1';
A B
-- ----------
1 1
2 1
3 1
4 1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (FULL) OF 'TEST'
前导列a没有作为查询条件,所以选择全部扫描
select /*+ RULE */ * from test where b = '1' and a= '1';
A B
-- ----------
1 1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 INDEX (RANGE SCAN) OF 'TEST_INDEX_COM' (NON-UNIQUE)
前导列a作为了查询条件,使用了索引
(4)CBO模式下选择的行数比例过大,优化器选择全表扫描
declare
i number;
j number;
begin
for i in 1 .. 10 loop
for j in 1 .. 10000 loop
insert into test values(to_char(j),i);
end loop;
end loop;
end;
/
declare i number;
begin
for i in 1 .. 100 loop
insert into test values(to_char(i),i);
end loop;
end;
/
SQL> select count(*) from test;
COUNT(*)
----------
200000
select * from test where a = '1';
已选择10000行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=27 Card=9333 Bytes=7
4664)
1 0 TABLE ACCESS (FULL) OF 'TEST' (Cost=27 Card=9333 Bytes=746
64)
比例过大,选择全表扫描
select * from test where a = '99';
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=2 Bytes=16)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=2 Card=2 Byt
es=16)
2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX' (NON-UNIQUE) (Cost=1
Card=2)
比例小,选择索引
select /*+ RULE */ * from test where a = '1';
已选择10000行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'
2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX' (NON-UNIQUE)
如果指定为RBO优化器,肯定就用索引了
(5)在CBO模式下表很久没分析,表的增长明显,优化器采取了全表扫描
(6)索引条件中使用了<>、!=、not\not in、not like等操作符,导致查询不使用索引
先做一个测试在一个表中插入130万条数据,其中不等于1的数据有30万条,以下是几种语句执行的结果
序号 语句 时间 代价
1 select * from test where b<>1; 00: 00: 03.04 398
2 select * from test where b not like 1; 00: 00: 03.03 398
3 select * from test where b !=1; 00: 00: 03.01 398
4 select * from test where b not in(1); 00: 00: 03.00 398
5 select * from test where b<1 union select * from test where b>1; 00: 00: 03.01 264
6 select * from test where b<1 union all select * from test where b>1; 00: 00: 02.09 132
7 select * from test where b<1 or b>1; 00: 00: 02.08 96
从以上可以看出最优化的语句是7,在查询过程中使用索引的有5、6、7
所以,如果建立了索引,在语句中尽量不要使用<>、!=、not、not in、not like操作,如果非要使用,请尽量用or和union操作替换
(7)索引对空值的影响
我们首先做一些测试数据:
SQL> create table t(x int, y int);
请注意,这里我对表t做了一个唯一(联合)索引:
SQL> create unique index t_idx on t(x,y);
SQL> insert into t values(1,1);
SQL> insert into t values(1,NULL);
SQL> insert into t values(NULL,1);
SQL> insert into t values(NULL,NULL);
SQL> commit;
下面我们分析一下索引:
SQL> analyze index t_idx validate structure;
SQL> select name,lf_rows from index_stats;
NAME LF_ROWS
------------------------------ ----------
T_IDX 3
然后,我们就可以看到,当前的索引中仅仅保存了3行数据。
请注意,上面我们插入并提交了四行数据。
所以,这里就有一个结论:
Oracle的索引不保存该索引包含的列中全部为空的行。
这同时也带来个好处,但当一个表中的某一列大部分为空值,至少90%以上是空值的时候,就可以为该列建立索引。
比如该表为t,该列为x
select * from t where x is null;
此时会选择全表扫描
select * from t where x=1;
此时就会使用索引,而且索引中不保存值为空的行,所以索引中只有10%左右的行,因此在这10%的行中找出x=1的行比在全表中找出x=1的行要快的多
我们继续插入数据,现在再插入几行全部为空的行:
SQL> insert into t values(NULL,NULL);
SQL> insert into t values(NULL,NULL);
我们看到这样的插入,居然没有违反前面我们设定的唯一约束(unique on t(x,y)),
所以,这里我们又得出一个结论:
Oracle认为 NULL<>NULL ,进而 (NULL,NULL)<>(NULL,NULL)
换句话说,Oracle认为空值(NULL)不等于任何值,包括空值也不等于空值。
我们看到下面的插入会违反唯一约束(DEMO.T_IDX),这个很好理解了,因为它不是全部为空的值,即它不是(NULL,NULL),只有全部为空的行才被认为是不同的行:
SQL> insert into t values(1,null);
ORA-00001: 违反唯一约束条件 (DEMO.T_IDX)
SQL> insert into t values(null,1);
ORA-00001: 违反唯一约束条件 (DEMO.T_IDX)
SQL>
请看下面的例子:
SQL> select x,y,count(*) from t group by x,y;
X Y COUNT(*)
----- -------- ----------
3
1 1
1 1
1 1 1
Executed in 0.03 seconds
SQL> select x,y,count(*) from t where x is null and y is null group by x,y;
X Y COUNT(*)
---- ------- ----------
3
Executed in 0.01 seconds
SQL>
SQL> select x,y,count(*) from t group by x,y having count(*)>1;
X Y COUNT(*)
------ -------------------- ----------
3
Executed in 0.02 seconds
SQL>
可以看见,完全为空的行有三行,这里我们又可以得出一个结论:
oracle在group by子句中认为完全为空的行是相同的行
换句话说,在group by子句中,oracle认为(NULL,NULL)=(NULL,NULL)
SQL> select * from t where x is null;
X Y
---------- ----------
1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=4 Bytes=8)
1 0 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=4 Bytes=8)
SQL> select * from t where x=1;
X Y
---------- ----------
1 1
1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=2 Bytes=4)
1 0 INDEX (RANGE SCAN) OF 'T_IDX' (UNIQUE) (Cost=1 Card=2 Byte
s=4)
从以上可以看出,在使用IS NULL 和 IS NOT NULL条件的时候,Oracle不使用索引
那么我们如何使用空值的比较条件呢?
首先,尽量不在前导列上使用空值,其次我们在创建表的时候,为每个列都指定为非空约束(NOT NULL),并且在必要的列上使用default值
8、不要为所有的列建立索引
我们知道,建立索引是为了提高查询的效率,但是同时也应该注意到,索引增加了对DML操作(insert, update, delete)的代价,而且,一给中的索引如果太多,那么多数的索引是根本不会被使用到的,而另一方面我们维护这些不被使用的所以还要大幅度降低系统的性能。所以,索引不是越多越好,而是要恰到好处的使用。
比如说,有些列由于使用了函数,我们要使用已有的索引(如一些复合索引)是不可能的,那么就必须建立单独的函数索引,如果说这个函数索引很少会被应用(仅仅在几个特别的sql中会用到),我们就可以尝试改写查询,而不去建立和维护那个函数索引,例如:
1,trunc函数
SQL> select empno,ename,deptno from emp where trunc(hiredate)='2004-01-01';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF 'EMP'
将上面的查询转换为:
SQL> select empno,ename,deptno from emp
2 where hiredate >= to_date('2004-01-01','yyyy-mm-dd')
3 and hiredate<to_date('2004-01-01','yyyy-mm-dd')+0.999;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'
2 1 INDEX (RANGE SCAN) OF 'EMP_ID3' (NON-UNIQUE)
2,to_char函数
SQL> select empno,ename,deptno from emp
2 where to_char(hiredate,'yyyy-mm-dd')='2003-09-05';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF 'EMP'
SQL> select empno,ename,deptno from emp
2 where hiredate=to_date('2003-09-05','yyyy-mm-dd');
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'
2 1 INDEX (RANGE SCAN) OF 'EMP_ID3' (NON-UNIQUE)
3,substr函数
SQL> select dname from dept where substr(dname,1,3)='abc';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF 'DEPT'
SQL> select dname from dept where dname like 'abc%';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 INDEX (RANGE SCAN) OF 'DEPT_ID1' (NON-UNIQUE)
通常,为了均衡查询的效率和DML的效率,我们要仔细的分析应用,找出来出现频率相对较多、字段内容较少(比如varchar2(1000)就不适合建立索引,而varchar2(10)相对来说就适合建立索引)的列,合理的建立索引,比如有时候我们希望建立复合索引,有时候我们更希望建立单键索引。
发表评论
-
Oracle性能调优-优化排序操作
2010-08-07 11:37 1182关于Oracle 10g性能方面,谈论最多的就是新的自动工作负 ... -
Oracle中的外连接简单介绍
2006-08-11 09:53 552在讲外连接之前,先举例介绍内连接,也就是一般的相等连接。 s ... -
SQLServer和Oracle常用函数对比
2006-08-11 09:55 359SQLServer和Oracle是大家经常用到的数据库,在此感 ... -
Oracle SQL 内置函数大全
2006-08-24 10:37 550... -
Oracle PL/SQL入门之慨述
2006-09-05 21:14 534一、PL/SQL出现的目的 结构化查询语言(Structur ... -
Oracle:PL/SQL 中如何使用Array
2006-09-18 20:41 644因为在PL/SQL 中并没有数 ... -
java高级编程:基于JNDI的应用开发
2006-10-02 18:08 592基于JNDI的应用开发 ... -
开源技术之Tomcat数据源配置总结
2006-10-06 14:55 604成功配置环境Tomcat5.0.28+ ... -
Java调用存储过程
2006-10-11 14:22 623摘要:本文阐述了怎 ... -
JNDI配置原理详解
2006-10-11 14:55 677最近写书,写到JNDI,到 ... -
ORACLE SEQUENCE的简单介绍
2006-12-28 11:01 750在oracle中sequence就是所 ... -
oracle系统表查询
2007-07-30 17:03 574数据字典dict总是属于Ora ... -
JOB
2007-09-04 17:42 446var jobno number begin sys.db ... -
网络收集:PLSQL常用方法汇总
2007-10-18 14:03 740网络收集:PLSQL常用方法汇总 在SQLPLUS下,实现中- ... -
oracle pl/sql 创建同义词
2007-10-24 11:05 1367CREATE OR REPLACE Procedure Cre ... -
ORACLE索引与高性能SQL介绍
2007-11-21 15:05 491转自:http://blog.csdn.net/annicyb ... -
oracle动态游标的简单实现方法
2008-05-27 09:17 768下面就是例子程序 --明细表打印予处理 通用报表: pro ... -
Oracle触发器
2008-05-27 15:22 632是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用 ... -
Oracle体系结构之-Oracle中各种名称
2008-05-31 15:18 796一、数据库名 数据 ... -
数据库设计准则(第一、第二、第三范式说明)
2009-01-04 11:53 627I、关系数据库设计范式介绍 1.1 第一范式(1NF)无重复的 ...
相关推荐
“db2advis”是一个用于分析和优化数据库中SQL语句执行计划的工具。它可以针对具体的SQL语句或一组SQL语句提供优化建议,包括但不限于创建新的索引、调整现有索引以及建议是否使用Materialized Query Tables (MQTs) ...
本篇文章将深入探讨Oracle中的B*Tree索引、反向索引、降序索引、位图索引和函数索引。 1. **B*Tree索引**: - B*Tree索引是Oracle中最常见的索引类型,其结构类似于二叉树,可以高效地处理高基数数据列,即具有...
4. **位图索引**:位图索引适合于低基数和分析性查询(OLAP),尤其是用于关联少量数据行的情况。它使用位图来表示数据行与索引项的关系,每个位代表一行。对于多列组合索引或选择性较低的列,位图索引能提供高效的...
### MySQL索引分析与优化详解 #### 一、引言 在现代数据库管理系统中,索引扮演着极其重要的角色。合理的索引设计不仅能显著提升查询性能,还能优化数据的存储结构,进而提高整个系统的响应速度。本文将深入探讨...
"MySQL索引分析及优化" 索引是数据库中提高速度的一个关键因素。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。索引的使用可以大幅度地提高查询速度,减少数据库的...
MySQL索引分析和优化是数据库管理中的重要环节,它直接影响到数据查询的速度和数据库的性能。索引可以被看作是数据库中的一种特殊文件,它按照特定的规则组织,允许数据库快速定位到所需的数据行。 首先,我们来看...
因此,合理地设计索引和定期分析其性能是非常重要的。 8. **索引优化**:MySQL提供了`EXPLAIN`关键字,可以帮助分析查询执行计划,了解是否正确使用了索引。通过`EXPLAIN`,可以发现查询是否进行了全表扫描、是否...
### MySQL索引分析和优化深度解析 #### 引言 MySQL数据库系统中,索引扮演着至关重要的角色,尤其在大数据量的环境下,其对查询性能的影响不可小觑。索引能够极大地加速数据检索速度,减少数据库服务器的负载,...
Sqlserver索引分析,Sqlserver索引缺失,Sqlserver索引建议
MySQL数据库中的索引是提升查询性能的关键工具,它的工作原理和设计细节对于数据库管理员和开发者来说至关重要。...同时,索引的维护也是数据库管理的重要部分,包括定期分析和优化索引,以确保数据库的高效运行。
2. 避免索引失效:使用函数、IN操作符、NOT操作符等可能导致索引失效,应尽量让索引列直接参与比较。 3. 选择正确的JOIN策略:了解不同JOIN类型的性能差异,如NLJOIN、HASH JOIN和MERGE JOIN。 五、实际应用中的...
### SQL Server 2005 索引碎片分析与解决方法 #### 一、索引碎片的概念 在SQL Server 2005中,索引是提高查询效率的重要手段之一。然而,随着数据的增删改查操作,索引可能会出现碎片化现象。碎片化的索引会导致...
在实践中,聚集索引和非聚集索引的使用规则很容易被忽视或不能根据实际情况进行综合分析。例如,主键就是聚集索引是一种误区。虽然 SQL SERVER 默认是在主键上建立聚集索引的,但这并不意味着主键一定是聚集索引。 ...
这种可视化方式对于数据分析和问题排查非常有帮助,尤其在处理大量数据时,能够提高工作效率。 在实际开发中,结合如Excel或数据可视化库(如Python的Pandas或JavaScript的D3.js),开发者可以创建交互式报告,...
5. 结果导出:分析结果可以导出为各种格式,便于进一步的分析和分享。 三、histcite的优势 1. 提高效率:histcite节省了人工查找和整理文献引用关系的时间,使科研工作更加高效。 2. 深度分析:软件提供强大的数据...
MongoDB是一种流行的NoSQL数据库,它的索引机制与传统的关系型数据库类似,旨在提升查询和排序的速度。...同时,定期分析查询性能和索引使用情况,根据需求调整索引策略,也是数据库管理的重要环节。
本文将深入探讨数据库中的非聚集索引、聚集索引以及索引模式的概念,并分析它们之间的区别。 首先,让我们了解一下**非聚集索引**。非聚集索引在数据库中不按照数据的实际物理顺序存储。每个非聚集索引条目包含键值...