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

Сравнете планове за изпълнение в SQL Server

Администраторът на база данни винаги полага усилия да настрои производителността на заявките на SQL Server. Първата стъпка в настройката на производителността на заявката е да се анализира планът за изпълнение на заявка. При някои условия SQL Server Query Optimizer може да създаде различни планове за изпълнение. На този етап бих искал да добавя някои бележки относно SQL Server Query Optimizer. SQL Server Query Optimizer е базиран на разходите оптимизатор, който анализира плановете за изпълнение и решава оптималния план за изпълнение на заявка. Важната ключова дума за SQL Server Query Optimizer е оптимален план за изпълнение, който не е непременно най-добрият план за изпълнение. Ето защо, ако SQL Server Query Optimizer се опита да намери най-добрия план за изпълнение за всяка заявка, това отнема допълнително време и причинява щети на производителността на SQL Server Engine. В SQL Server 2016 Microsoft добави нова способност към SQL Server Management Studio, наречена Compare Showplan. Тази функция ни позволява да сравним два различни плана за изпълнение. В същото време можем да използваме тази опция офлайн, което означава, че не е необходимо да свързваме екземпляра на SQL Server. Представете си, че пишете заявка и тази заявка се представя добре в TEST среда, но в PROD (производствена среда) се представя много лошо. За да се справим с този проблем, трябва да сравним плановете за изпълнение. Преди тази функция отваряхме две SQL Server Management Studios и донасяхме планове за изпълнение един до друг, но този метод беше много неудобен.

Как да сравним два плана за изпълнение?

В тази демонстрация ще използваме базата данни AdventureWorks и ще сравним два плана за изпълнение, които имат различна версия на модела за оценка на кардиналността, и ще открием тази разлика с Compare Showplan.

Първо ще отворим нов прозорец за заявка в SQL Server Management Studio и щракнете върху Включи действителен план за изпълнение и след това изпълнете следната заявка.

SELECT 
        soh.[SalesPersonID]
        ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName]
        ,e.[JobTitle]
        ,st.[Name] AS [SalesTerritory]
        ,soh.[SubTotal]
        ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] 
    FROM [Sales].[SalesPerson] sp 
        INNER JOIN [Sales].[SalesOrderHeader] soh 
        ON sp.[BusinessEntityID] = soh.[SalesPersonID]
        INNER JOIN [Sales].[SalesTerritory] st 
        ON sp.[TerritoryID] = st.[TerritoryID] 
        INNER JOIN [HumanResources].[Employee] e 
        ON soh.[SalesPersonID] = e.[BusinessEntityID] 
		INNER JOIN [Person].[Person] p
		ON p.[BusinessEntityID] = sp.[BusinessEntityID]

В тази стъпка ще запазим първия си план за изпълнение. Щракнете с десния бутон навсякъде в плана за изпълнение и щракнете върху Запазване на плана за изпълнение като и запазете плана за изпълнение като ExecutionPlan_CE140.sqlplan.

Сега ще отворим нов раздел за заявка в SQL Server Management Studio и ще изпълним заявката по-долу. В тази заявка ще добавим подсказката за заявка FORCE_LEGACY_CARDINALITY_ESTIMATION в края на заявката, която принуждава да се използва по-стара версия на модела за оценка на кардиналността.
Задачата на Оценка на кардиналността е да предвидим колко реда ще върне нашата заявка.

SELECT 
        soh.[SalesPersonID]
        ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName]
        ,e.[JobTitle]
        ,st.[Name] AS [SalesTerritory]
        ,soh.[SubTotal]
        ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] 
    FROM [Sales].[SalesPerson] sp 
        INNER JOIN [Sales].[SalesOrderHeader] soh 
        ON sp.[BusinessEntityID] = soh.[SalesPersonID]
        INNER JOIN [Sales].[SalesTerritory] st 
        ON sp.[TerritoryID] = st.[TerritoryID] 
        INNER JOIN [HumanResources].[Employee] e 
        ON soh.[SalesPersonID] = e.[BusinessEntityID] 
