Анализируя производительность SQL-запроса в Oracle, я заметил странное поведение.Я заметил, что поведение плана Oracle меняется в зависимости от значения, используемого в запросе.
Например, вот моя структура таблицы:
CREATE TABLE "USAGE"
( "ID" NUMBER(11,0) NOT NULL ENABLE,
"CREATED_DATE" TIMESTAMP (6),
"MODIFIED_DATE" TIMESTAMP (6),
"PERIOD" TIMESTAMP (6) NOT NULL ENABLE,
"DOWNLOAD" NUMBER(19,0),
PRIMARY KEY ("ID")
);
CREATE INDEX "USAGE_A0ACFA46" ON "USAGE" ("PERIOD");
CREATE UNIQUE INDEX "USAG_PERIOD_772992E2_UNIQ" ON "USAGE" ("PERIOD");
Когда я выбираю план следующего запроса, я вижу, что к таблице обращается INDEX RANGE SCAN, что ожидается:
explain plan for
select usg.period, sum(usg.download)
from usage usg
where usg.period>=TIMESTAMP '2018-11-30 00:00:00'
group by usg.period;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 18 | 3 (0)| 00:00:01 |
| 1 | SORT GROUP BY NOSORT | | 1 | 18 | 3 (0)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| USAGE | 1 | 18 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | USAG_PERIOD_E67F63D3_UNIQ | 1 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------
Однако, когда я меняю только значение, я заметил, что к таблице обращается TABLE ACCESS FULL, что очень странно для меня:
select usg.period, sum(usg.download)
from usage usg
where usg.period>=TIMESTAMP '2017-11-30 00:00:00'
group by usg.period;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 133 | 2394 | 69 (2)| 00:00:01 |
| 1 | HASH GROUP BY | | 133 | 2394 | 69 (2)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| USAGE | 9505 | 167K| 68 (0)| 00:00:01 |
----------------------------------------------------------------------------
Мой вопроспочему это происходит?Я ожидаю, что Oracle будет использовать INDEX RANGE SCAN, независимо от значения.
Моя база данных - Oracle 11g