2017-08-08 76 views
1

當使用JDBC的預處理語句查詢甲骨文,考慮一下:參數化常量在PreparedStatement的查詢的性能後果

String qry1 = "SELECT col1 FROM table1 WHERE rownum=? AND col2=?"; 

String qry2 = "SELECT col1 FROM table1 WHERE rownum=1 AND col2=?"; 

String qry3 = "SELECT col1 FROM table1 WHERE rownum=1 AND col2=" + someVariable ; 

邏輯決定了ROWNUM的值始終是一個常數(1在這個例子中)。雖然col2的值是一個變化的變量

問題1:是否有任何Oracle服務器的性能優勢(編譯查詢,緩存等)使用qry1其中ROWNUM值參數,在qry2這裏的rownum的恆定值是硬編碼?

問題2:忽略非性能考慮(如SQL注入,可讀性,等),是否有任何Oracle服務器性能優勢(查詢編譯,高速緩存等),以使用過qry2 qry3(其中col2的值顯式爲,附加,未參數化)。

回答

3

答案1:使用qry1(軟編碼查詢)而不是qry2(具有合理綁定變量的查詢)沒有性能優勢。

綁定變量通過減少查詢解析來提高性能;如果綁定變量是常量,則不需要額外解析。

(可能有一些奇怪的例子,添加額外的綁定變量可以提高某個特定查詢的性能,就像任何預測程序一樣,偶爾如果您向Oracle優化器提供不良信息,結果會更好。明白這些都是特殊情況下)

答2:有很多性能上的優勢,使用qry2(以合理的綁定變量查詢)在qry3(硬編碼的查詢)。

綁定變量允許Oracle重新使用大量進入查詢分析(查詢編譯)的工作。例如,對於Oracle需要檢查用戶是否有權查看相關表的每個查詢。使用綁定變量只需要爲查詢的所有執行完成一次。

綁定變量還允許Oracle使用一些額外的優化技巧,這些技巧只發生在第N次運行之後。例如,Oracle可以使用基數反饋來改進查詢的第二次執行。當Oracle在一個計劃中犯了一個錯誤時,例如,如果它估計一個連接產生了1行,當它真的產生100萬行時,它有時會記錄那個錯誤並使用該信息來改善下一次運行。如果沒有綁定變量,下一次運行將會不同,並且將無法修復該錯誤。

綁定變量還允許許多不同的計劃管理功能。有時,DBA需要更改執行計劃而不更改查詢的文本。如果查詢文本不斷變化,則SQL計劃基線,配置文件,輪廓和DBMS_ADVANCED_REWRITE等功能將不起作用。

另一方面,有一些合理的情況下最好對查詢進行硬編碼。有時,像分區修剪這樣的Oracle功能無法理解表達式,並且它有助於對值進行硬編碼。對於大型數據倉庫查詢,如果查詢要運行很長一段時間,解析查詢的額外時間可能是值得的。 (高速緩存不太可能影響任何一種情況,一個語句的結果高速緩存很少,Oracle很可能只高速緩存語句中使用的表的塊,緩衝區高速緩存可能並不關心這些塊多次訪問或多次訪問一次)