避免動態SQL(一)
動態SQL在執行過程中編譯,而普通SQL是在執行前就已經編譯過了。
案例1
案例1
點選(此處)摺疊或開啟
-
--create.sql
-
--建立Luise使用者和相應的優化指令碼包
-
conn / as sysdba;
-
-
drop user luise cascade;
-
CREATE USER luise IDENTIFIED BY luise;
-
GRANT DBA TO luise;
-
grant select any dictionary to luise;
-
-
conn luise/luise
-
-
CREATE OR REPLACE VIEW STATS AS
-
SELECT \'STAT...\' || a.name AS name, b.value FROM v$statname a, v$mystat b WHERE a.statistic# = b.statistic#
-
UNION ALL
-
SELECT \'LATCH.\' || name, gets FROM v$latch;
-
-
---------------------------------------------------------------------------------------
-
DROP TABLE run_stats;
-
CREATE GLOBAL TEMPORARY TABLE run_stats
-
(
-
runid VARCHAR2(15),
-
name VARCHAR2(80),
-
value INT
-
)ON COMMIT PRESERVE ROWS;
-
-
--------------------------------------------------------------------------------------
-
CREATE OR REPLACE PACKAGE runstats_pkg
-
AS
-
PROCEDURE rs_start;
-
PROCEDURE rs_middle;
-
PROCEDURE rs_stop(p_difference_threshold IN NUMBER DEFAULT 0);
-
END;
-
/
-
-
----------------------------------------------------------------------------------------
-
CREATE OR REPLACE PACKAGE BODY runstats_pkg
-
AS
-
g_start NUMBER;
-
g_run1 NUMBER;
-
g_run2 NUMBER;
-
-
PROCEDURE rs_start
-
IS
-
BEGIN
-
DELETE FROM run_stats;
-
INSERT INTO run_stats
-
SELECT \'before\', stats.* FROM stats;
-
g_start := dbms_utility.get_time;
-
END;
-
-
-
PROCEDURE rs_middle
-
IS
-
BEGIN
-
g_run1 := (dbms_utility.get_time - g_start);
-
INSERT INTO run_stats SELECT \'after 1\', stats.* FROM stats;
-
g_start := dbms_utility.get_time;
-
END;
-
-
PROCEDURE rs_stop(p_difference_threshold IN NUMBER DEFAULT 0)
-
IS
-
BEGIN
-
g_run2 := (dbms_utility.get_time - g_start);
-
dbms_output.put_line(\'Run1 ran in \' || g_run1 || \'hsec\');
-
dbms_output.put_line(\'Run2 ran in \' || g_run2 || \'hsec\');
-
dbms_output.put_line(\'run 1 ran in \' || round(g_run1/g_run2 * 100, 2)|| \'% of the time\');
-
dbms_output.put_line(chr(9));
-
-
INSERT INTO run_stats SELECT \'after 2\',stats.* FROM STATS;
-
dbms_output.put_line(rpad(\'Name\',30) || lpad(\'Run1\',10)|| lpad(\'Run2\',10) || lpad(\'Diff\',10));
-
-
FOR x IN(SELECT rpad(a.name,30) || to_char(b.value - a.value,\'9,999,999\') ||
-
to_char(c.value-b.value,\'9,999,999\') ||
-
to_char(((c.value - b.value)-(b.value - a.value)),\'9,999,999\') AS data
-
FROM run_stats a, run_stats b, run_stats c
-
WHERE a.name = b.name
-
AND b.name=c.name
-
AND a.runid=\'before\'
-
AND b.runid=\'after 1\'
-
AND c.runid=\'after 2\'
-
AND (c.value - a.value) > 0
-
AND abs((c.value - b.value) - (b.value - a.value)) > p_difference_threshold
-
ORDER BY abs((c.value - b.value) - (b.value - a.value)))
-
LOOP
-
dbms_output.put_line(x.data);
-
END LOOP;
-
-
dbms_output.put_line(chr(9));
-
dbms_output.put_line(\'Run1 latches total versus runs ----difference and pct\');
-
dbms_output.put_line(lpad(\'Run1\',10) || lpad(\'Run2\',10) || lpad(\'Diff\',10) || lpad(\'Pct\',8));
-
-
FOR x IN(SELECT to_char(run1,\'9,999,999\') || to_char(run2,\'9,999,999\') ||
-
to_char(diff,\'9,999,999\') || to_char(round(run1/run2*100, 2), \'999.99\') || \'%\' AS DATA
-
FROM (SELECT sum(b.value-a.value) AS run1, sum(c.value-b.value) AS run2,
-
sum((c.value - b.value) - (b.value - a.value)) AS diff
-
FROM run_stats a, run_stats b, run_stats c
-
WHERE a.name = b.name
-
AND b.name = c.name
-
AND a.runid = \'before\'
-
AND b.runid = \'after 1\'
-
AND c.runid = \'after 2\'
-
AND a.name LIKE \'LATCH%\'))
-
LOOP
-
dbms_output.put_line(x.data);
-
END LOOP;
-
END;
-
END;
-
/
-
--下面的實驗是為了說明動態SQL在效能上不如靜態SQL
-
CREATE TABLE t(col1 NUMBER(10));
-
INSERT INTO t SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 100000;
-
COMMIT;
-
-
set serveroutput on;
-
luise@TESTDB11>exec runstats_pkg.rs_start;
-
--動態SQL
-
BEGIN
-
EXECUTE IMMEDIATE \'DELETE FROM t\';
-
COMMIT;
-
END;
-
/
-
-
alter system flush shared_pool;
-
alter system flush buffer_cache;
-
truncate table t;
-
INSERT INTO t SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 100000;
-
COMMIT;
-
-
luise@TESTDB11>exec runstats_pkg.rs_middle;
-
--靜態SQL
-
BEGIN
-
DELETE FROM t;
-
COMMIT;
-
END;
-
/
-
-
luise@TESTDB11>exec runstats_pkg.rs_stop(5000);
-
Run1 ran in 32048hsec
-
Run2 ran in 6504hsec
-
run 1 ran in 492.74% of the time
-
-
Name Run1 Run2 Diff
-
STAT...buffer is not pinned co 5,447 306 -5,141
-
STAT...buffer is not pinned co 5,447 173 -5,274
-
STAT...buffer is not pinned co 5,447 173 -5,274
-
STAT...buffer is not pinned co 5,447 173 -5,274
-
STAT...sorts (rows) 6,264 852 -5,412
-
STAT...consistent gets 7,108 1,666 -5,442
-
STAT...consistent gets from ca 7,108 1,666 -5,442
-
STAT...sorts (rows) 6,264 751 -5,513
-
LATCH.enqueue hash chains 7,070 1,251 -5,819
-
STAT...consistent gets from ca 7,108 1,209 -5,899
-
STAT...consistent gets 7,108 1,209 -5,899
-
STAT...recursive calls 6,641 704 -5,937
-
LATCH.enqueue hash chains 7,070 1,078 -5,992
-
STAT...sorts (rows) 6,264 216 -6,048
-
LATCH.SQL memory manager worka 7,575 1,457 -6,118
-
STAT...consistent gets from ca 7,108 977 -6,131
-
STAT...consistent gets 7,108 977 -6,131
-
STAT...recursive calls 6,641 504 -6,137
-
STAT...recursive calls 6,641 495 -6,146
-
STAT...recursive calls 6,641 459 -6,182
-
STAT...sorts (rows) 6,264 7 -6,257
-
LATCH.enqueue hash chains 7,070 788 -6,282
-
LATCH.enqueue hash chains 7,070 689 -6,381
-
LATCH.SQL memory manager worka 7,575 1,178 -6,397
-
STAT...consistent gets from ca 7,108 617 -6,491
-
STAT...consistent gets 7,108 617 -6,491
-
LATCH.SQL memory manager worka 7,575 830 -6,745
-
LATCH.SQL memory manager worka 7,575 673 -6,902
-
LATCH.shared pool simulator 6,952 48 -6,904
-
LATCH.shared pool simulator 6,952 40 -6,912
-
LATCH.shared pool simulator 6,952 34 -6,918
-
LATCH.shared pool simulator 6,952 17 -6,935
-
STAT...file io wait time 8,172 1,166 -7,006
-
STAT...file io wait time 8,172 555 -7,617
-
STAT...file io wait time 8,172 555 -7,617
-
STAT...file io wait time 8,172 267 -7,905
-
LATCH.cache buffers lru chain 11,348 3,372 -7,976
-
LATCH.cache buffers lru chain 11,348 3,356 -7,992
-
LATCH.cache buffers lru chain 11,348 3,343 -8,005
-
LATCH.cache buffers lru chain 11,348 3,330 -8,018
-
LATCH.object queue header oper 27,193 5,798 -21,395
-
LATCH.object queue header oper 27,193 5,778 -21,415
-
LATCH.object queue header oper 27,193 5,758 -21,435
-
LATCH.object queue header oper 27,193 5,744 -21,449
-
LATCH.shared pool 60,100 1,563 -58,537
-
LATCH.shared pool 60,100 1,394 -58,706
-
LATCH.shared pool 60,100 1,165 -58,935
-
LATCH.shared pool 60,100 531 -59,569
-
STAT...session pga memory max 65,536 0 -65,536
-
STAT...session pga memory max 65,536 0 -65,536
-
STAT...session pga memory max 65,536 0 -65,536
-
STAT...session pga memory max 65,536 0 -65,536
-
LATCH.row cache objects 84,484 1,689 -82,795
-
LATCH.row cache objects 84,484 1,424 -83,060
-
LATCH.row cache objects 84,484 1,008 -83,476
-
LATCH.row cache objects 84,484 593 -83,891
-
STAT...session logical reads 115,455 208,500 93,045
-
STAT...session logical reads 115,455 208,901 93,446
-
STAT...session logical reads 115,455 209,180 93,725
-
STAT...session logical reads 115,455 209,678 94,223
-
STAT...redo entries 103,487 201,299 97,812
-
STAT...redo entries 103,487 201,314 97,827
-
STAT...redo entries 103,487 201,329 97,842
-
STAT...redo entries 103,487 201,344 97,857
-
STAT...buffer is pinned count 100,965 199,710 98,745
-
STAT...buffer is pinned count 100,965 199,710 98,745
-
STAT...buffer is pinned count 100,965 199,710 98,745
-
STAT...buffer is pinned count 100,965 199,710 98,745
-
STAT...HSC Heap Segment Block 101,118 200,015 98,897
-
STAT...HSC Heap Segment Block 101,118 200,030 98,912
-
STAT...HSC Heap Segment Block 101,118 200,045 98,927
-
STAT...HSC Heap Segment Block 101,118 200,060 98,942
-
STAT...db block gets 108,347 207,883 99,536
-
STAT...db block gets from cach 108,347 207,883 99,536
-
STAT...db block gets from cach 108,347 207,924 99,577
-
STAT...db block gets 108,347 207,924 99,577
-
STAT...db block gets from cach 108,347 207,971 99,624
-
STAT...db block gets 108,347 207,971 99,624
-
STAT...db block gets from cach 108,347 208,012 99,665
-
STAT...db block gets 108,347 208,012 99,665
-
STAT...table scan rows gotten 122,040 229,260 107,220
-
STAT...session uga memory max 130,952 0 -130,952
-
STAT...session uga memory max 130,952 0 -130,952
-
STAT...session uga memory max 130,952 0 -130,952
-
STAT...session uga memory max 130,952 0 -130,952
-
STAT...table scan rows gotten 122,040 272,388 150,348
-
STAT...session uga memory 158,352 0 -158,352
-
STAT...table scan rows gotten 122,040 301,140 179,100
-
STAT...session uga memory 158,352 -38,096 -196,448
-
STAT...session uga memory 158,352 -38,096 -196,448
-
STAT...session uga memory 158,352 -38,096 -196,448
-
STAT...db block changes 206,351 404,116 197,765
-
STAT...db block changes 206,351 404,176 197,825
-
STAT...db block changes 206,351 404,246 197,895
-
STAT...db block changes 206,351 404,305 197,954
-
STAT...table scan rows gotten 122,040 337,080 215,040
-
STAT...session pga memory 262,144 0 -262,144
-
STAT...redo synch time (usec) 458,442 148,810 -309,632
-
STAT...redo synch time (usec) 458,442 148,810 -309,632
-
STAT...redo synch time (usec) 458,442 148,810 -309,632
-
STAT...redo synch time (usec) 458,442 148,810 -309,632
-
LATCH.cache buffers chains 727,405 1,221,577 494,172
-
LATCH.cache buffers chains 727,405 1,222,490 495,085
-
LATCH.cache buffers chains 727,405 1,223,807 496,402
-
LATCH.cache buffers chains 727,405 1,224,848 497,443
-
STAT...cell physical IO interc 2,646,016 212,992-2,433,024
-
STAT...physical read bytes 2,646,016 212,992-2,433,024
-
STAT...physical read total byt 2,646,016 212,992-2,433,024
-
STAT...physical read total byt 2,646,016 131,072-2,514,944
-
STAT...physical read total byt 2,646,016 131,072-2,514,944
-
STAT...physical read bytes 2,646,016 131,072-2,514,944
-
STAT...physical read bytes 2,646,016 131,072-2,514,944
-
STAT...cell physical IO interc 2,646,016 131,072-2,514,944
-
STAT...cell physical IO interc 2,646,016 131,072-2,514,944
-
STAT...physical read bytes 2,646,016 73,728-2,572,288
-
STAT...physical read total byt 2,646,016 73,728-2,572,288
-
STAT...cell physical IO interc 2,646,016 73,728-2,572,288
-
STAT...undo change vector size##############################
-
STAT...undo change vector size##############################
-
STAT...undo change vector size##############################
-
STAT...undo change vector size##############################
-
STAT...redo size ##############################
-
STAT...redo size ##############################
-
STAT...redo size ##############################
-
STAT...redo size ##############################
-
STAT...logical read bytes from##############################
-
STAT...logical read bytes from##############################
-
STAT...logical read bytes from##############################
-
STAT...logical read bytes from##############################
-
-
Run1 latches total versus runs ----difference and pct
-
Run1 Run2 Diff Pct
-
3,879,348 5,027,245 1,147,897 77.17%
-
-
PL/SQL procedure successfully completed.
-
--結論: 動態SQL的時間為靜態SQL的492.74%,還可以看出動態SQL在栓鎖、物理讀等的消耗上大大超過了靜態
- -- SQL語句. 因此要儘可能地尋找將動態SQL轉換為靜態SQL的機會,即使因此導致程式碼更復雜也是值得的.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17013648/viewspace-1071366/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【SQL】Oracle避免動態SQL,提高過程執行效率SQLOracle
- MyBatis 動態 SQLMyBatisSQL
- MybBatis動態SQLBATSQL
- Mybatics動態sqlBATSQL
- mybatis動態SQLMyBatisSQL
- MyBatis(七) 動態SQLMyBatisSQL
- 1 Mybatis動態SQLMyBatisSQL
- Mybatis--動態SQLMyBatisSQL
- 一句SQL完成動態分級查詢SQL
- Mybatis(一)Porxy動態代理和sql解析替換MyBatisSQL
- mybatis動態sql總結MyBatisSQL
- Mybatis-06 動態SqlMyBatisSQL
- MyBatis框架之SQL對映和動態SQLMyBatis框架SQL
- MyBatis對動態SQL的支援MyBatisSQL
- mybatis動態sql與分頁MyBatisSQL
- Java-Mybatis動態SQL整理JavaMyBatisSQL
- Gbase 8s 動態 SQLSQL
- Mybatis介紹之 動態SQLMyBatisSQL
- APEX 通過PL/SQL動態展示區域中動態內容SQL
- 動態SQL-條件分頁SQL
- 動態 SQL 和快取機制SQL快取
- Mybatis 動態執行SQL語句MyBatisSQL
- day06-動態SQL語句SQL
- 介面的繫結方案和動態SQLSQL
- hive Sql的動態分割槽問題HiveSQL
- Myabtis動態SQL,你真的會了嗎?SQL
- 【MyBatis學習總結 (五),動態SQL】MyBatisSQL
- PHP--動態生成sql查詢表格PHPSQL
- Mybatis where 1=1 動態sql問題MyBatisSQL
- MyBatis 動態 SQL 最全教程,這樣寫 SQL 太優雅了!MyBatisSQL
- [20180928]避免表示式在sql語句中.txtSQL
- SQL 如何實現動態的行列轉置SQL
- GaussDB資料庫SQL系列-動態語句資料庫SQL
- Mybatis 裡對映檔案的動態 SQL 語句,實現if,where,foreache的SQL語句動態拼接查詢MyBatisSQL
- MyBatis標籤實現的動態SQL語句MyBatisSQL
- BIRT 中如何根據引數動態拼接 SQLSQL
- PL/SQL中動態掉用儲存過程SQL儲存過程
- Egencia:近一半差旅人士避免真人互動
- TiDB SQL調優案例之避免TiFlash幫倒忙TiDBSQL