Комментарии 1
С вычисляемыми столбцами по varchar(max)/nvarchar(max) колонкам есть ещё одна забавная штука, с которой столкнулись недавно.
В msdn пишут, что для varchar/nvarchar колонок стоит явно указывать длину и это правильно, но не пишут, что даже с явной длиной есть шанс, что индекс по вычисляемому столбцу не будет работать. Индекс по replaced_txt не работает, а если явно его указать план будет просто чудесный — скан некластерного индекса, лукап и фильтр после лукапа.
С replaced_txt2 индекс работает нормально, причём оба столбца Deterministic, Indexable и Precise.
CREATE TABLE t (id int, txt nvarchar(max));
INSERT INTO t
VALUES (1, N'1 str'), (2, N'2 str');
SELECT * FROM t;
ALTER TABLE t
ADD replaced_txt AS CAST (LEFT(REPLACE(REPLACE (REPLACE(txt, N'str', N'new str'), N'1', N'This is first replaced'), N'2', N'This is second replaced'), 50) AS nvarchar(50));
SELECT * FROM t;
CREATE INDEX ix_r ON t (replaced_txt);
SET STATISTICS XML ON;
SELECT replaced_txt
FROM t
WHERE replaced_txt = N'This is first replaced new str'
SET STATISTICS XML OFF;
SET STATISTICS XML ON;
SELECT replaced_txt
FROM t WITH (INDEX(ix_r))
WHERE replaced_txt = N'This is first replaced new str'
SET STATISTICS XML OFF;
ALTER TABLE t
ADD replaced_txt2 AS LEFT(REPLACE(REPLACE (REPLACE(CAST(txt AS nvarchar(50)), N'str', N'new str'), N'1', N'This is first replaced'), N'2', N'This is second replaced'), 50);
CREATE INDEX ix_r2 ON t (replaced_txt2);
SET STATISTICS XML ON;
SELECT replaced_txt2
FROM t
WHERE replaced_txt2 = N'This is first replaced new str'
SET STATISTICS XML OFF;
DECLARE @id int = OBJECT_ID('dbo.t')
SELECT
COLUMNPROPERTY(@id,'replaced_txt2','IsDeterministic') AS 'Deterministic',
COLUMNPROPERTY(@id,'replaced_txt2','IsIndexable') AS 'Indexable',
COLUMNPROPERTY(@id,'replaced_txt2','IsPrecise') AS 'Precise';
SELECT
COLUMNPROPERTY(@id,'replaced_txt','IsDeterministic') AS 'Deterministic',
COLUMNPROPERTY(@id,'replaced_txt','IsIndexable') AS 'Indexable',
COLUMNPROPERTY(@id,'replaced_txt','IsPrecise') AS 'Precise';
DROP TABLE t;
В msdn пишут, что для varchar/nvarchar колонок стоит явно указывать длину и это правильно, но не пишут, что даже с явной длиной есть шанс, что индекс по вычисляемому столбцу не будет работать. Индекс по replaced_txt не работает, а если явно его указать план будет просто чудесный — скан некластерного индекса, лукап и фильтр после лукапа.
С replaced_txt2 индекс работает нормально, причём оба столбца Deterministic, Indexable и Precise.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Производительность вычисляемых столбцов в SQL Server