2013-05-06 60 views
-5

我在JSP中爲我的oracle數據庫創建了一個API。有哪些方法可以減少Select查詢所花費的時間?

我有兩個表,每個包含20k記錄。我需要執行自然連接,結果將以JSON格式顯示在JSP頁面中。我的問題是需要將近3分鐘才能加載JSON頁面。

請告訴我如何提高我的頁面的性能?從WHERE子句條件

+0

關於如何改進select語句的好文章:http://www.componentace.com/help/absdb_manual/increaseqlperformance.htm – Max 2013-05-06 11:56:09

+0

你是否真的試圖在一頁上呈現20k條記錄? (考慮使用帶有頁面控件的數據網格,這樣頁面就不會嘗試一次渲染所有的數據了。Select需要多長時間才能對數據庫單獨運行?(<1秒,你可以做的問題不是JSP問題,因此數據網格和頁面的使用)如果> 1秒,那麼我們需要查看SQL,表結構和查詢分析器的結果來幫助[Others Agree](http://stackoverflow.com/questions/10734751/performance-問題到加載巨大記錄在一個單一的jsp頁) – xQbert 2013-05-06 11:58:09

+0

@xQbert:在oracle中它平均需要超過50secs ..因爲它是一個JSON頁面,我不能使用數據網格。是使用datagrid的一些方法,然後請告訴我。 – NewUser 2013-05-06 12:00:28

回答

0

可用指標

建議,以確保從那裏爲條件的最佳指標條款可用。 有關如何檢查搜索條件並創建適當索引的更多詳細信息,請參閱「加快搜索和篩選」主題。 例如,如果你想獲得對查詢有更好的表現:

SELECT * FROM customer WHERE City='Kapaa Kauai' AND State='HI' 

加快它的最好的辦法就是創建以下區分大小寫指數:

ABSTable1.AddIndex('idxCityState', 'City;State', []); 

如果您需要以獲取查詢有更好的表現:

SELECT * FROM customer WHERE Upper(City)='KAPAA KAUAI' 

加快它的最好的辦法就是創建以下不區分大小寫指數:

ABSTable1.AddIndex('idxCity_nocase', 'City', [ixCaseInsensitive]); 

的JOIN條件

爲了提高連接查詢可用的索引,請從JOIN條件的每個領域都有一個索引。 例如,如果你想提高查詢性能:

SELECT Event_Name,Venue FROM Events e JOIN Venues v ON (e.VenueNo = v.VenueNo) 

您可以創建以下指標:

VenuesTable.AddIndex('idxVenueNo', 'VenueNo', [ixPrimary]); 
EventsTable.AddIndex('idxVenueNo', 'VenueNo', []); 

與OR條件重寫查詢作爲UNION

絕對DB無法使用索引來提高具有OR條件的查詢的性能。

SELECT ... WHERE Field1 = 'Value1' 
UNION 
SELECT ... WHERE Field2 = 'Value2' 

可用索引ORDER BY子句

:您可以通過在上述條件下的每個字段創建索引,並通過使用UNION操盤 的使用或加速你的 查詢

SELECT * FROM table WHERE (Field1 = 'Value1') OR (Field2 = 'Value2') 

如果要使用ORDER BY子句加速來自單個表的「實時」SELECT,可以爲ORDER BY字段創建一個複合索引。 例如,如果你想提高查詢速度:

SELECT * FROM Employee ORDER BY LastName, FirstName 

,你可以通過創建下列複合索引做到這一點:BY子句

ABSTable1.AddIndex('idxLastNameFirstName', 'LastName;FirstName', []); 

爲羣的可用指標

爲了從具有GROUP BY子句的單個表中獲得更好的SELECT性能,可以爲GROUP BY字段創建一個複合索引。 例如,如果你想加快查詢:

SELECT * FROM Employee GROUP BY FirstName 

您可以創建以下指標:從內存中的表

ABSTable1.AddIndex('idxFirstName', 'FirstName', []); 

選擇

您的查詢perofrmance可能也有所增加如果您將所有數據從磁盤表移動到內存表,並且您將使用磁盤表的內存副本執行查詢(在查詢執行之前將TABSQuery.InMemory屬性設置爲True)。

SELECT INTO VS INSERT SELECT

在某些情況下SELECT ... INTO some_table查詢的運行速度比INSERT INTO some_table(SELECT ...),在另一種情況下,INSERT INTO更快。請注意,RequestLive屬性可能會影響這些查詢的性能。

+0

嗯,我不是在哪裏條件在一個二.. – NewUser 2013-05-06 11:58:21

+0

有很多方法來改善選擇語句,他們都在我的答案,他們並不都包含where條件。 – Max 2013-05-06 12:01:27

2

要優化一個過程(任何過程!),您需要了解它在哪裏花費時間。如果你在數據庫中花費了10秒,而在java中花費了170秒,你不想從明顯優化查詢開始。

你應該做的第一件事就是在數據庫中直接運行查詢,用最小的圖形顯示,例如在SQL * Plus有:

set timing on 
set autotrace traceonly statistics 

這會給你多少個大概的瞭解花費在從數據庫中提取時間上。最有可能加入兩個20k行的小表,這不應該超過1秒。

在數據庫服務器上運行查詢以消除任何網絡延遲。

如果需要更多時間,則意味着行非常大(很多大的列)或者您有一個異常大的high water mark

我認爲Oracle正在爲查詢選擇正確的計劃(因爲您沒有使用WHERE條件,應該是FULL SCAN + HASH JOIN)。

1

首先,您應該知道,有些顧問通過調整其他人的簡單代碼來做出非常好的生活。如果性能優化只是一些規則的問題,他們無法做到這一點。你的案件的具體細節真的很重要。

所以這裏有幾個意見。

我們有兩個感興趣的陳述。在問題正文中:

「我的問題是需要將近3分鐘來加載JSON頁面。」

...在評論這一點:

「在oracle中需要比50secs更平均」

這表明大部分的時間是存在花在數據庫中。因此,調優的第一個重點應該是前端代碼或網絡。包含20000行的結果集(包括來自兩個表的記錄)可能是很多數據包。也許你的網絡/系統管理員可以提供建議。

需要檢查的一件事是,您要從數據庫中收集信息集,而不是逐行(甚至更糟糕地,按屬性分類)進行。

即使如此,50秒也是很多時間來獲得數據庫中的兩萬行,除非這些行很長。或者沒有足夠的內存來對散列連接進行排序,因此它正在分頁到磁盤。


「是50秒一個resonalble時間?」

定義合理。如果我是一個用戶,並且我有一個電話上的客戶,並且在查詢返回之前我無法回覆他們,那當然是完全不可接受的。但是,如果這是一個異步Web服務,它在完成時將消息放入隊列中,我可以在接下來的一個小時內隨時處理它,然後50秒就可以了。

正如我已經說過,你的案件的具體細節問題。但是你沒有提供任何細節,所以你可以擁有一般性。一般而言,我會說幾乎一分鐘太長,無法加入並選擇一個?二?二十?來自兩個普通小桌子的行。

但讓我再重複一遍自己:50秒不到您填寫頁面花費的總時間的一半。如果你傳回幾行而不是兩萬行,那麼其他130秒更加明顯。

+0

結果集不是20,000行。它是兩排有兩萬行的自然連接的結果。因此,20,000 * 20,000比較完成以獲得結果集。 50秒是一個可調整的時間? – NewUser 2013-05-06 17:16:11