Въведение
Документацията на продукта на SQL Server е малко по-лека по темата за целите на редовете . Основните официални препратки са в:
- Съвети (Transact-SQL) – Заявка (
FAST
). иDISABLE_OPTIMIZER_ROWGOAL
намеци) - DBCC TRACEON – Флагове за проследяване (Transact-SQL) (флаг за проследяване 4138)
- Изпълнението на заявката може да отнеме много време, ако оптимизаторът на заявки използва оператора Top (KB 2667211)
Когато хората поискат повече информация, отколкото се съдържа там, обикновено ги насочвам към едно или повече от следните:
- Цели на редове в действие от екипа за оптимизиране на заявки на SQL Server
- Преразгледани цели на редовете – БЪРЗИ насоки и от екипа за оптимизиране на заявки на SQL Server
- Головете на редовия гол от Барт Дънкан
- В оптимизатора:Цели на редовете в дълбочина от мен
- Съветът за настройка на SSIS, който всеки пропуска, от Роб Фарли
За да обобщим накратко:Функцията за цел на реда позволява на оптимизатора да генерира план за изпълнение (или част(и) от план за изпълнение) с цел бързо връщане на определен брой редове. Това е в контраст с нормалното поведение (без цел за ред), което има за цел да намери план, оптимизиран за пълния потенциален набор от резултати.
Стратегията за цел на ред обикновено означава предпочитане на неблокиращи операции за навигация (например, присъединяване на вложени цикли, търсене на индекси и справки) пред блокиращи, базирани на набор операции, като сортиране и хеширане. Това може да бъде полезно винаги, когато клиентът може да се възползва от бързо стартиране и постоянен поток от редове (с може би по-дълго общо време за изпълнение – вижте публикацията на Роб Фарли по-горе). Има и по-очевидни и традиционни употреби, напр. при представяне на резултати страница по страница.
Естествено, има елемент на риск, свързан с плана за цели редове. Ако всичко се разиграва в общи линии, както очаква оптимизаторът (предвид наличната информация и направените предположения за моделиране), планът за изпълнение ще започне да предава желания брой редове по-бързо и ефективно, отколкото би било без целта на реда.
За съжаление, когато стратегията за гол в редовете се обърка, това може да бъде катастрофа в представянето (вижте публикацията на Барт Дънкан). Това може да се случи, например, когато оптимизаторът разполага с непълна информация, срещне неблагоприятно разпределение на данни или направи опасно предположение. Във всеки случай причината за лошата производителност почти винаги е, че много повече редове трябва да бъдат обработени по време на изпълнение, отколкото е очаквал оптимизаторът.
Може да бъде много полезно да идентифицирате областите на плана за изпълнение, засегнати от целта на реда, защото ни помага да разберем защо оптимизаторът направи избора, който направи. Това е особено важно, когато логиката на целта на реда води до неблагоприятен резултат. Без разбиране на ролята, която играе целта на реда, може да изглежда така, сякаш оптимизаторът просто е подценил броя на редовете, което кара хората да търсят на грешните места (например статистика) за основна причина.
Задаване на цели на редове
Много по-лесно е да се търсят ефектите на целта на реда, ако човек знае какви неща могат да доведат до поставяне на цел на ред. Официалната документация често говори за целите на редовете, свързани с ключовите думи TOP
, FAST
, IN
и EXISTS
. Това може да остави читателя с непълно или подвеждащо разбиране, така че си струва да отделите малко време, за да изясните някои аспекти.
Искам да подчертая отпред, че използването на специфични ключови думи за T-SQL в заявкане гарантира, че ще бъде зададена цел на реда . Официалната документация споменава определени ключови думи, за да помогне на хората да идентифицират често срещани сценарии, при които целите на редове могат бъде въведен, без да навлиза в твърде много технически подробности.
Втора обща точка, която трябва да имате предвид е, чецел за ред се задава само когато целта би била по-малка от обичайната оценка . В края на краищата, няма много смисъл да се генерира фрагмент на план, оптимизиран за 100 реда, ако така или иначе се очаква цялото нещо да произведе само 50 реда. За да бъде допълнително ясно, тази точка винаги важи за всички начини, по които може да се зададе цел за ред. Ако очаквате гол на ред, но не виждате такъв, това е вероятна причина.
И накрая, за преамбюла, имайте предвид, че целите на редовете са нещо за оптимизиране, базирано на разходите; целта на ред засяга избора на оптимизатора, така че ако няма избор, който да се направи (т.е. тривиален план), няма ефект на целта на реда.
Нека сега да разгледаме нещата, които могат да задават цел на ред:
БЪРЗО и ТОП
Използване на FAST
намек за заявка е надежден начин да зададете цел на ред в корена на плана за изпълнение (при спазване на общите изключения, отбелязани по-горе). A SET ROWCOUNT n
оператор също така задава подобна цел за редове от най-високо ниво (когато n
не е нула, разбира се) за твърденията, за които се отнася.
Писане на TOP
клаузата в заявка също много често води до цел на ред. Докато готовият план за изпълнение включва физически оператор Top, е вероятно поне част от плана под оператора Top да е била засегната от цел на ред (отново се прилагат общите условия).
Имайте предвид, че Топ операторите въведени от оптимизатора на заявки (без посочен от заявката TOP
клауза) може също да зададе цел за ред. Това е важно, тъй като има всякакви начини, по които това може да се случи, например при филтриране на обикновен номер на ред, както е показано в следната заявка на AdventureWorks:
ИЗБЕРЕТЕ THN.RowNum, THN.TransactionID ОТ ( ИЗБЕРЕТЕ TH.TransactionID, RowNum =ROW_NUMBER() НАД ( ORDER BY TH.TransactionID ASC) ОТ Production.TransactionHistory КАТО TH WHERE TH.ProductID =THN.WHER КАТО КАТО>=10 И THN.RowNum <20ORDER BY THN.RowNum ASC;
Планът за изпълнение на тази заявка включва оператор Top, добавен от оптимизатора (за ограничаване на броя на обработените редове до 20):