Не видя план выполнения actual
, нельзя сказать наверняка, но, как упомянул @mvisser, - вероятная причина в том, что оптимизатор выбирает лучший индекс, когда вы делаете
SELECT *
или включить столбец DataModelID, чем когда вы этого не сделаете. Здесь есть ряд решений, одним из которых было бы посмотреть план выполнения для запросов, которые выполняются в течение 3 секунд, отметить, какой индекс используется, и использовать индексную подсказку (см. Раздел G) для вынудите оптимизатор использовать этот индекс в ваших запросах, которые не ссылаются на эти столбцы. Я бы не советовал, хотя - слишком много неотвеченных переменных, чтобы считать этот вариант приемлемым.
Вот что я рекомендую:
Во-первых, как упомянул @Lukasz Szozda, это не SARGable:
AND PATINDEX( '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]',U1.IdentityNumber) = 1
Но это:
U1.IdentityNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
Так что я бы сначала исправил это. Далее, самый быстрый и надежный способ решить эту проблему - просто включить DataModelID в свои запросы, даже если они вам не нужны. Вы можете либо отфильтровать этот столбец на уровне приложения, либо создать сохраненный процесс, который заполняет временную таблицу, а затем, для окончательного набора результатов, вы можете извлечь свои результаты из этой временной таблицы, исключая DataModelID.
ВАРИАНТ № 2
Вы можете создать индексированное представление таблицы USERS, которая выглядит примерно так:
CREATE VIEW dbo.vwUSERS_clean
WITH SCHEMABINDING AS
SELECT U1.ID, UserId, U1.IdentityNumber IdentityNumber,
U1.ArabicFirstName, U1.ArabicSecondName, DataModelID, U2.IdentityNumber
FROM USERS U1
WHERE U2.ID IS NOT NULL
AND U1.IdentityNumber <> ''
AND U1.IdentityNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]';
GO
Затем создайте уникальный кластерный индекс для него. Затем вы измените отправленный запрос, чтобы он ссылался на индексированное представление (, например, измените обе ссылки на USERS
на dbo.vwUSERS_clean WITH (NOEXPAND)
).
Обратите внимание, что ROW_NUMBER недопустим в индексированных представлениях, но если вы сделаете ID своим кластеризованным индексом (или первым столбцом в составном кластерном индексе), то добавление ROW_NUMBER() OVER ORDER BY ID
к запросам, которые ссылаются на это индексированное представление, не будет стоить ,