ОПТИМИЗАТОР ЗАПРОСОВ В sql server И СТАТИСТИКА ·...

41
ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей ([email protected]) ООО “Предприятие “НИКС”

Upload: others

Post on 23-Sep-2020

25 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

ОПТИМИЗАТОР ЗАПРОСОВ

В SQL SERVER И СТАТИСТИКА

Олонцев Сергей ([email protected])

ООО “Предприятие “НИКС”

Page 2: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 3: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 4: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 5: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

0

500

1000

1500

2000

2500

3000

3500

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

DENSITY = 1 / DISTINCT ROWS COUNT

Page 6: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Зачем нам это нужно?

Производительность и стабильность

Page 7: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

О чем эта презентация?

Page 8: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Начинаем погружение ...

Page 9: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

INDEX SEEK + KEY\RID LOOKUP vs.

TABLE SCAN

Пример

Page 10: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

USE [TEST]; GO IF OBJECT_ID('[dbo].[test_table]', 'U') IS NOT NULL DROP TABLE [dbo].[test_table]; GO CREATE TABLE [dbo].[test_table]( [i] int NOT NULL, [c] varchar(100) NOT NULL DEFAULT '##########' ); GO CREATE NONCLUSTERED INDEX [IX_CL_i] ON [dbo].[test_table] ( [i] ASC ); GO INSERT INTO [dbo].[test_table] ( [i] ) VALUES ( 1 ) GO 100000 INSERT INTO [dbo].[test_table] ( [i] ) VALUES ( 2 ) GO

Page 11: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

USE [TEST]; GO SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = 1 OPTION (RECOMPILE); GO SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = 2 OPTION (RECOMPILE); GO

Page 12: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Просмотр статистики

Page 13: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 14: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 15: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей
Page 16: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Dynamic Management Views \ DBCC

sys.stats sys.stats_columns

DBCC SHOW_STATISTICS ( table_or_indexed_view_name , target ) [ WITH [ NO_INFOMSGS ] < option > [ , n ] ] < option > :: = STAT_HEADER | DENSITY_VECTOR | HISTOGRAM

Page 17: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Опции базы данных AUTO_CREATE_STATISTICS

AUTO_UPDATE_STATISTICS AUTO_UPDATE_STATISTICS_ASYNCHRONOUSLY

Page 18: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Управление статистикой

CREATE STATISTICS

FULLSCAN, SAMPLE number { PERCENT | ROWS }

NORECOMPUTE

UPDATE STATISTICS

FULLSCAN, SAMPLE number { PERCENT | ROWS }, RESAMPLE

ALL | COLUMNS | INDEX

NORECOMPUTE

DROP STATISTICS

Page 19: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Пример из практики

Query Timeout

Page 20: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Manual vs. Auto Updates

Page 21: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Когда нужно обновлять вручную

После BULK LOAD

Когда требуется большая точность

MULTI COLUMN STATISTICS

FILTERED STATISTICS

UPDATE STATISTICS PLAN RECOMPILATION

Page 22: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Наблюдение

SQL Profiler

Performance > Auto Stats

XEvents

auto_stats

Page 23: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Пример из практики

REORGANIZE INDEX ≠ UPDATE STATISTICS

Page 24: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Проблема Оптимизатор не может определить значение предиката

на момент компиляции.

DECLARE @i int = 2; SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = @i; GO SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = (SELECT MAX([j]) FROM [dbo].[j_table]); GO SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = dbo.fn_test_value(1); GO

Page 25: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Решение: параметризация

Stored Procedures (Parameter Sniffing)

CREATE PROCEDURE [dbo].[sp_test] @i int AS BEGIN SET NOCOUNT ON; SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = @i; END GO

Page 26: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

НО!!!

CREATE PROCEDURE [dbo].[sp_test2] @i int AS BEGIN SET NOCOUNT ON; SET @i = @i / 2; SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] = @i; END GO

