Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Проблема: при запросе по View не используется индекс  [new]
KellyLynch
Member

Откуда:
Сообщений: 84
Мне подсунули такой View (не я его сочинил :-) ):

CREATE VIEW [dbo].[TheView]
	AS
WITH sysParam
	AS (
		SELECT 
		CASE WHEN EXISTS (SELECT TOP 1 1 FROM dbo.[System.Parameters] 
			WHERE dbo.[System.Parameters].Variable = 'TheFlag' 
					AND dbo.[System.Parameters].Value = '1')
				THEN 1
		ELSE 0
		END as theFlag
	)
SELECT	[IPCAEDetailID],
		CASE WHEN sysParam.theFlag = 1
				THEN [IPNameNumber]
		ELSE [CAENumber]
		END as [IPNumber]
FROM    dbo.[IPCAEDetail]
INNER JOIN sysParam
	ON 1 = 1


Задумка создателя View была такая: он хотел, чтобы код, делающий запросы по [TheView], не знал, что в данный конкретный момент прячется за полем [TheView].IPNumber: поле [IPCAEDetail].IPNameNumber или поле [IPCAEDetail].CAENumber. Чтобы можно было это “динамически регулировать” через некую другую таблицу [System.Parameters].

И всё работает, но: при этом НЕ используются индексы, которые таблица [IPCAEDetail] имеет на этих полях [IPCAEDetail].IPNameNumber и [IPCAEDetail].CAENumber. При таком вот запросе:

select * from [TheView] ipc where ipc.IPNumber = '426976225'


происходит Scan по всей таблице [IPCAEDetail]. Тогда как “select * from [IPCAEDetail] ipc where ipc.CAENumber = '426976225'” использует индекс, имеющийся для [IPCAEDetail].CAENumber.

Вопрос: можно ли как-то “заставить” SQL использовать эти индексы при поиске по этому “динамически определяемому через CASE ...” полю [TheView].IPNumber ?
15 окт 18, 12:52    [21704054]     Ответить | Цитировать Сообщить модератору
 Re: Проблема: при запросе по View не используется индекс  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36686
Все or придется писать через union all.

Т.е. как-то так:

CREATE VIEW [dbo].[TheView]
	AS
WITH sysParam
	AS (
		SELECT 
		CASE WHEN EXISTS (SELECT TOP 1 1 FROM dbo.[System.Parameters] 
			WHERE dbo.[System.Parameters].Variable = 'TheFlag' 
					AND dbo.[System.Parameters].Value = '1')
				THEN 1
		ELSE 0
		END as theFlag
	)
SELECT	[IPCAEDetailID],
		[IPNumber] = [IPNameNumber]
FROM    dbo.[IPCAEDetail]
where exists ( select * from sysParam x where x.theFlag = 1 )
union all 
SELECT	[IPCAEDetailID],
		[IPNumber] = [CAENumber]
FROM    dbo.[IPCAEDetail]
where not exists ( select * from sysParam x where x.theFlag = 1 )


Условия из cte тоже неплохо бы убрать из под case.

Сообщение было отредактировано: 15 окт 18, 13:03
15 окт 18, 12:59    [21704069]     Ответить | Цитировать Сообщить модератору
 Re: Проблема: при запросе по View не используется индекс  [new]
court
Member

Откуда:
Сообщений: 1956
select [IPCAEDetailID],[IPNameNumber] as IPNumber
from dbo.[IPCAEDetail]
where exists (...)
union all
select [IPCAEDetailID],[CAENumber] as IPNumber
from dbo.[IPCAEDetail]
where NOT exists (...)
15 окт 18, 13:01    [21704073]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить