[20120726]建立约束和使用绑定变量.txt

简介: [20120726]建立约束和使用绑定变量.txt昨天检查awr报表文件,发现:select condition from cdef$ where rowid=:1这条语句执行次数很高,因为查询的where条件使用rowid=:1,应该不会是用户的程序执行,而是某种递归的调用。
[20120726]建立约束和使用绑定变量.txt

昨天检查awr报表文件,发现:
select condition from cdef$ where rowid=:1
这条语句执行次数很高,因为查询的where条件使用rowid=:1,应该不会是用户的程序执行,而是某种递归的调用。

直接在google输入select condition from cdef$ where rowid=:1,发现如下链接:
http://jonathanlewis.wordpress.com/2006/12/14/constraints-inserts-and-bind/

原来我当时偷懒,直接使用toad导出insert语句导入别的数据库,这些insert语句没有使用绑定变量,而且正好这个表有个出生日期。我做了限制,限制出生日期必须大于'1900/1/1',还有其他2个约束,一共3个约束。

按照链接的介绍当没有绑定变量插入时,insert时每次都需要读取sys.cdef$的信息:

    Oracle doesn't keep long columns cached in the dictionary cache (rowcache) so every time it optimises a new statement
that uses a check constraint (and the condition column is a long column) it has to re-read the constraint definition from
the database – just as it does with the view definition when you optimise a statement that uses a view.
--我的测试对定义not null字段不进行再次检查。

自己在测试机器如下:

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> create table t ( id number check (id > 0), name varchar2(10) not null); 
SQL> column condition format a30
SQL> select obj#,condition from sys.cdef$ where obj# in (select object_id from dba_objects where wner=user and object_name='T');
      OBJ# CONDITION
---------- ------------------------------
    101266 "NAME" IS NOT NULL
    101266 id > 0

--可以发现存在两个约束在表T上。

2.测试:
alter system flush shared_pool;
SQL> select sql_text,executions from v$sql where sql_text like 'select condition from cdef$ where rowid=:1%';
no rows selected

begin
 for i in 1..1000 loop 
  execute immediate 'insert into t values(' || i || ',''test'')'; 
 end loop; 
end; 
/

SQL> column sql_text format a60
SQL> select sql_text,executions from v$sql where sql_text like 'select condition from cdef$ where rowid=:1%';
SQL_TEXT                                                     EXECUTIONS
------------------------------------------------------------ ----------
select condition from cdef$ where rowid=:1                         1001

--可以发现select condition from cdef$ where rowid=:1执行了1001次。
--再次执行上面过程(注意我修改了循环的开始与结束值,如果不改,前面的insert sql语句已经在shared pool,
select condition from cdef$ where rowid=:1%的executions次数应该不存在变化)!

begin
 for i in 1001..2000 loop 
  execute immediate 'insert into t values(' || i || ',''test'')'; 
 end loop; 
end; 
/

SQL> select sql_text,executions from v$sql where sql_text like 'select condition from cdef$ where rowid=:1%';
SQL_TEXT                                                     EXECUTIONS
------------------------------------------------------------ ----------
select condition from cdef$ where rowid=:1                         2001

--可以发现执行次数从1001=>2001.

3.可以发现如果insert的语句不使用绑定变量,在遇到有约束的字段就会执行1次select condition from cdef$ where rowid=:1%。
而对于像name varchar2(10) not null的约束仅仅访问1次。

再次修改约束条件,加入如下:
alter table t add constraint name_is_not_null check (name is not null);

SQL> select obj#,condition from sys.cdef$ where obj# in (select object_id from dba_objects where wner=user and object_name='T');
      OBJ# CONDITION
---------- ------------------------------
    101266 "NAME" IS NOT NULL
    101266 id > 0
    101266 name is not NULL

执行如下:
rollback;
begin 
 for i in 2001..3000 loop 
  execute immediate 'insert into t values(' || i || ',''test'')'; 
 end loop; 
end; 
/

SQL> select sql_text,executions from v$sql where sql_text like 'select condition from cdef$ where rowid=:1%';
SQL_TEXT                                                     EXECUTIONS
------------------------------------------------------------ ----------
select condition from cdef$ where rowid=:1                         4001

--可以发现执行次数从2001=>4001.增加了2000次。

4.改用绑定变量看看结果如何:
SQL> alter session set cursor_sharing = force ;