Не надо изменять параметр внутри хранимой процедуры.

Page 27: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

DBCC FREEPROCCACHE

EXECUTE [dbo].[sp_test2] @i = 1

Page 28: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

DBCC FREEPROCCACHE

EXECUTE [dbo].[sp_test2] @i = 2

Page 29: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Проблема: неточная статистика

Page 30: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

#temp_tables vs. @table_variables

SQL Server не создает статистику для табличной

переменной, но делает это для временной таблицы.

Оптимизатор при составлении плана запроса будет

считать, что в табличной переменной только 1 строка.

Очевидно, что это может приводить к не самому

лучшему плану запроса.

Page 31: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Проблема: выражения в предикате

SELECT [i], [c] FROM [dbo].[test_table] WHERE power([i], 0) = 1 OPTION (RECOMPILE); GO SELECT [i], [c] FROM [dbo].[test_table] WHERE [i] * LEN([c]) = 1 OPTION (RECOMPILE); GO

• Преобразовать выражение

• Computed column

Page 32: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Связанные значения в столбцах

CREATE TABLE [dbo].[Hotels]( [hotel_id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [stars] [int] NOT NULL, [price_per_night] [decimal](6, 2) NOT NULL, [description] [nvarchar](max) NOT NULL DEFAULT ('##########') ) GO CREATE NONCLUSTERED INDEX [IX_NC_stars_price] ON [dbo].[Hotels] ( [stars] ASC, [price_per_night] ASC ) GO

Page 33: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

WITH HotelTypes (min_price, max_price, stars) AS ( SELECT 10, 29, 2 UNION ALL SELECT 31, 51, 3 UNION ALL SELECT 49, 81, 4 UNION ALL SELECT 79, 150, 5 ) INSERT INTO [dbo].[Hotels] (stars, price_per_night) SELECT stars, min_price + ABS(CHECKSUM(NEWID())) % (max_price - min_price) FROM HotelTypes; GO 25000 UPDATE STATISTICS Hotels WITH FULLSCAN; GO ALTER INDEX [IX_NC_stars_price] ON [dbo].[Hotels] REBUILD GO

Page 34: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

SELECT * FROM [dbo].[Hotels] WHERE stars = 5 and price_per_night < 80 OPTION (RECOMPILE);

Page 35: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

CREATE STATISTICS [price_stars_eq_5] ON [dbo].[Hotels]([price_per_night]) WHERE stars = 5;

SELECT * FROM [dbo].[Hotels] WHERE stars = 5 and price_per_night < 80 OPTION (RECOMPILE);

Page 36: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Read-only Databases

Read-only Databases

Snapshots

Page 37: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

* ЭТО НЕ РЕКЛАМА

tempdb

Page 38: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

О самой частой причине выбора нестабильного/неэффективного плана

запроса, или Оценка Кардинальности: что это такое, и как с ней бороться

Алексей Эксаревский

XEvents

channel = debug

event = inaccurate_cardinality_estimate

Page 39: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Ссылки

http://www.sqlcmd.ru/density-selectivity-cardinality-part01.html

http://sqlblog.com/blogs/elisabeth_redei/archive/2009/03/01/lies-

damned-lies-and-statistics-part-i.aspx

http://msdn.microsoft.com/en-us/library/ms190397.aspx

http://www.sqlservercentral.com/articles/Stairway+Series/72446/

http://www.simple-talk.com/sql/sql-training/questions-about-sql-

server-distribution-statistics/

http://www.simple-talk.com/sql/t-sql-programming/13-things-you-

should-know-about-statistics-and-the-query-optimizer/

Page 40: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Существуют три вида лжи: ложь, наглая ложь,

и статистика

Эпилог

Page 41: ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА · ОПТИМИЗАТОР ЗАПРОСОВ В SQL SERVER И СТАТИСТИКА Олонцев Сергей

Вопросы

[email protected]