В своем операторе SELECT я использую необязательные параметры следующим образом:
DECLARE @p1 INT = 1
DECLARE @p2 INT = 1
SELECT name FROM some_table WHERE (id = @p1 OR @p1 IS NULL) AND (name = @p2 OR @p2 IS NULL)
В этом случае оптимизатор генерирует операции «сканирования индекса» (не поиска) для объекта, который не наиболее эффективен, когдапараметры снабжены ненулевыми значениями.
Если я добавлю подсказку RECOMPILE к запросу, оптимизатор создаст более эффективный план, который использует «поиск».Он работает на моем сервере MSSQL 2008 R2 SP1, и это также означает, что оптимизатор МОЖЕТ построить план, который учитывает только одну логическую ветвь моего запроса.
Как я могу сделать так, чтобы использовать этот план везде, где я хочу, без перекомпиляции?Подсказка USE PLAN, похоже, не работает в этом случае.
Ниже приведен тестовый код:
-- see plans
CREATE TABLE test_table(
id INT IDENTITY(1,1) NOT NULL,
name varchar(10),
CONSTRAINT [pk_test_table] PRIMARY KEY CLUSTERED (id ASC))
GO
INSERT INTO test_table(name) VALUES ('a'),('b'),('c')
GO
DECLARE @p INT = 1
SELECT name FROM test_table WHERE id = @p OR @p IS NULL
SELECT name FROM test_table WHERE id = @p OR @p IS NULL OPTION(RECOMPILE)
GO
DROP TABLE test_table
GO
Обратите внимание, что не все версии SQL-сервера изменят план, как показано на рисунке.