1. 程式人生 > >sqlplus之使用繫結變數

sqlplus之使用繫結變數

oracle將已解析、已編譯的SQL連同其他內容儲存在共享池(shared pool)中,這是系統全域性區(System Global Area,SGA)中一個非常重要的共享記憶體結構.

繫結變數(bind variable)是查詢中的一個佔位符。

例如,要獲取員工編號7369的相應記錄,可以使用:

[email protected]>select * from emp where empno=7369;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM    DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ----------    ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                20

或者可以將繫結變數:empno設定為7369,再執行查詢:

[email protected]>variable empno number;
[email protected]>exec :empno := 7369;
PL/SQL 過程已成功完成。

[email protected]>select * from emp where empno=:empno;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM    DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ----------    ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                20

在典型的系統中,你可能只查詢一次員工 7369,然後不再查詢這個員工了。之後,你可能會查詢員工666,然後是員工888,如此等等。如果在查詢中使用直接量(常量),那麼每個查詢都將是一個全新的查詢,在資料庫看來以前從未見過,必須對查詢進行解析、限定(命名解析)、安全性檢查、優化等。你執行的每條不同的語句都要在執行時進行編譯。

第二個查詢使用了一個繫結變數:empno,變數值在查詢執行時提供。這個查詢只編譯一次,隨後會把查詢計劃儲存在一個共享池(庫快取)中,以便以後獲取和重用這個查詢計劃。


--------------------------------------------------------------------------------------------------------------------------------

第一個過程使用了帶繫結變數的sql語句,如下:

[email protected]>create or replace procedure proc1
  2  as
  3  begin
  4  for i in 1 .. 10000
  5  loop
  6  execute immediate
  7  'insert into t values(:x)' using i;
  8  end loop;
  9  end;
 10  /

過程已建立。

第二個過程則分別要為插入的每一行構造一條獨特的sql語句,如下:

[email protected]>create or replace procedure proc2
  2  as
  3  begin
  4  for i in 1 .. 10000
  5  loop
  6  execute immediate
  7  'insert into t values('|| i ||')';
  8  end loop;
  9  end;
 10  /

過程已建立。

比較兩者效能區別:

[email protected]>exec runstats_pkg.rs_start
PL/SQL 過程已成功完成。

[email protected]>exec proc1
PL/SQL 過程已成功完成。

[email protected]>exec runstats_pkg.rs_middle
PL/SQL 過程已成功完成。

[email protected]>exec proc2
PL/SQL 過程已成功完成。

[email protected]>exec runstats_pkg.rs_stop(1000) #列印差距大於1000以上的比較結果
Run1 ran in 25 cpu hsecs
Run2 ran in 396 cpu hsecs
run 1 ran in 6.31% of the time

Name                                  Run1        Run2        Diff
LATCH.object queue header oper       2,569         280      -2,289
STAT...sql area evicted                  0       7,506       7,506
STAT...session cursor cache hi      10,010          63      -9,947
STAT...calls to kcmgcs                  51      10,048       9,997
STAT...enqueue requests                 30      10,029       9,999
STAT...enqueue releases                 28      10,029      10,001
STAT...parse count (hard)                4      10,011      10,007
STAT...parse count (total)              26      10,057      10,031
STAT...consistent gets from ca          51      10,126      10,075
STAT...consistent gets                  96      10,318      10,222
STAT...consistent gets from ca          96      10,318      10,222
STAT...file io wait time            19,052           0     -19,052
LATCH.enqueue hash chains              853      20,669      19,816
LATCH.enqueues                         759      20,626      19,867
STAT...db block gets                10,421      30,373      19,952
STAT...db block gets from cach      10,421      30,373      19,952
STAT...db block gets from cach          61      20,042      19,981
STAT...session logical reads        10,517      40,691      30,174
STAT...recursive calls              10,328      41,019      30,691
STAT...session uga memory max      123,512      72,952     -50,560
LATCH.kks stats                          9      50,688      50,679
LATCH.cache buffers chains          57,017     113,844      56,827
STAT...session uga memory           65,488     130,976      65,488
STAT...session pga memory max      131,072      65,536     -65,536
STAT...session pga memory           65,536     131,072      65,536
LATCH.shared pool simulator             27      77,205      77,178
STAT...physical read total byt      81,920           0     -81,920
STAT...cell physical IO interc      81,920           0     -81,920
STAT...physical read bytes          81,920           0     -81,920
LATCH.row cache objects                809     182,273     181,464
LATCH.shared pool                   20,393     455,102     434,709

Run1 latches total versus runs -- difference and pct
Run1        Run2        Diff       Pct
86,743     925,525     838,782      9.37%

PL/SQL 過程已成功完成。
結果清楚地顯示,從牆上時鐘來看,proc2(沒有使用繫結變數)插入10000行記錄的時間要比proc1(使用了繫結變數)要多出很多。實際上,proc2需要的時間是proc1的15倍多,這說明,在這種情況下,對於每個"無繫結變數"的insert,執行語句所需時間中有14/15僅用於解析!

可以看到,如果使用了繫結變數,則只有4次解析;沒有使用繫結變數,卻有不下10000次的硬解析(每次插入都會帶來一次硬解析).

相關推薦

Oracle SQL調優變數用法簡介

