簡體   English   中英

Oracle count(*)花費了太多時間

[英]Oracle count (*) is taking too much time

我試圖從表中獲取count(*) ,該表有近700萬條記錄,返回結果需要一個多小時。

此外,該表還有153列,其中已為列123創建了索引,因此嘗試並行運行以下查詢,但它沒有幫助。

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

請建議是否有其他方式。

當我在Toad的表上運行desc時,索引選項卡保持值為no。 的行。 知道如何在那里更新該值嗎?

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

ALL_TABLES.NUM_ROWS (或USER_TABLES.NUM_ROWS )中的值只是analyze table ...dbms_stats.gather_table_stats過程生成的統計信息。 這不准確,不是實時信息。

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

我不確定為什么你要計算表的行數。 如果您在不經常運行的批處理程序中需要它,則可以對表進行分區以增加並行性。 如果您需要在線計划中的計數,您應該找到一種不使用計數的方法。

有幾個問題需要提及:

  1. 對於“從表中選擇count(*)”以使用索引,索引列必須是非可空的,或者索引必須是位圖類型。
  2. 如果列中已知沒有空值但是對它沒有空約束,則使用“select column(*)from table其中column_name不為null”。
  3. 掃描索引當然必須比表更高效,但是如果有很多表列,你可能會很好。
  4. 如果您確實需要並行索引掃描,請使用parallel_index提示,而不是並行。 但是只有700萬行,你可能不會發現需要並行性。
  5. 您需要檢查執行計划以查看是否正在使用索引和/或並行查詢。
  6. 如果您可以使用估計的行數,那么請考慮使用sample子句:例如“從表樣本中選擇1000 * count(*)(0.1)”
select /*+ parallel (5) */ 

對於並行度來說,似乎是奇數。 嗯,明顯的5是奇數,這很奇怪。 的DOPS應該是二的的多個(見以下更多)。

無論如何,你有理由使用並行查詢嗎? 你有至少五個備用處理器嗎? 如果沒有,管理PQ從站的開銷很可能至少導致性能不佳。


為什么DOP = n * 2? 基於排隊論的已建立的啟發式方法是,同時運行兩個以上的批處理作業會導致性能下降。 了解更多。 (我認為排隊理論實際上建議使用1.8的數字,但由於數據庫作業通常受I / O或磁盤的限制,我們通常可以使用2.)

我最初說的是“2的強大”,但這主要是因為多核服務器往往有一些CPU的功率為2,但2的倍數更准確,因為有些盒子有12個CPU或其他一些數字。

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

DOP=n*2只是一個經驗法則,並不是一成不變的。 然而,它基於合理的推理,我們應該知道為什么我們做了不同的事情。 顯然,我們應該進行一些實驗來確認我們選擇了正確的DOP(無論我們采用什么價值)。

暫無
暫無

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

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