2011-08-13 69 views
4

我有一個使用Java servlet編寫的Web應用程序。我使用Tomcat 7作爲我的servlet引擎,但以前使用過Glassfish並且具有完全相同的問題。Java Web應用程序緩慢MySQL查詢

有問題的頁面有一個「統計」部分,每5分鐘更新一次。由於涉及的MySQL表的大小,統計信息需要大約30秒才能生成。

當我得到一個頁面加載時,我顯示緩存的統計信息。在頁面中的所有內容都被渲染之後,我會刷新然後關閉輸出流。然後我更新統計數據。這樣,沒有用戶需要等待約30秒才能加載頁面,統計信息在頁面已經完全發送後纔會更新。

問題是,如果刷新頁面時,它正在運行查詢,頁面不會加載,直到查詢完成,這意味着雖然初始用戶沒有任何延遲,之後有一個長時間延遲。

爲什麼應用程序有效拖延?即使一個線程仍然忙,Tomcat是否應該能夠使用另一個工作線程來處理請求?

謝謝。

+1

你說這個問題確實很好。但是我們仍然需要知道如何創建執行查詢。我懷疑問題出在一個阻止每個人的同步方法。分享一些代碼! –

回答

2

發生什麼情況是您的數據在更新發生時被「鎖定以進行更新」 - 這取決於數據是如何重新計算的。

解決此問題的一個好方法是將新計算放入一個單獨的數據區域,然後在完成後切換到使用新數據。實現這一點的一種方法是使用一個數據庫視圖和版本號,這樣的:

create table my_statistics (
    id int not null primary key auto_increment, 
    version int not null, 
    -- other columns with your data 
); 

create table stats_version (current_version int); -- holds just one row 

create view stats as 
select * 
from stats_version v 
join my_statistics s on s.version = v.current_version); 

把你的新的統計入表CURRENT_VERSION的版本號+ 1,所有計算好之後。然後一個簡單的update stats_version set current_version = current_version + 1將切換到使用新的數據。這最後一個語句只需要幾毫秒就可以執行,所以鎖定等待很小。

切換後,您可以刪除舊的統計信息以節省空間。

使用「開關」方法使得更新和「原子更新」 - 更新發生「即刻且完全」,因此用戶看不到部分更改的數據集。