[20120726]建立約束和使用繫結變數.txt
[20120726]建立約束和使用繫結變數.txt
昨天檢查awr報表檔案,發現:
select condition from cdef$ where rowid=:1
這條語句執行次數很高,因為查詢的where條件使用rowid=:1,應該不會是使用者的程式執行,而是某種遞迴的呼叫。
直接在google輸入select condition from cdef$ where rowid=:1,發現如下連結:
原來我當時偷懶,直接使用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欄位不進行再次檢查。
自己在測試機器如下:
--可以發現存在兩個約束在表T上。
2.測試:
--可以發現select condition from cdef$ where rowid=:1執行了1001次。
--再次執行上面過程(注意我修改了迴圈的開始與結束值,如果不改,前面的insert sql語句已經在shared pool,
--可以發現執行次數從1001=>2001.
3.可以發現如果insert的語句不使用繫結變數,在遇到有約束的欄位就會執行1次select condition from cdef$ where rowid=:1%。
而對於像name varchar2(10) not null的約束僅僅訪問1次。
再次修改約束條件,加入如下:
--可以發現執行次數從2001=>4001.增加了2000次。
4.改用繫結變數看看結果如何:
--可以發現執行次數從4001=>4003.僅僅增加2次。
總結:
又給使用繫結變數的使用找到一個好的理由,雖然遇到這種情況的不多,不過像insert語句,在表有主鍵的情況下,不可能一條語句執行多次!
一般在程式沒有使用繫結的情況下,我的建議都是先修改有DML語句的地方,因為這些語句重複執行的可能性很小!
昨天檢查awr報表檔案,發現:
select condition from cdef$ where rowid=:1
這條語句執行次數很高,因為查詢的where條件使用rowid=:1,應該不會是使用者的程式執行,而是某種遞迴的呼叫。
直接在google輸入select condition from cdef$ where rowid=:1,發現如下連結:
原來我當時偷懶,直接使用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語句的地方,因為這些語句重複執行的可能性很小!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-737207/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20171231]PLSQL使用繫結變數.txtSQL變數
- PLSQL使用繫結變數SQL變數
- 【優化】使用繫結變數 OR 不使用繫結變數,這不是問題!優化變數
- 【最佳化】使用繫結變數 OR 不使用繫結變數,這不是問題!變數
- 繫結變數變數
- [20170929]& 代替冒號繫結變數.txt變數
- [20160706]like % 繫結變數.txt變數
- 繫結變數和BIND PEEKING變數
- SQL Developer中使用繫結變數SQLDeveloper變數
- 繫結變數的使用範圍變數
- 關於繫結變數的使用變數
- 使用繫結變數的一點總結!變數
- 繫結變數之繫結變數窺探(Bind Peeking)變數
- Oracle 繫結變數Oracle變數
- 繫結變數和cursor_sharing變數
- 【sql調優】使用繫結變數(二)SQL變數
- 【sql調優】使用繫結變數(一)SQL變數
- 繫結變數優缺點、使用、繫結變數窺探、 Oracle自適應共享遊標變數Oracle
- [20180930]in list與繫結變數個數.txt變數
- [20180912]PLSLQ與繫結變數.txt變數
- [20180930]in list與繫結變數.txt變數
- 如何在對in操作使用變數繫結(轉)變數
- 在繫結變數下使用outline變數
- PLSQL中使用繫結變數的語法SQL變數
- java程式裡怎麼使用繫結變數Java變數
- SQL使用繫結變數,測試例項。SQL變數
- 檢視繫結變數變數
- 繫結變數窺測變數
- Oracle之繫結變數Oracle變數
- 關於繫結變數變數
- [20210120]in list與繫結變數個數.txt變數
- [20160224]繫結變數的分配長度.txt變數
- [20150812]關於抓取繫結變數.txt變數
- [20121102]PLSQL中的繫結變數.txtSQL變數
- ORACLE 繫結變數用法總結Oracle變數
- zt_繫結變數和cursor_sharing變數
- OLTP系統中儘量使用繫結變數變數
- oracle 查詢未使用繫結變數的sqlOracle變數SQL