簡體   English   中英

如何更快地通過Java進行Oracle更新/插入操作?

[英]How to make my Oracle update/insert action through Java faster?

我在公司面臨一個問題 - 我們的程序速度不夠快。 更具體地說,我們是電信公司,這個程序處理我們城市每個手機用戶的電話/互聯網服務交易。 由於iphone用戶下載內容的數量太多,我們的程序無法足夠快地處理它們。

情況是,用戶進行的交易量是我們程序處理的交易量的兩倍。 程序的大部分運行時間都由數據庫事務控制。

我通過互聯網搜索並瀏覽了一些關於數據庫中Java性能的網站(例如: http//www.javaperformancetuning.com/tips/rawtips.shtml ),但我找不到適合我們的建議。

這些建議不適用/已經使用過,例如:

1.使用准備好的陳述。 使用參數化SQL

已經使用過准備好的聲明。 每次都會通過清除參數和設置參數使用不同的參數。

2.調整SQL以最小化返回的數據(例如,不是'SELECT *')。

當然,已經使用過。

3.使用連接池。

我們在程序執行期間保持一個連接。 我懷疑匯集無法解決問題,因為我們的程序充當1個用戶,因此並發訪問DB沒有問題。 如果你們有人認為合並是好的,請告訴我原因。 謝謝。

4.嘗試組合查詢和批量更新。

不能這樣做。 每個查詢/插入/更新都取決於數據庫的信息。 例如,我們在DB中查找客戶端的信息,如果我們找不到他的用法,我們會將用法插入到DB中,否則我們會更新。

5.完成后關閉資源(Connections,Statements,ResultSet)

當然。

6.選擇最快的JDBC驅動程序。

我不知道。 我在互聯網上搜索可用的驅動程序類型,我很困惑。 我們使用oracle.jdbc.driver.OracleDriver ,我們使用thin而不是oci,這就是我所知道的。 另外,我們的程序是雙層方式(java < - > oracle)

7.關閉自動提交

已經做到了。

期待任何幫助。

4.嘗試組合查詢和批量更新。

不能這樣做。 每個查詢/插入/更新都取決於數據庫的信息。 例如,我們在DB中查找客戶端的信息,如果我們找不到他的用法,我們會將用法插入到DB中,否則我們會更新。

如果您是從Java應用程序執行此操作,則可以通過一次往返在數據庫中執行此操作來提高性能。 有兩種方法:

1)使用SQL MERGE語句

2)編寫存儲過程來執行插入或更新邏輯,然后從Java調用它。

進一步說明

我假設您說的是目前Java邏輯的工作方式如下:

// Pseudocode
execute SQL 'select count(*) from mytable where id=?'
if result = 0 then
    execute SQL 'insert into mytable (id,a,b,c) values (?,?,?,?)';
else
    execute SQL 'update mytable set a=?, b=?, c=? where id=?';
end if;

這意味着對數據庫進行2次單獨的往返:一次是檢查記錄是否存在,另一次是根據需要插入或更新。

替代方案是:

1)使用SQL MERGE語句:

// Pseudocode
execute SQL 'merge into mytable t using (select ? id, ? a, ? b, ? c from dual) s
             on (t.id = s.id)
             when matched then update set t.a = s.a, t.b = s.b, t.c = s.c
             when not matched then insert (id, a, b, c)
                  values (s.id, s.a, s.b, s.c)';

MERGE語句起初有點令人生畏,特別是在這樣的情況下你必須使用Oracle的“雙”表。

2)使用存儲過程:

// Pseudocode
execute SQL 'begin mytable_package.insert_or_update
              (p_id => ?, p_a => ?, p_b => ?, p_c => ?); end;'

存儲過程在名為mytable_package的包中看起來像

procedure insert_or_update (p_id mytable.id%type
                           ,p_a  mytable.a%type
                           ,p_b  mytable.a%type
                           ,p_c  mytable.a%type
                           )
is
begin
    update mytable
    set    a = p_a, b = p_b, c = p_c
    where  id = p_id;
    if sql%rowcount = 0 then
        insert into mytable (id, a, b, c) values (p_id, p_a, p_b, p_c);
    end if;
end;

檢查你的索引! 更新性能不佳可能是外鍵約束的結果,其中外鍵上的索引在引用表上缺失。

4)嘗試組合查詢和批量更新。