INNER JOIN [Person].[Person] p
	ON p.[BusinessEntityID] = sp.[BusinessEntityID]
	OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'));

Ще щракнем върху Сравни Showplan и изберете предишен план за изпълнение, който е записан като ExecutionPlan_CE140.sqlplan.

Следното изображение илюстрира първия екран на плана за сравнение на изпълнение на SQL Server и подчертаните в розов цвят зони дефинират подобни операции.

Ако щракнем върху който и да е оператор в долния или горния екран на план за изпълнение, SQL Server Management Studio подчертава други подобни оператори. От дясната страна на панела можете да намерите свойства и подробности за сравнение на свойства.

В тази стъпка ще променим опциите за анализ на ShowPlan и ще подчертаем несъответстващия оператор. В долната част на екрана можем да видим Анализ на Showplan панел. Ако изчистим Открояване на подобни операции и изберете Открояване на оператори, които не съответстват на подобни сегменти, SQL Server Management Studio подчертава ненадминат оператор. След това щракнете върху Избор на оператори в долния и горния план за изпълнение в панела. SQL Server Management Studio сравнява свойствата на избраните оператори и поставя знаци за неравенство на неидентичните стойности.

Ако анализираме този екран по-подробно, първото нещо е Версия на модела за оценка на кардиналността разлика. Първата версия на заявката е 70, а втората е 140. Тази разлика засяга Прогнозен брой редове . Основната причина, която причинява различнияПрогнозен брой редове е различна версия на оценката на кардиналността. По този начин версията за оценка на кардиналността пряко засяга прогнозните показатели на заявката. За това сравнение на заявката можем да заключим, че заявката, чиято версия на Cardinality Estimation е 140, се представя по-добре, тъй като прогнозният брой редове е близо до Действителния брой редове . Този случай може да бъде изяснен от таблицата по-долу.

[table id=50 /]

Ако искаме да виждаме планове за изпълнение един до друг на същия екран, можем да щракнем върху Превключване на ориентацията на разделителя .

Сега ще направим още една демонстрация. Ще разгледаме заявката по-долу и ще сравним плановете за изпълнение преди и след създаването на индекс.
Когато разгледаме плана за изпълнение на заявката по-долу, той препоръчва създаване на неклъстериран индекс.

SELECT [CarrierTrackingNumber] 
FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12

Ще приложим препоръчания индекс и ще изпълним отново същата заявка.

CREATE NONCLUSTERED INDEX Index_NC
ON [Sales].[SalesOrderDetail] ([SalesOrderDetailID])
GO
SELECT [CarrierTrackingNumber] 
FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12

В тази последна стъпка ще сравним плановете за изпълнение.

На горното изображение можем да получим няколко части информация за плановете за изпълнение. Но основната разлика е Логическата операция поле. Един от тях е Index Seek и друг е Индексно сканиране и тази диференциация на операцията води до различни оценени и действителни метрични стойности. И накрая, операторът Index Seek работи по-добре от оператора Index Scan.

Заключения

Както споменахме в статията, функцията Compare Showplan предлага някои предимства за разработчика на база данни или администратора. Някои от тях могат да се преброят като:

  • Лесно за сравнение между два плана за изпълнение.
  • Лесно за откриване на проблеми с производителността на заявките в различни версии на SQL Server.
  • Лесно за откриване на проблеми с производителността на заявките в различни среди.
  • Просто изяснява промените в плана за изпълнение преди и след създаването на индекса.

Препратки

  • Оценка на кардиналността (SQL сървър)
  • Ръководство за архитектура за обработка на заявки

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. TODATETIMEOFFSET() Примери в SQL Server

  2. 5 начина да коригирате грешката „Деление на нула“ в SQL Server (Msg 8134)

  3. Разделете дял на две в SQL Server (T-SQL)

  4. Какво има с (nolock) в SQL Server?

  5. Любими трикове за настройка на производителността