Oracle
Oracle 忽略索引
我有一個感測器數據表,簡化後如下所示:
DEVICE_ID NUMBER SENSOR_ID NUMBER DATA_TIME NUMBER DATA_VALUE1 NUMBER
該表包含數十億行並按週數分區,DATA_TIME 採用 Unix 時間(自 1970 年以來的毫秒數)。我在這個表上有兩個索引,IX1 在 (DATA_TIME DESC) 和 IX2 在 (DEVICE_ID,SENSOR_ID,DATA_TIME)。IX2 是昨天創建的。
我的查詢想要查看當月一個感測器的數據,如下所示:
SELECT /*+ PARALLEL (12) */ data_time, data_value1 FROM table WHERE device_id = 1041 AND sensor_id = 202 AND data_time BETWEEN 1383304859 *1000 AND 1385464859 *1000 ORDER BY data_time ASC
我驚訝地發現優化器忽略了 IX2 並提出了以下計劃:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 65 | 1365 | 5 (20)| 00:00:01 | | | | | | | 1 | PX COORDINATOR | | | | | | | | | | | | 2 | PX SEND QC (ORDER) | :TQ10001 | 65 | 1365 | 5 (20)| 00:00:01 | | | Q1,01 | P->S | QC (ORDER) | | 3 | SORT ORDER BY | | 65 | 1365 | 5 (20)| 00:00:01 | | | Q1,01 | PCWP | | | 4 | PX RECEIVE | | 65 | 1365 | 4 (0)| 00:00:01 | | | Q1,01 | PCWP | | | 5 | PX SEND RANGE | :TQ10000 | 65 | 1365 | 4 (0)| 00:00:01 | | | Q1,00 | P->P | RANGE | | 6 | PX PARTITION RANGE ITERATOR | | 65 | 1365 | 4 (0)| 00:00:01 | 252 | 256 | Q1,00 | PCWC | | |* 7 | TABLE ACCESS BY LOCAL INDEX ROWID| table | 65 | 1365 | 4 (0)| 00:00:01 | 252 | 256 | Q1,00 | PCWP | | |* 8 | INDEX RANGE SCAN | ix1 | 1 | | 4 (0)| 00:00:01 | 252 | 256 | Q1,00 | PCWP | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 7 - filter("DEVICE_ID"=1041 AND "SENSOR_ID"=202) 8 - access(SYS_OP_DESCEND("DATA_TIME")>=HEXTORAW('38FDD8C8BEA9A4FF') AND SYS_OP_DESCEND("DATA_TIME")<=HEXTORAW('38FDD8DDFAA9A4FF') ) filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATA_TIME"))>=1383304859000 AND SYS_OP_UNDESCEND(SYS_OP_DESCEND("DATA_TIME"))<=1385464859000) Note ----- - automatic DOP: skipped because of IO calibrate statistics are missing
表和索引的統計資訊是最近的。我找到了一些為此語句創建的 SQL 基線並將它們刪除。最重要的是,SQL 調整顧問建議在 (DEVICE_ID,SENSOR_ID,DATA_TIME,DATA_VALUE1) 上創建一個索引。
我通過刪除並重新創建 IX1 解決了這個問題。(其背後的原因是使仍在使用它的任何記憶體計劃無效。)查詢現在在 11 秒後返回 420 行。如果有人可以就發生的事情給我一個很好的理論,我會接受它作為正確答案。