日期範圍查詢上的 oracle 性能
我正在嘗試計算某個組織在某個時間範圍內傳遞的訂單數量。但是我發現下面的查詢(時間範圍為 2 天)比每天執行兩個單獨的查詢要慢得多。
SELECT COUNT(*) FROM ORDER_HISTORY WHERE organization = 'BA' AND TIMESTAMP > = TO_DATE('2016-01-05', 'YYYY-MM-DD') AND TIMESTAMP<= TO_DATE('2016-01-05', 'YYYY-MM-DD')+2;
我在列上有一個索引,在列上有
timestamps
另一個索引organization
這是我的表的架構。該列
timestamp
的類型為DATE
。超過 2 天的查詢執行計劃使用索引 on
organization
:超過 1 天的查詢執行計劃使用索引 on
timestamp
:有一些統計數據:
SELECT COUNT(*) FROM ORDER_HISTORY WHERE ORGANIZATION = 'BA' ;
給出 2359847。
SELECT COUNT(*) FROM ORDER_HISTORY WHERE TIMESTAMP > = TO_DATE('2016-01-05', 'YYYY-MM-DD') AND TIMESTAMP<= TO_DATE('2016-01-05', 'YYYY-MM-DD')+1;
給出 9260。2 天內的相同查詢給出 16510。
為什麼我會得到 oracle DB 引擎的那種奇怪行為?
原因是基於成本的優化器在記憶體中有一個來自先前選擇的計劃,其中給定組織的記錄數(即“LOL”)要小得多,約為 14000。當計劃在記憶體中時,CBO不再關心參數值。採用:
WHERE organization || '' = 'BA'
在我看來,優化器統計資訊要麼已過時,要麼您有數據偏差(即您在 ORGANIZATION 列中有流行和不流行)。優化器估計過濾器
ORGANIZATION = 'BA'
返回 14898 行,這與實際結果有很大不同。dbms_stats.gather_table_stats
應該解決這個問題。** 根據螢幕截圖,“LOL”似乎是與組織一起使用的值EXPLAIN
,我建議發布實際執行計劃。您還可以在 2 列(組織、時間戳)上創建擴展統計資訊。
此外,始終檢查實際執行計劃 (
dbms_xplan.display_cursor
),而不是explain
.更新
還有一件事可能有助於調查問題。
v$sql
我還建議在/中查找查詢(或查詢)v$sqlarea
並檢查其成本。此外,顯示優化器是否考慮和使用不同計劃的v$sql
hasis_bind_aware
和is_bind_sensitive
列取決於綁定變數的不同值。關於為什么生成多個計劃的其他詳細資訊V$SQL_SHARED_CURSOR
系統視圖顯示了現有子游標未與新游標共享的原因。