2013-06-24 230 views
1

我試圖從表中獲取count(*),表中有近700萬條記錄,並且返回結果需要一個多小時。Oracle count(*)花費的時間太長

另外,表中有153列已經爲列123創建了索引,因此試圖並行運行以下查詢,但它沒有幫助。

select /*+ parallel (5) */ count(123) from <table_name> 

請建議是否有其他方法。

當我在Toad的表上運行desc時,索引選項卡保存no的值。的行。任何想法如何在那裏更新價值?

+1

我假定由'計數(123)'你的意思是'count(column_123)',對嗎? – Bohemian

+0

'select/* + parallel(5)*/count(123)from'我認爲你無意中查詢了。 –

+1

你見過這個:http://stackoverflow.com/questions/1840538/faster-alternative-in-oracle-to-select-count-from-sometable? – LMeyer

回答

2

計算大型表的行數需要很長時間。這很自然。某些DBMS存儲記錄的數量,但是,這種類型的DBMS限制了併發性。它應該在表格上的DML操作之前鎖定整個表格。 (整個表鎖是必要的正確地更新的數量。)

ALL_TABLES.NUM_ROWS(或USER_TABLES.NUM_ROWS)的值剛剛通過analyze table ...dbms_stats.gather_table_stats程序產生的統計信息。這不是準確的,也不是實時信息。

如果您不需要確切的行數,您可以使用統計信息。但是你不應該依賴它。它由Oracle優化器使用,但不應用於應用程序。

我不知道爲什麼你必須計算表的行數。 如果您在不頻繁運行的批處理程序中需要它,則可以對錶進行分區以增加並行性。 如果您需要在線計劃中的計數,您應該找到一種不使用計數的方法。

+1

+1但通常情況下,並行和分區是相互獨立的。在較舊的版本中,這種情況並非如此,並且仍然有一些地方需要並行和分區協同工作,例如分區智能連接。但爲了統計所有的行,劃分5個不同進程的範圍可能不會受益於分區。 –

+1

如果您好奇,下面是[平行度粒度]的更多信息(http://docs.oracle.com/cd/E11882_01/server.112/e25523/parallel002.htm#BEIIGIFH)。 –

+0

@jonearles是的,你是對的。感謝您的好意和有用的信息。 – ntalbs

0
select /*+ parallel (5) */ 

似乎並行度爲奇數。那麼,明顯的5是一個奇數,這很奇怪。 DoPs應該是電力的兩倍(見下面的更多信息)。

無論如何,你有使用並行查詢的理由嗎?你有至少五個備用處理器嗎?如果沒有,管理PQ奴隸的開銷很可能至少會導致糟糕的表現。


爲什麼要DOP = n * 2?基於排隊論的建立的啓發式運行超過兩個批處理作業同時導致性能下降。 Find out more.(我認爲排隊理論實際上推薦一個1.8的數字,但由於數據庫作業常常受I/O或磁盤限制,所以我們通常可以用2來獲得)。

我原本說「2的冪」,但主要是因爲多核服務器傾向於擁有2個冪的CPU,但2的倍數更精確,因爲有些機箱有12個CPU或其他一些數字。

現在,如果我們有一個64核心的盒子,5或37的DOP是好的,因爲我們有足夠的CPU來同時運行多個線程。但是如果我們有一個小的四核處理器,那麼只有2,4或8個處理器纔有意義,因爲這是確保所有四個處理器均勻分配工作的唯一值。在一個quadcore盒子上運行五個線程意味着一個CPU將比另外三個CPU做更多的工作;有可能需要更長的時間才能完成,其他三個奴隸等待。因此DOP=5實際上可能導致比DOP=4更長的時間。

DOP=n*2只是一個經驗法則,不是一成不變的。然而,它基於合理的推理,我們應該知道爲什麼我們要做的不同。很明顯,我們應該進行一些實驗來確認我們選擇了正確的DOP(無論我們決定什麼價值)。

+0

爲什麼DOP應該是兩個冪的?你在想散列分區的數量嗎? –

+0

@jonearles - 不,我肯定想到並行查詢。 DOP的經驗法則是2 * CPU(假設系統上沒有其他進程爭用資源)。雖然其原因與散列分區相同 - 即使是分佈,在這種情況下也是工作量。 – APC

+0

由於ORA_HASH的工作方式,2規則的威力對散列分區很有用。但是我找不到任何暗示ORA_HASH或類似函數的源,它們在將塊分配給並行服務器中發揮作用。我認爲,無論是塊還是範圍的列表都存儲了,對於這個查詢來說,取得這個列表並將其分成N個組是很簡單的事情。除以5應該和4或8一樣好。我見過很多Oracle示例和一些不是2的權力的自動DOP。該數字幾乎總是2的倍數,但我想知道是否真的事項。 –

2

的幾個問題提:

  1. 對於「SELECT COUNT(*)FROM表」使用索引,索引的字段必須是非空的,或者索引必須是位圖類型。
  2. 如果已知列中沒有空值,但沒有空值約束,則使用「select column_name不爲空的表中的select count(*)」。
  3. 它當然必須比表格更有效地掃描索引,但是如此多的表格列可能很好。
  4. 如果您確實需要並行索引掃描,請使用parallel_index提示,而不是並行。但只有700萬行,你可能找不到任何並行性需求。
  5. 您需要檢查執行計劃以查看是否正在使用索引和/或並行查詢。
  6. 如果可以使用的估計的行數則可以考慮使用的樣品子句:例如「選擇1000 *從表樣本計數(*)(0.1)」