rollback;
begin 
 for i in 3001..4000 loop 
  execute immediate 'insert into t values(' || i || ',''test'')'; 
 end loop; 
end; 
/

SQL> select sql_text,executions from v$sql where sql_text like 'select condition from cdef$ where rowid=:1%';
SQL_TEXT                                                     EXECUTIONS
------------------------------------------------------------ ----------
select condition from cdef$ where rowid=:1                         4003

--可以发现执行次数从4001=>4003.仅仅增加2次。

总结:
又给使用绑定变量的使用找到一个好的理由,虽然遇到这种情况的不多,不过像insert语句,在表有主键的情况下,不可能一条语句执行多次!
一般在程序没有使用绑定的情况下,我的建议都是先修改有DML语句的地方,因为这些语句重复执行的可能性很小!



目录
相关文章
|
SQL Oracle 关系型数据库
数据库必知词汇:检查约束(CHECK)
CHECK 约束用于限制列中的值的范围,限制范围取决于<Sql表达式>。如果对单个列定义 CHECK 约束,那么该列只允许特定的值。如果对一个表定义 CHECK 约束,那么此约束会基于行中其他列的值在特定的列中对值进行限制。
849 0
|
4月前
|
SQL Oracle 关系型数据库
SQL FOREIGN KEY 约束- 保障表之间关系完整性的关键规则
SQL FOREIGN KEY 约束用于防止破坏表之间关系的操作。FOREIGN KEY 是一张表中的字段(或字段集合),它引用另一张表中的主键。具有外键的表称为子表,具有主键的表称为被引用表或父表。
87 0
SQL FOREIGN KEY 约束- 保障表之间关系完整性的关键规则
|
10月前
Tidyverse| XX_join :多个数据表(文件)之间的各种连接
Tidyverse| XX_join :多个数据表(文件)之间的各种连接
|
SQL
SQL Server 导入excel时“该值违反了该列的完整性约束”错误
SQL Server 导入excel时“该值违反了该列的完整性约束”错误 这个问题看似高大上,仔细分析了一下,ID列怎么会有重复呢? 原来是有很多空行呀!!! 所以导入excel时一定要注意空行的问题! 没有空行才是对的!!!
5438 0
|
SQL 关系型数据库 MySQL
(解释文)My SQL中主键为0和主键自排约束的关系
  上一篇我们说了关于自排如果主键是0的问题,在这里我搞清楚了原因,导致这种情况是因为在SQL中对自排设置了初始值:      从这里可以看到这两个变量一个是自增的初始值,一个是增量,这里都是1,所以在设置自增的时候会把那个字段原来存在的所有0变成从1开始的步长为1的等差数列。
979 0
|
数据库
关于T-SQL中exists或者not exists子查询的“伪优化”的做法
原文:关于T-SQL中exists或者not exists子查询的“伪优化”的做法   问题起源 在使用t-sql中的exists(或者not exists)子查询的时候,不知道什么时候开始,发现一小部分人存在一种“伪优化”的一些做法,并且向不明真相的群众传递这一种写法“优越性”,实在看不下去,无法传递给他人正确的指导思想无可厚非,给他人传递错误的思想或者说误导人倒是一种罪恶。
1116 0
|
Oracle 关系型数据库
Oracle 查询对应表所有字段名称,可排除不想要的字段
由于Oracle varchar类型长度限制为4000 ,以下方法仅支持查询字段拼接后长度小于等于4000 第一种方法 select wm_concat(column_name) from user_tab_cols where table_name = upper(...
1447 0
|
关系型数据库 Oracle Linux
[20170516]nvl与非NULL约束2.txt
[20170516]nvl与非NULL约束2.txt --//接着上午的测试看看COALESCE看看过滤的情况. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION      ...
922 0
|
SQL Oracle 关系型数据库
[20170516]nvl与非NULL约束.txt
[20170516]nvl与非NULL约束.txt --前几天做的测试http://blog.itpub.net/267265/viewspace-2137853/,实际上差异没有这个大,因为第2个多数是常量.
854 0
|
关系型数据库 索引
[20170427]唯一索引与约束注意的地方.txt
[20170427]唯一索引与约束注意的地方.txt --//昨天看书Apress.Expert.Oracle.Indexing.and.Access.Paths.Maximum.
921 0

热门文章

最新文章

相关实验场景

更多