Oracle

計數很慢 Oracle

  • October 19, 2016

這是我的查詢:

SELECT Count(last_upd)
FROM S_CONTACT
WHERE last_upd_by = '0-1' AND LAST_NAME <> 'Wait' AND last_upd  +  1/24 > SYSDATE - (1 / (24 * 60));

返回這個結果需要 84 秒:

COUNT(LAST_UPD)
---------------
43

我不明白為什麼只有 43 個返回行太慢了……

這是執行計劃:

執行計劃

誰能幫我?這是 V$STATNAME

清除期間的活動 txn 計數 1
通過 SQL*Net 從客戶端 497 接收的字節數
通過 SQL*Net 發送到客戶端 14803 的字節
獲取快照 scn 的呼叫:kcmgss 23
呼叫 kcmgas 45
cleanout - ktugct 呼叫次數 12
清理和回滾 - 一致讀取獲得 2
僅清除 - 一致讀取獲得 10
在清理 11 期間送出 txn 計數
一致的變化 450
一致得到 1458915
一致得到 - 考試 458
從記憶體 1458915 獲取一致
此會話使用的 CPU 4485
呼叫開始時使用的 CPU 4493
創建 CR 塊 44
為 CR 1 轉換的目前塊
游標認證 1
數據塊一致讀取 - 應用撤消記錄 59
db 塊更改 12
數據庫時間 8383
檢查臟緩衝區 31
入隊發布 1
入隊請求 1
執行計數 2
檢查了空閒緩衝區 1442014
請求的可用緩衝區 1436612
堆塊壓縮 12
熱緩衝區移動到 LRU 25764 的頭部
立即 (CR) 塊清除應用程序 12
沒有工作 - 一致讀取得到 1458380
打開游標累積 2
作業系統非自願上下文切換 18069
作業系統最大駐留集大小 1956
作業系統頁面錯誤 4
作業系統頁面回收 410
OS 系統使用時間 1868
作業系統使用者使用時間 2625
作業系統自願上下文切換 63594
解析計數(硬)1
解析計數(總數)2
物理讀取字節 11768365056
物理讀取 IO 請求 55724
物理讀取總字節數 11768365056
物理讀取總 IO 請求 55724
物理讀取總計多塊請求 54675
物理讀取 1436568
物理讀取記憶體 1436568
物理讀取記憶體預取 1380844
預取塊在使用前老化 8
遞歸呼叫 1
重做條目 12
重做大小 1272
重做 subscn 最大計數 8
僅回滾 - 一致讀取獲得 40
會話邏輯讀取 1458915
會話 pga 記憶體 -393216
會話 pga 記憶體最大 262144
會話 uga 記憶體最大 299256
共享散列鎖存器升級 - 無需等待 4
排序(記憶)2
排序(行)760
SQL*Net 往返客戶端 9
表掃描塊得到 1458432
表掃描行得到 16656961
表掃描(長表)1
事務表一致讀回滾 4
事務表一致讀取 - 撤消記錄應用 391
使用者撥打 11
使用者 I/O 等待時間 6172
工作區執行 - 最佳 5

我正在使用 Oracle 數據庫 10g 企業版版本 10.2.0.4.0 - 64 位

謝謝

  • 查詢不返回 43 行,而是 1 行包含數字 43
  • 查詢的執行時間不取決於它返回的行數,而是取決於它檢查的行數。
  • 從您的查詢計劃中,您可以看到您的查詢進行了全表掃描。這意味著它從頭到尾讀取表並讀取表的所有 1600 萬行(表掃描行數為16656961)。
  • 為此,它必須讀取大約 11G 數據(物理讀取總字節數 11768365056)並執行 55,000 次讀取操作(物理讀取總 IO 請求55724)。60 秒內 55,000 次讀取(使用者 I/O 等待時間6172)意味著每次讀取 1.1 毫秒。這是一個很好的價值。

您必須減少查詢必須處理的行數。索引可以幫助 Oracle 有效地計算您感興趣的 rowa 的數量。

  • where -clause中最具選擇性的子句​​將是last_upd子句。所以在這個列上做一個索引。
  • 您也應該將其他where -clauses(和select -clause )中的列添加到索引中。因此,Oracle 不必查找表中的索引找到的每個合適的行來獲取last_upd_by和 last_name 值。
  • last_upd_by子句是下一個選擇子句,因此它應該是索引中的下一列。因此,您應該按此順序在列(last_updlast_upd_bylast_name)上創建一個 inex。

根據提供的統計數據,使用者 I/O 等待時間為 6172 分貝時間 8383。

當您將“使用者 I/O”視為主要等待事件時,SQL 調整是最好的答案,特別是添加缺失的索引。由於計劃顯示它正在使用全表掃描,因此您可以在 where 子句中使用的列中添加索引。

引用自:https://dba.stackexchange.com/questions/128870