Всем привет.
Есть таблица с такой структурой
create table dbo.ORDERS (ID int, ENABLED int, [CREATIONDATETIME] float, [CLIENTID] float,
[WORKNAME] varchar(100),[WORKPHONE] varchar(100),[FRIEND] varchar(100),[INFO] varchar(100),[ADULTINFO] varchar(100),[WORKHEADMEN] varchar(100)
);
CREATE NONCLUSTERED INDEX [_dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63] ON [dbo].[ORDERS]
(
[CLIENTID] ASC,
[ENABLED] ASC,
[CREATIONDATETIME] ASC,
[ID] ASC
)
INCLUDE([WORKNAME],[WORKPHONE],[FRIEND],[INFO],[ADULTINFO],[WORKHEADMEN]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 95) ON [PRIMARY]
GO
Говорю разработчикам на работе: использовать функции применительно к столбцам в WHERE нельзя, это может привести к сканированию индекса вместо быстрого поиска. На что мне кидают пример запроса по этой таблице:
select o.id from orders o
where convert(datetime, o.CREATIONDATETIME -2)>= '20201020'
- 2 секунды
select o.id from orders o
where creationdatetime >= dbo.DateStrToDate('2020-10-20')
- 1 минута.
DateStrToDate
- CLR функция, которая превращает текст в тип float.
В обоих актуал планах используется сканирование индекса
_dta_index_ORDERS_7_1540200537__K19_K6_K18_K1_7_9_16_34_62_63, только во втором плане дополнительным шагом идёт итератор FILTER со стоимостью 5%. Статистика по индексу была обновлена перед выполнением запроса, фрагментация - 22%, строк в таблице - 7 млн, значения
creationdatetime
идут с 2012 года по текущий день, с уплотнением начиная с 2018 года. Почему время выполнения двух запросов насколько разное?