SELECT *
FROM …
WHERE @bar = 'BAR'
AND foo IN ('FOO', 'BAR', 'BAZ')
UNION ALL
SELECT *
FROM …
WHERE @bar = 'BAZ'
AND foo IN ('FOOBAR', 'FOOBAZ')
Это будет наиболее эффективным индекс.
SQL Server
будет просто оптимизировать один из запросов, в зависимости от значения @bar
, и будет использовать индекс на foo
для выполнения оставшегося запроса.
Обновление:
Таблица master
имеет 20,000,000
записи с 2,000,000
записей, имеющих name = 't'
.
Этот запрос:
DECLARE @s INT
SET @s = 2
SELECT *
FROM master
WHERE (@s = 1 AND name IN ('t')) OR
(@s = 2 AND name IN ('zz'))
использует и ничего не возвращает в 4
секунд:
|--Parallelism(Gather Streams)
|--Index Scan(OBJECT:([test].[dbo].[master].[ix_name_desc]), WHERE:([@s]=(1) AND [test].[dbo].[master].[name]='t' OR [@s]=(2) AND [test].[dbo].[master].[name]='zz'))
Этот запрос:
DECLARE @s INT
SET @s = 2
SELECT *
FROM master
WHERE @s = 1 AND name IN ('t')
UNION ALL
SELECT *
FROM master
WHERE @s = 2 AND name IN ('zz')
использует CONCATENATION
из двух отдельных запросов (один из их оптимизируется) и мгновенно возвращается:
|--Concatenation
|--Parallelism(Gather Streams)
| |--Filter(WHERE:(STARTUP EXPR([@s]=(1))))
| |--Index Seek(OBJECT:([test].[dbo].[master].[ix_name_desc]), SEEK:([test].[dbo].[master].[name]='t') ORDERED FORWARD)
|--Filter(WHERE:(STARTUP EXPR([@s]=(2))))
|--Index Seek(OBJECT:([test].[dbo].[master].[ix_name_desc]), SEEK:([test].[dbo].[master].[name]='zz') ORDERED FORWARD)
Это не потерянное, это была моя вторая скорость ввода. –