Added AQP/IQP demos

This commit is contained in:
pmasl
2019-05-03 09:25:44 -07:00
parent 68a5d6f9f9
commit 02b01d6d3c
11 changed files with 322 additions and 23 deletions
@@ -3,7 +3,7 @@
-- bigger - so you can see more impactful
-- Intelligent QP demonstrations (aka.ms/iqp)
--
-- Script last updated 10/02/2018
-- Script last updated 05/03/2019
--
-- Database backup source: aka.ms/wwibak
--
@@ -100,4 +100,4 @@ GO
UPDATE Fact.OrderHistoryExtended
SET [WWI Order ID] = [Order Key];
GO
GO
@@ -9,7 +9,17 @@
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
USE WideWorldImportersDW;
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 150;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
-- Compare execution time and distinct counts
@@ -0,0 +1,54 @@
-- ******************************************************** --
-- Batch mode Adaptive Join
-- See https://aka.ms/IQP for more background
-- Demo scripts: https://aka.ms/IQPDemos
-- This demo is on SQL Server 2017 and Azure SQL DB
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 140;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
-- Show with Live Query Stats
SELECT [fo].[Order Key], [si].[Lead Time Days], [fo].[Quantity]
FROM [Fact].[Order] AS [fo]
INNER JOIN [Dimension].[Stock Item] AS [si]
ON [fo].[Stock Item Key] = [si].[Stock Item Key]
WHERE [fo].[Quantity] = 360;
GO
-- Inserting quantity row that doesn't exist in the table yet
DELETE [Fact].[Order]
WHERE Quantity = 361;
INSERT [Fact].[Order]
([City Key], [Customer Key], [Stock Item Key], [Order Date Key], [Picked Date Key], [Salesperson Key], [Picker Key], [WWI Order ID], [WWI Backorder ID], Description, Package, Quantity, [Unit Price], [Tax Rate], [Total Excluding Tax], [Tax Amount], [Total Including Tax], [Lineage Key])
SELECT TOP 5 [City Key], [Customer Key], [Stock Item Key],
[Order Date Key], [Picked Date Key], [Salesperson Key],
[Picker Key], [WWI Order ID], [WWI Backorder ID],
Description, Package, 361, [Unit Price], [Tax Rate],
[Total Excluding Tax], [Tax Amount], [Total Including Tax],
[Lineage Key]
FROM [Fact].[Order];
GO
-- Show with Live Query Stats
SELECT [fo].[Order Key], [si].[Lead Time Days], [fo].[Quantity]
FROM [Fact].[Order] AS [fo]
INNER JOIN [Dimension].[Stock Item] AS [si]
ON [fo].[Stock Item Key] = [si].[Stock Item Key]
WHERE [fo].[Quantity] = 361;
GO
@@ -0,0 +1,46 @@
-- ******************************************************** --
-- Batch mode Memory Grant Feedback
-- See https://aka.ms/IQP for more background
-- Demo scripts: https://aka.ms/IQPDemos
-- This demo is on SQL Server 2017 and Azure SQL DB
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 140;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
-- Intentionally forcing a row underestimate
CREATE OR ALTER PROCEDURE [FactOrderByLineageKey]
@LineageKey INT
AS
SELECT [fo].[Order Key], [fo].[Description]
FROM [Fact].[Order] AS [fo]
INNER HASH JOIN [Dimension].[Stock Item] AS [si]
ON [fo].[Stock Item Key] = [si].[Stock Item Key]
WHERE [fo].[Lineage Key] = @LineageKey
AND [si].[Lead Time Days] > 0
ORDER BY [fo].[Stock Item Key], [fo].[Order Date Key] DESC
OPTION (MAXDOP 1);
GO
-- Compiled and executed using a lineage key that doesn't have rows
EXEC [FactOrderByLineageKey] 8;
GO
-- Execute this query a few times - each time looking at
-- the plan to see impact on spills, memory grant size, and run time
EXEC [FactOrderByLineageKey] 9;
GO
@@ -10,12 +10,18 @@
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 150;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
-- Row mode due to hint
SELECT [Tax Rate],
[Lineage Key],
@@ -0,0 +1,173 @@
-- ******************************************************** --
-- Interleaved Execution
-- See https://aka.ms/IQP for more background
-- Demo scripts: https://aka.ms/IQPDemos
-- This demo is on SQL Server 2017 and Azure SQL DB
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
/*
Create MSTVF
*/
USE [WideWorldImportersDW];
GO
CREATE FUNCTION [Fact].[WhatIfOutlierEventQuantity](@event VARCHAR(15), @beginOrderDateKey DATE, @endOrderDateKey DATE)
RETURNS @OutlierEventQuantity TABLE (
[Order Key] [bigint],
[City Key] [int] NOT NULL,
[Customer Key] [int] NOT NULL,
[Stock Item Key] [int] NOT NULL,
[Order Date Key] [date] NOT NULL,
[Picked Date Key] [date] NULL,
[Salesperson Key] [int] NOT NULL,
[Picker Key] [int] NULL,
[OutlierEventQuantity] [int] NOT NULL)
AS
BEGIN
-- Valid @event values
-- 'Mild Recession'
-- 'Hurricane - South Atlantic'
-- 'Hurricane - East South Central'
-- 'Hurricane - West South Central'
IF @event = 'Mild Recession'
INSERT @OutlierEventQuantity
SELECT [o].[Order Key], [o].[City Key], [o].[Customer Key],
[o].[Stock Item Key], [o].[Order Date Key], [o].[Picked Date Key],
[o].[Salesperson Key], [o].[Picker Key],
CASE
WHEN [o].[Quantity] > 2 THEN [o].[Quantity] * .5
ELSE [o].[Quantity]
END
FROM [Fact].[Order] AS [o]
INNER JOIN [Dimension].[City] AS [c]
ON [c].[City Key] = [o].[City Key]
IF @event = 'Hurricane - South Atlantic'
INSERT @OutlierEventQuantity
SELECT [o].[Order Key], [o].[City Key], [o].[Customer Key],
[o].[Stock Item Key], [o].[Order Date Key], [o].[Picked Date Key],
[o].[Salesperson Key], [o].[Picker Key],
CASE
WHEN [o].[Quantity] > 10 THEN [o].[Quantity] * .5
ELSE [o].[Quantity]
END
FROM [Fact].[Order] AS [o]
INNER JOIN [Dimension].[City] AS [c]
ON [c].[City Key] = [o].[City Key]
WHERE [c].[State Province] IN
('Florida', 'Georgia', 'Maryland', 'North Carolina',
'South Carolina', 'Virginia', 'West Virginia',
'Delaware')
AND [o].[Order Date Key] BETWEEN @beginOrderDateKey AND @endOrderDateKey
IF @event = 'Hurricane - East South Central'
INSERT @OutlierEventQuantity
SELECT [o].[Order Key], [o].[City Key], [o].[Customer Key],
[o].[Stock Item Key], [o].[Order Date Key], [o].[Picked Date Key],
[o].[Salesperson Key], [o].[Picker Key],
CASE
WHEN [o].[Quantity] > 50 THEN [o].[Quantity] * .5
ELSE [o].[Quantity]
END
FROM [Fact].[Order] AS [o]
INNER JOIN [Dimension].[City] AS [c]
ON [c].[City Key] = [o].[City Key]
INNER JOIN [Dimension].[Stock Item] AS [si]
ON [si].[Stock Item Key] = [o].[Stock Item Key]
WHERE [c].[State Province] IN
('Alabama', 'Kentucky', 'Mississippi', 'Tennessee')
AND [si].[Buying Package] = 'Carton'
AND [o].[Order Date Key] BETWEEN @beginOrderDateKey AND @endOrderDateKey
IF @event = 'Hurricane - West South Central'
INSERT @OutlierEventQuantity
SELECT [o].[Order Key], [o].[City Key], [o].[Customer Key],
[o].[Stock Item Key], [o].[Order Date Key], [o].[Picked Date Key],
[o].[Salesperson Key], [o].[Picker Key],
CASE
WHEN [cu].[Customer] = 'Unknown' THEN 0
WHEN [cu].[Customer] <> 'Unknown' AND
[o].[Quantity] > 10 THEN [o].[Quantity] * .5
ELSE [o].[Quantity]
END
FROM [Fact].[Order] AS [o]
INNER JOIN [Dimension].[City] AS [c]
ON [c].[City Key] = [o].[City Key]
INNER JOIN [Dimension].[Customer] AS [cu]
ON [cu].[Customer Key] = [o].[Customer Key]
WHERE [c].[State Province] IN
('Arkansas', 'Louisiana', 'Oklahoma', 'Texas')
AND [o].[Order Date Key] BETWEEN @beginOrderDateKey AND @endOrderDateKey
RETURN
END
GO
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 130;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
SELECT [fo].[Order Key], [fo].[Description], [fo].[Package],
[fo].[Quantity], [foo].[OutlierEventQuantity]
FROM [Fact].[Order] AS [fo]
INNER JOIN [Fact].[WhatIfOutlierEventQuantity]('Mild Recession',
'1-01-2013',
'10-15-2014') AS [foo] ON [fo].[Order Key] = [foo].[Order Key]
AND [fo].[City Key] = [foo].[City Key]
AND [fo].[Customer Key] = [foo].[Customer Key]
AND [fo].[Stock Item Key] = [foo].[Stock Item Key]
AND [fo].[Order Date Key] = [foo].[Order Date Key]
AND [fo].[Picked Date Key] = [foo].[Picked Date Key]
AND [fo].[Salesperson Key] = [foo].[Salesperson Key]
AND [fo].[Picker Key] = [foo].[Picker Key]
INNER JOIN [Dimension].[Stock Item] AS [si]
ON [fo].[Stock Item Key] = [si].[Stock Item Key]
WHERE [si].[Lead Time Days] > 0
AND [fo].[Quantity] > 50;
GO
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 140;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
SELECT [fo].[Order Key], [fo].[Description], [fo].[Package],
[fo].[Quantity], [foo].[OutlierEventQuantity]
FROM [Fact].[Order] AS [fo]
INNER JOIN [Fact].[WhatIfOutlierEventQuantity]('Mild Recession',
'1-01-2013',
'10-15-2014') AS [foo] ON [fo].[Order Key] = [foo].[Order Key]
AND [fo].[City Key] = [foo].[City Key]
AND [fo].[Customer Key] = [foo].[Customer Key]
AND [fo].[Stock Item Key] = [foo].[Stock Item Key]
AND [fo].[Order Date Key] = [foo].[Order Date Key]
AND [fo].[Picked Date Key] = [foo].[Picked Date Key]
AND [fo].[Salesperson Key] = [foo].[Salesperson Key]
AND [fo].[Picker Key] = [foo].[Picker Key]
INNER JOIN [Dimension].[Stock Item] AS [si]
ON [fo].[Stock Item Key] = [si].[Stock Item Key]
WHERE [si].[Lead Time Days] > 0
AND [fo].[Quantity] > 50;
GO
@@ -10,13 +10,16 @@
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
ALTER DATABASE WideWorldImportersDW SET COMPATIBILITY_LEVEL = 150;
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 150;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE WideWorldImportersDW;
USE [WideWorldImportersDW];
GO
-- Simulate out-of-date stats
@@ -30,10 +33,10 @@ GO
SELECT
fo.[Order Key], fo.Description,
si.[Lead Time Days]
FROM Fact.OrderHistory AS fo
FROM Fact.OrderHistory AS fo
INNER HASH JOIN Dimension.[Stock Item] AS si
ON fo.[Stock Item Key] = si.[Stock Item Key]
WHERE fo.[Lineage Key] = 9
WHERE fo.[Lineage Key] = 9
AND si.[Lead Time Days] > 19;
-- Cleanup
@@ -9,19 +9,21 @@
-- Email IntelligentQP@microsoft.com for questions\feedback
-- ******************************************************** --
USE WideWorldImportersDW;
USE [master];
GO
ALTER DATABASE WideWorldImportersDW
SET COMPATIBILITY_LEVEL = 150;
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 150;
GO
ALTER DATABASE SCOPED CONFIGURATION
CLEAR PROCEDURE_CACHE;
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
GO
/*
Adapted from SQL Server Books Online
https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=sqlallproducts-allversions
https://docs.microsoft.com/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=sqlallproducts-allversions
*/
CREATE OR ALTER FUNCTION
dbo.customer_category(@CustomerKey INT)
@@ -13,7 +13,10 @@
USE [master];
GO
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 140;
ALTER DATABASE [WideWorldImportersDW] SET COMPATIBILITY_LEVEL = 150;
GO
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;
GO
USE [WideWorldImportersDW];
@@ -8,6 +8,9 @@ Here are the instructions to prepare for demonstrating Intelligent QP's latest r
Demos (with more on the way!):
- [Batch Mode Adaptive Join](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20Batch%20Mode%20Adaptive%20Join.sql)
- [Interleaved Execution](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20Interleaved%20Execution.sql)
- [Batch mode memory grant feedback](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20Batch%20Mode%20MGF.sql)
- [Row mode memory grant feedback](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20Row%20Mode%20MGF.sql)
- [Batch mode on rowstore](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20Batch%20Mode%20on%20Rowstore.sql)
- [APPROX_COUNT_DISTINCT](Intelligent%20QP%20Demos%20WideWorldImportersDW%20Public%20Preview%20-%20APPROX_COUNT_DISTINCT.sql)
+8 -9
View File
@@ -1,4 +1,4 @@
**Query Store demo**
## Query Store demo
This demo shows capabilities of Query Store. Usually we demo 3-4 scenarios:
1. How to turn on and initially configure Query Store
@@ -6,19 +6,17 @@ This demo shows capabilities of Query Store. Usually we demo 3-4 scenarios:
3. Detecting and fixing query with plan choice regression
4. Detecting and fixing workload that is candidate for auto-parametrization
**Prerequisites**
## Prerequisites
Restore AdventureWorks2016_EXT database from the provided BAK at https://github.com/Microsoft/sql-server-samples/releases/tag/adventureworks.
Turn ON and Configure Query Store
After restoring the database AdventureWorks2016_EXT, go to Properties / Query Store tab, turn ON Query Store, and configure it according to best practices in https://docs.microsoft.com/sql/relational-databases/performance/best-practice-with-the-query-store.
After restoring the database, go to Properties / Query Store tab.
![Query Store in SSMS](../QS_SSMS.png)
![Query Store in SSMS](./QS_SSMS.png)
Use docs content to walk through main config settings: https://docs.microsoft.com//sql/relational-databases/performance/best-practice-with-the-query-store#Configure
**How Query Store Works**
### How Query Store Works
Open ShowBasics.sql script and execute queries individually:
- Run simple `SELECT * FROM` Part
- Show where query ends in sys.query_store_query_text, sys.query_store_query, sys.query_store_plan, sys.query_store_runtime_stats
@@ -27,12 +25,13 @@ Open ShowBasics.sql script and execute queries individually:
- Show what happens with query that gets auto-parametrized. It cannot be searched using the original query text because QDS stores query as parametrized. Hopefully, sys.fn_stmt_sql_handle_from_sql_stmt can be used to track down query using original query text
- Run `vw_QueryStoreRuntimeInfo` (again custom view) to show main runtime stats combined with query/plan info
**Query with plan regression**
### Query with plan regression
1. Run QueryStoreSimpleDemo.exe with option R or option S
2. Open SSMS, analyze and explain - two execution plans that SQL Server use alternately (switches between 2 plan almost randomly). This is known as Parameter Sniffing problem - plan gets generated based on parameter available at the compilation time. When compilation happens frequently and randomly and data is skewed (not all parameter values are uniformly distributed PSP is likely to occur and degradations are common)
3. Force better plan, explain what happens (SSMS)
4. Summarize benefits for DBA fixing performance quickly without knowing details about the query. Fully transparent to running apps
Detect and fix ad hoc workload that is candidate for parametrization
### Detect and fix ad hoc workload that is candidate for parametrization
1. Run QueryStoreSimpleDemo.exe with option P and let it work for some time (15-20 sec)
2. Open “Auto-Param Analysis.sql” and run queries from groups (1) and (2). What we see is:
a. Large number of queries / plan entries, small number of different query/plan hashes indicates queries that are not parametrized although they are good candidates