不能這樣做。 每個查詢/插入/更新都取決於數據庫的信息。 例如,我們在DB中查找客戶端的信息,如果我們找不到他的用法,我們會將用法插入到DB中,否則我們會更新。

我想到了兩件事:

  • 執行UPDATE語句並檢查ExecuteUpdate()的結果; 僅當它為零時,執行INSERT。 為您保存一個SELECT語句。

  • 始終(可能批量)插入中間表,稍后使用MERGE語句更新您的使用表。

5)完成后關閉資源(Connections,Statements,ResultSet)

盡可能長時間保持連接打開(即永久關閉服務器),准備一次PreparedStatement並重復使用。


在寫入數據庫之前先進行一些聚合。 現在生成交易的手機用戶可能會在幾秒鍾內生成另一個交易。 使用哈希表來聚合當前使用情況,並在一分鍾左右后將其寫入數據庫。

獲取Professional Oracle Programming的副本。

在2005年,它似乎有點舊,但在優化性能方面,Oracle並沒有大幅改變。 我自己有這本書,並且已經使用它的建議來加速許多應用程序看似棘手的性能問題。 得到它。 閱讀。 做吧。

那么在等待快遞時你能做些什么呢?

  • 讓DBA站在你的一邊, - 你需要他們的幫助和他們的工具
  • 掌握TOAD並在必要時支付額外的查詢分析工具
  • 檢查您運行的每個查詢的索引 - 您需要仔細檢查執行計划(AUTOTRACE和EXPLAIN PLAN是您的朋友)
  • 考慮一下你正在使用的索引類型(功能索引可以做到這一點嗎?)
  • 考慮使用可傳輸的表空間
  • 使用內置優化程序收集信息
  • 獲取統計信息,以便您可以衡量性能提升(無論預緩存等)
  • 考慮存儲的輪廓
  • 考慮物化視圖以允許將數據拆分為立即需要的數據以及可能會出現延遲的數據
  • 考慮使用表截斷來減少整個表的大小,因為舊數據已被清除

這應該足以讓你牢牢掌握失敗的原因以及解決方法。

首先, 您需要DBA在您身邊告訴您實際花費的時間。 您可以在客戶端快速閃電,並且在設置關鍵索引之前仍然需要很長的事務處理時間。

自從我使用Java + Oracle已經八年了,但我沒有找到oci驅動程序(在DLL中使用本機驅動程序)比使用瘦驅動程序(全部用Java編寫)快得多。

快速解決方法可以為您提供喘息空間,可以生成一次包含1000或10000個事務的文本文件,並讓“SQLLDR”將批處理注入數據庫。 也許更多。 正確調用SQLLDR是最快的事情,它會讓你有時間正確地執行它。

您是否為每次執行啟動JVM的新實例? 您能詳細說明應用程序的性質(即如何調用它,觸發調用的內容等)。 根據您的描述,它聽起來並不像Java和DB問題。 聽起來好像是某種數據庫索引問題或其他設計問題。 您正在使用的SQL命令的性質是什么? 你有沒有定時或描述這些電話,看看有些人比其他人要長嗎?

您可以將工作負載划分為使用多個會話到數據庫嗎? 有很多往返數據庫的往返導致延遲。 如果表的結構正確,它們可以毫無問題地處理多個並發插入/更新(檢查重插入表的INITRANS屬性是否與執行插入的並發會話數相同)。 我認為這將是贏得應用性能最簡單的方法。 正在使用哪個版本的數據庫? 你能得到ADDM報告嗎? 他們可以立即告訴您 - 數據庫中的問題是什么 - 如果有的話。 應用服務器有足夠的CPU資源嗎? 如果沒有,這是將負載分成多個會話的另一個原因,在這種情況下分成多個應用服務器。 如果沒有statspack報告或 - 最好是 - ADDM報告,很難說出問題出在哪里。

羅納德,我希望這會有所幫助。

如果您希望將DBA的參與保持在最低限度,您至少可以要求登錄以訪問在測試服務器上運行的Oracle Enterprise Manager。 在OEM中,您實際上可以看到哪些操作需要很長時間。 OEM還會嘗試通過建議提高性能的方法來幫助您,例如添加索引或更改查詢結構。 希望OEM至少可以為您提供可靠的理由,要求DBA進一步參與。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM