Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Какви са основните разлики между OPTION(OPTIMIZE FOR UNKNOWN) и OPTION(RECOMPILE)?

Да, ще стане.

Има две основни разлики между OPTION(OPTIMIZE FOR UNKNOWN) и OPTION(RECOMPILE) както може да се види от този цитат от MSDN :

И така, двете основни разлики са:

  1. Кеширане (или не) на плана на заявката.

Обикновено генерираният план за заявка се кешира и използва повторно. OPTIMIZE FOR UNKNOWN не засяга тази характеристика на двигателя. RECOMPILE потиска тази функция и казва на двигателя да отхвърли плана и да не го поставя в кеша.

  1. Използване (или не) на действителни стойности на параметри по време на генериране на план.

Обикновено оптимизаторът "надушва" стойностите на параметрите и ги използва при генериране на плана. OPTIMIZE FOR UNKNOWN потиска тази функция и казва на двигателя да третира всички параметри, сякаш стойностите им са неизвестни. Оптимизаторът има вградени правила и евристики как да използва наличната статистика за различни критерии за филтриране. Вижте Оптимизиране за... Посредствено? за повече информация. Обикновено снифирането на параметри се използва при първото изпълнение на заявката/съхранената процедура и използва стойностите на параметрите по време на първото изпълнение. Генерираният план се кешира и по-късно може да се използва повторно.

Едно неочевидно нещо, което трябва да запомните тук, е, че и в двата случая (нормално без подсказки за заявка и с OPTIMIZE FOR UNKNOWN намек) генерираният план трябва да е валиден и да дава правилен резултат за всеки възможна стойност на параметъра. Той е съобразен с надушените стойности, които са били използвани по време на първото изпълнение в случай нормален/без намек; не е съобразено с конкретна стойност в OPTIMIZE FOR UNKNOWN случай, но все още е валиден, ако параметърът се промени по-късно по някакъв начин.

Това е важно и не позволява на оптимизатора да извърши определени трансформации и опростявания на плана.

OPTION(RECOMPILE) позволява на оптимизатора да вгражда действителните стойности на параметрите по време на всяко изпълнение и оптимизаторът използва действителните стойности на параметрите, за да генерира по-добър план. Не е нужно да се притеснявате, че генерираният план може да не работи с някаква друга стойност на параметъра, защото планът няма да бъде кеширан и използван повторно.

Този ефект е видим най-вече за Условия за динамично търсене заявки. Например:

SELECT ...
FROM T
WHERE
    (@ParamSomeID = 0)
    OR
    (
        @ParamSomeID = -1
        AND
        T.SomeID NOT IN
        (
            SELECT OtherTable.SomeID
            FROM OtherTable
        )
    )
    OR
    (
        T.SomeID IN
        (
            SELECT OtherTable.SomeID
            FROM OtherTable
            WHERE OtherTable.SomeID = @ParamSomeID
        )
    )
OPTION(RECOMPILE)

Ако @ParamSomeID е 0 оптимизаторът ще третира заявката така, сякаш няма WHERE клауза изобщо. В плана не се споменава OtherTable изобщо.

Ако @ParamSomeID е -1 , планът ще се присъедини към T към OtherTable използвайки Left Anti Semi Join и ще сканира цялата OtherTable .

Ако @ParamSomeID е, да речем, 5, планът ще извърши търсене на индекс в уникален индекс на OtherTable и прочете само един ред от OtherTable .

Без OPTION(RECOMPILE) този вид опростяване и трансформация няма да се случи.

Друга причина да използвате OPTION(RECOMPILE) е, когато разпределението на вашите данни е много изкривено. Например, имате таблица с 1M редове. Една колона има стойност 0 в 990K реда и стойности от 1 до 10 в 1K реда. Заявките, които филтрират тази колона, трябва да имат различни планове в зависимост от действителната стойност на филтъра.

И в двата примера по-горе OPTIMIZE FOR UNKNOWN ще генерира посредствен план.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Групирайте редове с разлика, по-малка от 15 дни, и задайте минимална/максимална дата

  2. Week() функция в sql скрипт

  3. Динамичен SQL (предаване на името на таблицата като параметър)

  4. Инструкцията UPDATE е в конфликт с ограничението REFERENCE - SQL Server / TSQL урок, част 76

  5. SQL - Брои срещанията на конкретна дума във всички съхранени процедури