Учитывая следующее в базе данных SQL Server 2014:
create table t
(
c1 int primary key,
c2 datetime2(7),
c3 nvarchar(20),
c4 as cast(dbo.toTimeZone(c2, c3, 'UTC') as date) persisted
);
create index i on t (c4);
declare @i int = 0;
while @i < 10000
begin
insert into t (c1, c2, c3) values
(@i, dateadd(day, @i, '1970-01-02 03:04:05:6'), 'Asia/Manila');
set @i = @i + 1;
end;
toTimeZone
- это CLR UDF, который преобразует a datetime2
в часовом поясе в datetime2
в другой часовой пояс.
Когда я запускаю следующий запрос:
select c1
from t
where c4 >= '1970-01-02'
and c4 <= '1970-03-04';
План выполнения, за которым следует SQL Server, указывает, что i
не используется.
Вместо этого выполняется сканирование неявного индекса на PK, за которым следует несколько скалярных вычислений, прежде чем, наконец, фильтр, используя предикаты запроса. Планом выполнения, который я ожидал, является проверка на i
.
Используйте SSDT-проект в этот файл ZIP, чтобы попытаться воспроизвести проблему. Он включает в себя ложное определение CLR UDF. Включен также план выполнения, который я получаю.