2012-06-10 47 views
2

在調用返回SYS_RECURSOR或調用查詢的過程時是否有任何性能改進?從數據庫表中獲取結果的更好選擇

例如

CREATE OR REPLACE PROCEDURE my_proc 
(
    p_id number, 
    emp_cursor IN OUT SYS_REFCURSOR 
) 
AS 
BEGIN 

OPEN emp_cursor for 
select * from emp where emp_number=p_id 
end; 
/

和通過註冊OUT參數調用從Java以上,通過IN參數和獲取結果。

或者

Java通過

preparedStatement = prepareStatement(connection, "select * from emp where emp_number=?", values); 
resultSet = preparedStatement.executeQuery(); 

哪一個上面是一個更好的選擇,從Java調用get從emptable的結果?

回答

1

假設您的prepareStatement方法對所有綁定變量使用適當的類型,沒有性能差異。也就是說,您需要確保您正在調用setLong,setDatesetString等,具體取決於參數的數據類型。如果您不正確地綁定數據(即調用setString來綁定數字值),則可能會強制Oracle執行數據類型轉換,這可能會阻止優化器使用可提高性能的索引。

但是,從代碼組織和維護的角度來看,我寧願在數據庫中而不是Java應用程序中查詢。例如,如果您發現某個查詢使用的是較差的計劃,那麼如果該查詢位於存儲過程中,則與查詢嵌入到Java應用程序中相比,DBA可能更容易解決該問題。如果查詢存儲在數據庫中,則還可以使用數據庫的依賴關係跟蹤功能更輕鬆地進行影響分析,如果需要執行某些操作,例如確定表格需要更改時會受到什麼影響。

+0

從維護和其他角度來看,我認爲這是一個好主意,保持存儲過程中的查詢。 'prepareStatement方法的意思是使用適合所有綁定變量的類型'。能夠多解釋一下嗎?謝謝 – user75ponic

+0

@Polappan - 更新了我的答案。 –

1

那麼,我認爲從Java調用的角度來看,並沒有太大的區別。

一些differencesI能想到的是:

  • 你現在必須保持兩個不同的代碼庫:你的Java代碼和存儲過程。如果出現錯誤,您必須在兩個不同的地方進行調試,並在兩個不同的地方解決問題。
  • 一旦生產就緒,對數據庫進行更改可能需要一些額外的形式,除了需要更改部署的Java代碼之外。
  • 另一個要考慮的重要問題是數據庫獨立性,如果您正在構建一個產品以使用不同類型的數據庫,則您將被迫編寫不同版本的存儲過程,並且您將擁有更多的代碼來維護(調試,錯誤修正,更改等)。
  • 如果您打算在不同的(可能還是未知的)客戶機的不同環境中部署產品,那麼這一點非常重要,因爲您無法預測將要使用的RDBMS。
  • 如果你想使用ORM框架,即Hibernate,EclipseLink),它會爲你生成相當優化的查詢。另外,如果你使用存儲過程,稍後集成它會更困難。
  • 通過適當的日誌記錄功能可以輕鬆分析查詢以實現優化目的。您可以使用JDBC日誌記錄或ORM提供程序提供的日誌記錄,並實際查看應用程序使用查詢的方式,次數,次數等,並優化它的重要位置。
+0

是的,如果表格結構發生變化,我可能不得不改變兩個地方。通過'resultSet.getstring(「emp_name」)'或'resultSet.getstring(2);''獲取行是一個好習慣。通過指定'2'作爲位置,我們不需要擔心'java'中的列名是不是? – user75ponic

+1

@Polappan如果重命名列,則使用整數而不是名稱將簡化更改,但會使代碼在結果集和對象之間的映射中更難理解。另外,如果您重新安排專欄的順序或者如果您刪除專欄,該怎麼辦?我想說的好處不是那麼大。此外,我更新了我的答案,包括其他決定標準。 –

+0

感謝您的解釋。 – user75ponic

相關問題