Подобно SQLServer, где я могу сделать следующее
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (validationStatus, completionStatus)
where completionStatus= N'Complete'
and validationStatus= N'Pending'
Подобно SQLServer, где я могу сделать следующее
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (validationStatus, completionStatus)
where completionStatus= N'Complete'
and validationStatus= N'Pending'
Вы можете создать функциональный индекс в Oracle, который использует тот факт, что значения NULL не сохраняются в индексах b-дерева. Что-то вроде
CREATE INDEX TimeSeriesPeriodSs1
ON TimeSeriesPeriod(
(CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
THEN validationStatus
ELSE NULL
END),
(CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
THEN completionStatus
ELSE NULL
END)
);
Вы можете использовать для этого индекс на основе функций, хотя это не очень приятно для этого сценария:
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (
case when validationStatus= N'Pending' and completionStatus= N'Complete' then validationStatus else null end,
case when validationStatus= N'Pending' and completionStatus= N'Complete' then completionStatus else null end);
Вам нужно было бы сделать запрос where
таким же образом, чтобы он использовал индекс.
select <fields>
from TimeSeriesPeriod
where case when validationStatus= N'Pending' and completionStatus= N'Complete' then validationStatus else null end = N'Pending'
and case when validationStatus= N'Pending' and completionStatus= N'Complete' then completionStatus else null end = N'Complete';
Это было бы очень аккуратно, если вы можете определить (детерминированные) функции для case
. См. здесь для получения дополнительной информации и примеров. Или это, из быстрого Google.
Здесь небольшой вариант ответа Джастина и Алекса, который может сэкономить дополнительное пространство индекса и сделает измененный запрос более читаемым ИМО:
CREATE INDEX TimeSeriesPeriodSs1
ON TimeSeriesPeriod(
(CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
THEN 1
ELSE NULL
END);
SELECT * FROM TimeSeriesPeriod
WHERE 1 = (CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
THEN 1
ELSE NULL
END)
Потенциальная альтернатива/улучшение индексов на основе функций заключается в использовании виртуальных столбцов.
create table TimeSeriesPeriod (
--...
pendingValidation as (
case when completionStatus = N'Complete' and validationStatus= N'Pending'
then 1
else null
) virtual
);
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (pendingValidation);
select * from TimeSeriesPeriod where pendingValidation = 1;
Обратите внимание, что статистика собирается для виртуальных столбцов/основанных на функциях индексов, как и обычные столбцы, поэтому они имеют ненулевую стоимость. Рассмотрите возможность объединения нескольких фильтров в один виртуальный столбец, где это возможно.
create table TimeSeriesPeriod (
--...
incompleteValidationStatus as (
case when completionStatus = N'Complete' and validationStatus != N'Complete'
then validationStatus
else null
) virtual
);
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (incompleteValidationStatus);
select * from TimeSeriesPeriod where incompleteValidationStatus = N'Pending';
select * from TimeSeriesPeriod where incompleteValidationStatus = N'Failed Validation';