约束对效率的影响
2013-06-28 21:27
211 查看
约束对效率的影响 ========== sqlplus scott/tiger SQL> create table t1 pctfree 0 2 as 3 select * from dba_objects where 1=2; Table created. SQL> alter table T1 2 add constraint T1_PK primary key (OBJECT_ID); Table altered. select a.name, b.value from v$statname a, v$mystat b where a.statistic# = b.statistic# and a.name = 'redo size' and b.value > 0 SQL> SQL> set timing on 17:07:23 SQL> set time on 17:07:24 SQL> create table t2 pctfree 0 17:07:44 2 as 17:07:44 3 select 17:07:44 4 t.Owner , 17:07:44 5 t.Object_Name , 17:07:44 6 t.Subobject_Name , 17:07:44 7 rownum obid , 17:07:44 8 t.Data_Object_Id , 17:07:44 9 t.Object_Type , 17:07:44 10 t.Created , 17:07:44 11 t.Last_Ddl_Time , 17:07:44 12 t.Timestamp , 17:07:44 13 t.Status , 17:07:44 14 t.Temporary , 17:07:44 15 t.Generated , 17:07:44 16 t.Secondary 17:07:44 17 from (select * from dba_objects where rownum <=20000) t, 17:07:44 18 (select rownum rn from dba_objects where rownum <=200) d; Elapsed: 00:01:04.59 18:36:37 SQL> 18:36:37 SQL> 18:36:37 SQL> 18:36:37 SQL> 18:36:37 SQL> 18:42:08 SQL> select a.name, b.value 18:42:13 2 from v$statname a, v$mystat b 18:42:13 3 where a.statistic# = b.statistic# 18:42:13 4 and a.name = 'redo size' 18:42:13 5 and b.value > 0 18:42:15 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 410796268 Elapsed: 00:00:00.00 18:42:16 SQL> set autot traceonly statistics 18:42:42 SQL> INSERT INTO t1 SELECT * FROM t2; 4000000 rows created. Statistics ---------------------------------------------------------- 2013 recursive calls 583664 db block gets 190827 consistent gets 49685 physical reads 694767276 redo size == redo非常大,因为约束的索引 794 bytes sent via SQL*Net to client 683 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 4000000 rows processed Elapsed: 00:05:30.97 18:54:18 SQL> set autot off 18:54:23 SQL> select a.name, b.value 18:54:23 2 from v$statname a, v$mystat b 18:54:23 3 where a.statistic# = b.statistic# 18:54:23 4 and a.name = 'redo size' 18:54:23 5 and b.value > 0 18:54:24 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 1105563544 == 694767276+410796268 SQL> select 694767276+410796268 from dual; 694767276+410796268 ------------------- 1105563544 18:54:46 SQL> rollback; Rollback complete. 18:55:35 SQL> select a.name, b.value 18:56:17 2 from v$statname a, v$mystat b 18:56:17 3 where a.statistic# = b.statistic# 18:56:17 4 and a.name = 'redo size' 18:56:17 5 and b.value > 0 18:56:18 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 1151016204 ==1151016204-1105563544=45452660 ==我们看到INSERT的回滚非常小 ==因为INSERT的UNDO是DELETE,只要记录ROWID就行了 ==其实UNDO的实体就是空,加操作类型和行号 ==另外还有些空间操作 19:03:39 SQL> 19:03:39 SQL> commit; Commit complete. Elapsed: 00:00:00.02 19:05:44 SQL> set autot off 19:07:14 SQL> select sum(bytes) from dba_extents where segment_name = 'T1'; SUM(BYTES) ---------- 411107328 ==该表的大小,跟创建表语句时产生的REDO差不多大 ==这里表T1没有记录 Elapsed: 00:00:00.85 19:07:21 SQL> INSERT INTO T2 SELECT * FROM T2 WHERE ROWNUM <=20000; 20000 rows created. Elapsed: 00:00:00.17 19:08:38 SQL> commit; Commit complete. 18:55:35 SQL> select a.name, b.value 18:56:17 2 from v$statname a, v$mystat b 18:56:17 3 where a.statistic# = b.statistic# 18:56:17 4 and a.name = 'redo size' 18:56:17 5 and b.value > 0 18:56:18 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 1699354563 Elapsed: 00:00:00.01 19:08:43 SQL> ALTER TABLE t1 DISABLE PRIMARY KEY ; 19:09:13 2 Table altered. Elapsed: 00:00:05.31 19:09:18 SQL> select a.name, b.value 19:09:31 2 from v$statname a, v$mystat b 19:09:31 3 where a.statistic# = b.statistic# 19:09:31 4 and a.name = 'redo size' 19:09:31 5 and b.value > 0 19:09:32 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 1699658564 ==我们看到删除索引REDO非常小 19:09:33 SQL> TRUNCATE TABLE T1; Table truncated. Elapsed: 00:01:13.04 19:13:02 SQL> 19:13:02 SQL> select a.name, b.value 19:15:08 2 from v$statname a, v$mystat b 19:15:08 3 where a.statistic# = b.statistic# 19:15:08 4 and a.name = 'redo size' 19:15:08 5 and b.value > 0 19:15:09 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 1699756884 ==TRUNCATE有很少的REDO SQL> INSERT INTO t1 SELECT * FROM t2; 4020000 rows created. Elapsed: 00:03:11.16 Execution Plan ---------------------------------------------------------- 0 INSERT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'T2' Statistics ---------------------------------------------------------- 80 recursive calls 200566 db block gets 198588 consistent gets 44039 physical reads 444366592 redo size 785 bytes sent via SQL*Net to client 683 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 4020000 rows processed commit; ==我们看到DISABLE主键后,REDO少了一小半,这是维护索引产生的 ==而且现在有20000条违规数据。 SQL> ALTER TABLE t1 ENABLE NOVALIDATE PRIMARY KEY; ALTER TABLE t1 ENABLE NOVALIDATE PRIMARY KEY * ERROR at line 1: ORA-02437: cannot validate (SYS.T1_PK) - primary key violated ==ENABLE NOVALIDATE约束需要非唯一性索引来实现 Elapsed: 00:00:09.42 SQL> SQL> CREATE INDEX NOUNIQ_IDX ON T1 (OBJECT_ID); Index created. Elapsed: 00:01:05.99 ==创建非唯一性索引 SQL> select a.name, b.value 2 from v$statname a, v$mystat b 3 where a.statistic# = b.statistic# 4 and a.name = 'redo size' 5 and b.value > 0 6 / NAME VALUE ---------------------------------------------------------------- ---------- redo size 524147536 ==明显比694767276小 SQL> ALTER TABLE t1 ENABLE NOVALIDATE PRIMARY KEY; Table altered. Elapsed: 00:00:00.02 SQL> ALTER TABLE t1 ENABLE PRIMARY KEY; ALTER TABLE t1 ENABLE PRIMARY KEY * ERROR at line 1: ORA-02437: cannot validate (SYS.T1_PK) - primary key violated Elapsed: 00:00:17.75 ==ENABLE 语句默认就是ENABLE VALIDATE,所以不允许老数据有违反约束的数据存在 SQL> delete from t1 where rowid in ( select rid from ( select rowid rid , row_number() over (partition by OWNER , OBJECT_NAME , SUBOBJECT_NAME , OBJECT_ID , DATA_OBJECT_ID , OBJECT_TYPE , d6f3 CREATED , LAST_DDL_TIME , TIMESTAMP , STATUS , TEMPORARY , GENERATED , SECONDARY order by OBJECT_ID) rn from t1 ) where rn <> 1 ) ; 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 20000 rows deleted. Elapsed: 00:02:35.80 Execution Plan ---------------------------------------------------------- 0 DELETE STATEMENT Optimizer=CHOOSE 1 0 DELETE OF 'T1' 2 1 NESTED LOOPS 3 2 VIEW OF 'VW_NSO_1' 4 3 SORT (UNIQUE) 5 4 VIEW 6 5 WINDOW (SORT) 7 6 TABLE ACCESS (FULL) OF 'T1' 8 2 TABLE ACCESS (BY USER ROWID) OF 'T1' Statistics ---------------------------------------------------------- 48 recursive calls 82249 db block gets 70062 consistent gets 131116 physical reads 11091288 redo size 799 bytes sent via SQL*Net to client 1421 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 2 sorts (memory) 1 sorts (disk) 20000 rows processed commit; ==删除违反约束的数据 SQL> ALTER TABLE t1 ENABLE PRIMARY KEY; Table altered. Elapsed: 00:00:24.47 复杂索引和约束结合测试 ============= 我们知道约束其实是索引来实现的,那我们能不能来创建一个复杂和特殊的索引来实现约束功能呢 SQL> conn scott/tiger 已连接。 SQL> drop table t01; drop table t01 * ERROR 位于第 1 行: ORA-00942: 表或视图不存在 SQL> create table t01 2 (a int, 3 b int, 4 c varchar2(1) not null); 表已创建。 SQL> create unique index t01_idx on t01 2 (case when c <> 'w' then a end, 3 case when c <> 'w' then b end); case when c <> 'w' then b end) * ERROR 位于第 3 行: ORA-01031: 权限不足 SQL> conn /as sysdba 已连接。 SQL> grant query rewrite to scott; 授权成功。 SQL> conn scott/tiger 已连接。 SQL> create unique index t01_idx on t01 2 (case when c <> 'w' then a end, 3 case when c <> 'w' then b end); case when c <> 'w' then b end) * ERROR 位于第 3 行: ORA-01536: 超出表空间'SYSTEM'的空间限量 ==非SYS用户不要将默认表空间设置在SYSTEM里 SQL> conn /as sysdba 已连接。 SQL> grant resource to scott; 授权成功。 ==RESOURCE角色拥有完全空间资源的权限,对于测试用户要注意空间使用安全 SQL> conn scott/tiger 已连接。 SQL> create unique index t01_idx on t01 2 (case when c <> 'w' then a end, 3 case when c <> 'w' then b end); 索引已创建。 ==我们创建的这个索引的含义是 ==当c不等于'w'时,a和b字段的联合unique索引 下面对此进行验证 SQL> insert into t01 values (1,1,'w'); 已创建 1 行。 SQL> insert into t01 values (1,1,'w'); 已创建 1 行。 SQL> insert into t01 values (1,1,'x'); 已创建 1 行。 SQL> insert into t01 values (1,1,'y'); insert into t01 values (1,1,'y') * ERROR 位于第 1 行: ORA-00001: 违反唯一约束条件 (SCOTT.T01_IDX)
相关文章推荐
- 影响仿真效率的随机约束写法(多层foreach)和随机数据bit位宽表示
- 黑马程序员之SQL 学习笔记:非空约束对数据更新的影响
- 在SqlServer里面没有索引的情况下 where子句的条件顺序对查询效率有影响吗?
- 浅谈数据对齐对CPU效率的影响
- 数据库使用NULL对于效率有什么影响
- JAVA编程中影响运行效率的一些因素
- 多余的Using Namespaces或引用会影响程序的执行效率么?(转)
- Try Catch到底影响了程序多少效率?
- 通过tomcat插件+jndi配置,避免tomcat热重启影响开发效率
- 数据绑定方式影响执行效率
- 设计select语句时影响效率查询的15个情况
- 时钟频率对程序效率影响测试(Platform: ARM ZYNQ 7000 ZP20 Board)
- 去掉影响效率的where 1=1
- 影响查询效率的select语句
- 在企业级开发中使用Try...Catch...会影响效率吗?
- 到底是什么在影响我们的开发效率?
- as3 中trace() 函数对效率的影响
- 【Android Training - Connectivity】优化下载的效率[Lesson 1 - 看无线电波如何影响网络操作]
- 数据库主键设定对查询效率的影响
- Console输出影响程序效率