最近在看《基於Oracle的SQL優化一書》,並做了筆記,作者的個人部落格:[http://www.dbsnake.net/](http://www.dbsnake.net/) @[toc] ## 一、SQL執行過程簡介 繼上一篇部落格Oracle的cursor學習筆記:[Oracle的遊標Cursor原理

sqlplus使用變數

oracle將已解析、已編譯的SQL連同其他內容儲存在共享池(shared pool)中,這是系統全域性區(System Global Area,SGA)中一個非常重要的共享記憶體結構.繫結變數(bind variable)是查詢中的一個佔位符。例如,要獲取員工編號7369的

WPFS資料(要是後臺類物件的屬性值發生改變,通知在“客戶端介面與的控制元件值”也發生改變需要實現INotitypropertyChanged介面)

WPFS資料繫結(要是後臺類物件的屬性值發生改變,通知在“客戶端介面與之繫結的控制元件值”也發生改變需要實現INotitypropertyChanged介面) MainWindow.xaml 1 <Window x:Class="WpfApplication1.MainWindow" 2

SQL Profiles的force_match引數在不改變程式碼的情況下解決沒有使用變數的問題

How To Use SQL Profiles for Queries Using Different Literals Using the Force_Match Parameter of DBMS_SQLTUNE.ACCEPT_SQL_PROFILE (Doc ID 1253696.1)

檢視oracle中未使用變數的sql語句

資料庫版本:11.2.0.4 查詢語句: with force_mathces as (select l.force_matching_signature mathces, max(l.sql_id || l.child_number) max_sql_

Nginx 內建變數

Nginx作為一個成熟、久經考驗的負載均衡軟體,與其提供豐富、完整的內建變數是分不開的,它極大增加了對Nginx網路行為的控制細度。這些變數大部分都是在請求進入時解析的,並把他們快取到請求cycle中,方便下一次獲取使用。首先來看看Nginx對都開放了那些API。 參看下表

mybatis批量分批次插入oracle資料庫,報ORA-01745: 無效的主機/變數名...

方法一:迴圈呼叫插入單條記錄的方法,效率真心讓人捉急 (3萬條資料,快三分鐘)     public int saveGwghidlist1(List<Gwghid> list) {                  int xh=0;         dele

python學習-方法和非方法

繫結方法 @classmethod 函式功能上面新增這個內建函式就是繫結給類 繫結給類的,引數裡面就是cls,cls這個是規範的寫法,cls就是指傳入的是類 特殊之處: 繫結給誰就應該由誰來呼叫,會將呼叫者(點左邊的就是呼叫者)當做第一個引數自動傳入 繫結物件的方法: 類中定義的函式在沒有

Vue事件

繫結事件 v-on:click 簡寫:@click;為button新增一個change的點選事件,改變content的值 <div> <div class="button

angular/ionic中對img、iframe等的src進行動態變數的問題解決

例如以下程式碼: 對應的html頁面中是這樣:<iframe class=“filling” [src] = “iframe”> 在這裡直接對src進行動態繫結變數就會出現:unsafe value used in a resource URL co

SpringMVC引數的型別轉換(Date/Double)

一、使用註解式控制器註冊PropertyEditor(針對具體的controller類處理)         1、使用WebDataBinder進行控制器級別的註冊PropertyEditor(控制器獨享) Java程式碼   @InitBinder   // 此

yii事件機制

事件機制一共分為兩種:掃碼式和繫結式,yii中主要用的是繫結式,而繫結式又涉及兩個方法:trigger()和on() 1. trigger() : 事件通過呼叫 yii\base\Component::trigger() 方法觸發,此方法須傳遞事件名, 還可以傳遞一個事件物

spring 中@ModelAttribute變數中文亂碼的解決辦法

網上找了一些方法: 方法一 在專案的web.xml中配置spring的Character Encoding Filter <!-- Servlet Encoding Start --> <filter> <filter

Spring-AOP @AspectJ進階類註解物件

概述 例項 概述 @within()和@target()函式可以將目標類的註解物件繫結到增強方法中。 我們通過@within()演示註解繫結的操作 例項 註

python cx_oracle 變數

insert into tlcb_collect_f5 values(:stime,:virtual_servers,:default_pool_name,:ipaddr,:port,:AVAILABILITY_STATUS,:ENABLED_STATUS,:POOL_MEMBER_STATUS);

Spring-AOP @AspectJ進階丟擲的異常

概述 例項 總結 概述 和通過切點函式繫結連線點資訊不同,連線點丟擲的異常必須使用AfterThrowing註解的throwing成員進行繫結 例項 業務類 p

C# Socket程式設計IP與埠

 Socket serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);  //獲取Socket     &

powershell指令碼,命令列引數傳值,並變數的例子

        這是小技巧文章,所以文章不長。但原創唯一,非常重要。我搜了下,還真沒有人發 powershell怎樣 【命令列 引數 繫結】,所以我決定寫成部落格。 搜尋關鍵字如下: powershell 命令列 引數 繫結 powershell 傳入 引數 powershell 傳遞 引數 p

面向物件方法與非方法

一 類中定義的函式分成兩大類 一:繫結方法(繫結給誰,誰來呼叫就自動將它本身當作第一個引數傳入):     1. 繫結到類的方法:用classmethod裝飾器裝飾的方法。                 為類量身定製                 類.boud_method(),自動將類當作第一個

Oracle 變數窺探

Bind Peeking是Oracle 9i中引入的新特性,一直持續到Oracle 10g R2。它的作用就是在SQL語句硬分析的時候,檢視一下當前SQL謂詞的值 ,以便生成最佳的執行計劃。而在oracle 9i之前的版本中,Oracle 只根據統計資訊來做出執行計劃。