Presentation is loading. Please wait.

Presentation is loading. Please wait.

T-SQL Performance Tuning

Similar presentations


Presentation on theme: "T-SQL Performance Tuning"— Presentation transcript:

1 T-SQL Performance Tuning
Jes Borland Premier Field Engineer, Data & AI

2 Goals Learn how SQL Server interprets queries
Learn strategies for making queries faster and less resource-intensive using T-SQL Learn about aggregations, window functions, subqueries, views, and functions to go beyond basic T-SQL

3 What is T-SQL? Transact SQL – Microsoft’s implementation of the ANSI standard Declarative language – you only tell SQL Server what you want, not how to do it

4 SELECT CustomerID, COUNT(SalesOrderID) AS CountOrders, SUM(TotalDue) AS TotalSales, AVG(TotalDue) AS AvgSales, MIN(TotalDue) AS MinOrder, MAX(TotalDue) AS MaxOrder FROM Sales.SalesOrderHeader SOH WHERE OrderDate >= '2014/01/01' AND OrderDate <= '2014/12/31' GROUP BY CustomerID ORDER BY COUNT(SalesOrderID) DESC;

5 Order of operations

6 Order of operations FROM WHERE GROUP BY HAVING SELECT ORDER BY

7 FROM FROM determines which tables or view the data is being retrieved from Only include tables or views you need data from Use aliases for easier recognition FROM dbo.Orders AS Ord Use primary key and foreign key relationships when creating your tables Indexes on FKs can reduce reads through join elimination

8 Demo - FROM Done

9 WHERE WHERE determines your predicates – what is the statement evaluated on? Equality and inequality options = <> > >= < <= BETWEEN IN The order of the fields in the WHERE clause compared to the order of the key columns in indexes matters! SARGability is an important consideration!

10 Index key columns and WHERE clause order
If the order of the predicates in the WHERE clause doesn’t match the order of the key columns in the index, SQL Server may still be able to use the index – but it may be a less-efficient scan, instead of a seek CREATE NONCLUSTERED INDEX IX_WhereClause ON dbo.WhereClauseDemo (OrderDate, DueDate, ShipDate); SELECT OrderDate FROM WhereClauseDemo WHERE ShipDate = ' '; Good place to mention the new showplan option “Estimated number of rows read”!

11 SARGability Searching a field that contains a value is a lot of work and can’t take advantage of indexes SELECT FirstName FROM Person WHERE FirstName LIKE '%Jen%’ This is a non-SARGable query A SARGable query can use indexes and is more efficient WHERE FirstName LIKE 'Jen%'

12 SARGability If you have a wildcard contains search, SQL Server will not use your index the way you intended it to Indexes on character fields (in particular) can hurt you if they are not being used Functions in the WHERE clause can cause issues too Options Computed column Full text search Range search

13 Demos – WHERE, WHERE – Key column order, SARGability
WHERE – Done WHERE Key column order – done SARGability – done

14 GROUP BY If it's in SELECT, and not aggregated, it's here

15 HAVING A predicate for the aggregations
Specifies a search condition based on a previously calculated aggregation

16 Demo – GROUP BY and HAVING
Done

17 SELECT Only include columns necessary for the operation you are performing SELECT *, while a shortcut, returns unnecessary data Using this in views or application code can introduce unwanted effects When selecting from multiple tables, reference the table’s alias you created in the FROM clause for easier recognition SELECT Ord.OrderID, Ord.OrderDate, OrdLin.ItemID, OrdLin.Quantity FROM dbo.Orders AS Ord JOIN dbo.OrderLines AS OrdLin ON OrdLin.OrderID = Ord.OrderID

18 Demo – SELECT Done

19 DISTINCT Specifies that only unique rows can appear in the result set
Removes duplicates based on column list results, not source table Provides uniqueness across set of selected columns Removes rows already operated on by WHERE, HAVING, and GROUP BY clauses Will likely inject a SORT operator into the query – which can add overhead to the query

20 TOP Lets you limit the number or percentage of rows returned by a query Works with ORDER BY clause to limit rows by sort order If ORDER BY list is not unique, results are not deterministic Modify ORDER BY list to ensure uniqueness, or use TOP WITH TIES Added to SELECT clause: SELECT TOP (N) | TOP (N) Percent With percent, number of rows rounded up SELECT TOP (N) WITH TIES Retrieve duplicates where applicable (nondeterministic)

21 Demo – DISTINCT and TOP Done

22 When is ORDER BY OK? Order isn't guaranteed unless this is used
Can declare ASC or DESC It requires a sort so be careful Use an indexed column

23 Joins

24 The Logical Join INNER JOIN OUTER JOIN Cross Join Self Join
CROSS APPLY OUTER APPLY

25 Understanding Inner Joins
Module 5: Querying Multiple Tables Course 10774A Understanding Inner Joins Returns rows matched between two input sources The comparison operator is typically equality (=) equi-join Matches rows based on attributes supplied in predicate ON clause in SQL-92 syntax Why filter in ON clause? Logical separation between filtering for purposes of join and filtering results in WHERE Typically no difference to query optimizer

26 Understanding Outer Joins
Module 5: Querying Multiple Tables Course 10774A Understanding Outer Joins Returns all rows from one table and any matching rows from second table Table ordering DOES matter here when written One table’s rows are “preserved” LEFT vs RIGHT refers to which table’s output will be reserved Additional rows added to results for non-matched rows NULLs added in place where attributes do not match Example: Return all customers and for those who have placed orders, return order information. Customers without matching orders will display NULL for order details. Consider explaining this as answering the "whether or not" question – all customers and their orders whether or not they have an order.

27 Understanding Cross Joins
Module 5: Querying Multiple Tables Course 10774A Understanding Cross Joins Combine each row from first table with each row from second table All possible combinations output Logical foundation for inner and outer joins Inner join starts with Cartesian product, adds filter Outer join takes Cartesian output, filtered, adds back non-matching rows (with NULL placeholders) Due to Cartesian product output, not typically a desired form of join Some useful exceptions: Table of numbers, generating data for testing

28 Understanding Self-Joins
Module 5: Querying Multiple Tables Course 10774A Understanding Self-Joins Why use self-joins? Compare rows in same table to each other Hierarchies and Organization charts are great examples Create two instances of same table in FROM clause At least one alias required Example: Return all employees and the name of the employee’s manager While only one alias is required, it is useful when demonstrating to alias both tables in the join.

29 Using the CROSS APPLY Operator
Module 12: Using Set Operators Course 10774A Using the CROSS APPLY Operator APPLY is a table operator used in the FROM clause Includes CROSS APPLY and OUTER APPLY Operates on two input tables, left and right Right table is often a derived table or a table-valued function Can be used with a table-valued function or a correlated subquery See APPLY in the REMARKS section of "FROM (Transact-SQL)" the Books Online: See also Remind students that use of "left" and "right" refers to the order of the tables as listed in the FROM clause, much like in a JOIN.

30 The Physical Join Nested loops Merge Hash

31 This is the execution plan of the INNER JOIN query

32 Nested Loops Best for small data sets
Outer (top) and inner (bottom) inputs Compare every row in inner loop to outer loop

33 Merge Both inputs must be sorted in the same order
Each row is compared

34 Hash Best for large data sets
Hash tables are built in memory – build and probe Values from probe compared to build

35 Demo – Joins Done

36 Views Named query stored in the database Great for security
Give a group or user access to a view, not the underlying table Can index for greater performance – “indexed view” or “materialized view”

37 Demo – Views Done

38 Writes INSERT – UPDATE – DELETE

39 INSERT INSERT INSERT INTO [...] SELECT [...] FROM [...]
Into one table at a time INSERT INTO [...] SELECT [...] FROM [...] Insert into an existing table from another table, temp table, or table variable SELECT [...] INTO [...] FROM [...] Creates new table from another table, temp table, or table variable

40 UPDATE Modify only existing data
Data can be filtered using a WHERE or JOIN clause

41 DELETE Delete specific rows from a given table
Data can be filtered using a WHERE or JOIN clause Use this method when you only want to remove certain rows – not everything in the table TRUNCATE is for emptying an entire table Deletion of each row is logged in database's transaction log

42 Writing good INSERT/UPDATE/DELETE statements
What slows them down? Too many rows at a time Too many nonclustered indexes on a table

43 Demo - INSERT - UPDATE - DELETE
Mostly done

44 Aggregations Performing calculations on the data What is the "cost"?
NULL values ignored (except COUNT) What is the "cost"? Aggregations require the server to do work. This can mean increased CPU usage, increased memory usage, and tempdb usage. AVG GROUPING_ID STDEVP CHECKSUM_AGG MAX STRING_AGG COUNT MIN VAR COUNT_BIG SUM VARP GROUPING STDEV AVG - Returns the average of the values in a group. Null values are ignored. CHECKSUM_AGG - Returns the checksum of the values in a group. Null values are ignored. CHECKSUM_AGG can be used to detect changes in a table. COUNT - Returns the number of items in a group. Always returns an int data type value. COUNT_BIG - Returns the number of items in a group. Always returns a bigint data type value. GROUPING - Indicates whether a specified column expression in a GROUP BY list is aggregated or not. Used to distinguish the null values that are returned by ROLLUP, CUBE or GROUPING SETS from standard null values. GROUPING_ID - Is a function that computes the level of grouping. MAX - Returns the maximum value in the expression. MIN - Returns the minimum value in the expression. STDEV - Returns the statistical standard deviation of all values in the specified expression. STDEVP - Returns the statistical standard deviation for the population for all values in the specified expression. SUM - Returns the sum of all the values, or only the DISTINCT values, in the expression. SUM can be used with numeric columns only. Null values are ignored. STRING_AGG - Concatenates the values of string expressions and places separator values between them. VAR - Returns the statistical variance of all values in the specified expression. VARP - Returns the statistical variance for the population for all values in the specified expression.

45 Demo - Aggregations Done

46 Window functions Aggregations over a partition (a window) of the result set Window functions can simplify queries that need to find running totals, moving averages, or gaps in data Ranking RANK, DENSE_RANK, NTILE, ROW_NUMBER Aggregate AVG, COUNT, MAX, MIN, SUM, STDEV, more Analytic FIRST_VALUE, LAST_VALUE, LEAD, LAG, more Ranking RANK, DENSE_RANK, NTILE, ROW_NUMBER Aggregate AVG, COUNT, MAX, MIN, SUM, STDEV, more Analytic FIRST_VALUE, LAST_VALUE, LEAD, LAG, more

47 Syntax SELECT Column1, Column2, RANK() OVER (PARTITION BY Column1 ORDER BY Column2 ASC) FROM Table1 WHERE Column1 IS NOT NULL;

48 Module 13: Using Window Ranking, Offset and Aggregate Functions
Course 10774A The OVER Clause OVER defines a window, or set of rows to be used by a window function, including any ordering The OVER clause restricts the set of rows to those with the same values in the partitioning elements By itself, OVER() is unrestricted and includes all rows Multiple OVER clauses can be used in a single query, each with its own partitioning and ordering, if needed For example, SUM(<col>) OVER () means to calculate the aggregate (SUM) using the underlying query's result set (all rows). SUM(<col>) OVER (PARTITION BY <col>) means to calculate the aggregate once for each window of rows restricted to only those rows that have the same value in <col> as in the current row.

49 Module 13: Using Window Ranking, Offset and Aggregate Functions
Course 10774A Partition By Partitioning applies a windowing function to a set to rows in a result set that share the same columns in the PARTITION BY clause Without a PARTITION BY clause defined, OVER() creates a single partition of all rows Don't take the comparison too far, but PARTITION is conceptually similar to a GROUP BY, even if the mechanisms are very different.

50 Demo – Window Functions
Done

51 Subqueries Nested queries – in SELECT, FROM, or WHERE
Results of inner passed to outer Dependent? Self-contained - not dependent on outer query Correlated - dependent on outer query Return values Scalar - returns single value to outer query Multi-valued - returns multiple values - use with IN Table-valued

52 Self-contained subquery
Write a query that can be in the SELECT, FROM, or WHERE clause Can reference one of the tables or views in the outer query, or different tables or views May return scalar value or multiple values

53 Correlated Subqueries
Module 10: Using Subqueries Course 10774A Correlated Subqueries Correlated subqueries refer to elements of tables used in outer query Dependent on outer query, cannot be executed separately Harder to test than self-contained subqueries Behaves as if inner query is executed once per outer row May return scalar value or multiple values Question: Why can't a correlated subquery be executed separately from the outer query? The subquery depends on input from the outer query for its values.

54 Writing Scalar Subqueries
Module 10: Using Subqueries Course 10774A Writing Scalar Subqueries Scalar subquery returns single value to outer query Can be used anywhere single-valued expression can be used: SELECT, WHERE, etc. If inner query returns an empty set, result is converted to NULL The example returns details about the most recent order. This is the error returned if the inner query is not scalar and the outer is written to expect a single value: Msg 512, Level 16, State 1, Line 1 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

55 Writing Multi-Valued Subqueries
Module 10: Using Subqueries Course 10774A Writing Multi-Valued Subqueries Multi-valued subquery returns multiple values as a single column set to the outer query Used with IN predicate If any value in the subquery result matches IN predicate expression, the predicate returns TRUE May also be expressed as a JOIN (test both for performance) The example returns information about orders placed by customers in Mexico. This may be rewritten as a JOIN: SELECT c.custid, o.orderid FROM Sales.Customers AS c JOIN Sales.Orders AS o ON c.custid = o.custid WHERE c.country = 'Mexico‘ Point out to the students that sometimes it’s easier to write and test a query one piece at a time, in which case a subquery may be more accessible.

56 Demo – Subqueries Done

57 Derived table May be used in place of a temp tables, if you don’t need to reference it more than once A SELECT statement, referenced in the FROM clause Query-scoped Can get ugly if nested

58 Demo - Derived table Done

59 CTEs A temporary result set
Can define multiple CTEs and reference in one final SELECT Great for recursion ;WITH CTEName (Optional Defined Fields) AS ( SELECT statement ) SELECT * FROM CTEName

60 CTE versus Temporary Tables
Temporary tables inherit no indexes from base tables, causing table scans CTEs use the raw tables (reducing processing time) When using a temporary table, the table has no index on it, and therefore SSE will complete a table scan operation on it when executing the second part. In contrast, CTEs use the raw tables. There is no creation of a temporary table, which uses up processing time, and also existing indexes could be used in building up the query as well rather than a table scan. The CTE is built up using the WITH keyword, which defines the name of the CTE you’ll be returning. The columns returned within the CTE will take the data types placed into it from the SELECT statement within the brackets. Of course, the number of columns within the CTE has to be the same as the table defined within the brackets. This table is built up, returned, and passed immediately into the following SELECT statement outside the WITH block where the rows of data can then be processed as required. Therefore, the rows returned between the brackets could be seen as a temporary table that is used by the statement outside the brackets. Explicitly materializing a CTE (or view or sub-select) result does not always yield better performance.  First, we must consider the cost of creating and writing the temp table.  If the cost of computing the CTE is not too great, it may be cheaper simply to compute the CTE result multiple times.  Second, in some cases, the query optimizer may be able to choose a better plan and avoid computing the entire CTE result.  For example, suppose that we only want to compute the number of orders for a single employee: INT = 268; WITH Sales_CTE (SalesPersonID, NumberOfOrders, MaxDate) AS (     SELECT SalesPersonID, COUNT(*), MAX(OrderDate)     FROM Sales.SalesOrderHeader     GROUP BY SalesPersonID ) SELECT E.EmployeeID, OS.NumberOfOrders, OS.MaxDate,     E.ManagerID, OM.NumberOfOrders, OM.MaxDate FROM HumanResources.Employee AS E     JOIN Sales_CTE AS OS     ON E.EmployeeID = OS.SalesPersonID     LEFT OUTER JOIN Sales_CTE AS OM     ON E.ManagerID = OM.SalesPersonID WHERE E.EmployeeID This query yields a different plan from the original query:   |--Nested Loops(Left Outer Join, OUTER REFERENCES:([E].[ManagerID]))        |--Nested Loops(Inner Join)        |    |--Clustered Index Seek(OBJECT:([HumanResources].[Employee].[PK_Employee_EmployeeID] AS [E]), ORDERED FORWARD)        |    |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1021],0)))        |         |--Stream Aggregate(DEFINE:([Expr1021]=Count(*), [Expr1006]=MAX([Sales].[SalesOrderHeader].[OrderDate])))        |              |--Clustered Index Scan(OBJECT:([Sales].[SalesOrderHeader].[PK_SalesOrderHeader_SalesOrderID]),        |--Compute Scalar(DEFINE:([Expr1010]=[Expr1010], [Expr1011]=[Expr1011]))             |--Compute Scalar(DEFINE:([Expr1010]=CONVERT_IMPLICIT(int,[Expr1022],0)))                  |--Stream Aggregate(DEFINE:([Expr1022]=Count(*), [Expr1011]=MAX([Sales].[SalesOrderHeader].[OrderDate])))                       |--Clustered Index Scan(OBJECT:([Sales].[SalesOrderHeader].[PK_SalesOrderHeader_SalesOrderID]), WHERE:([E].[ManagerID]=[Sales].[SalesOrderHeader].[SalesPersonID])) While the original plan computed the number of orders and the most recent order date for all employees, this plan only computes this information for a single employee and for that employee's manager.  Observe the WHERE predicates on the clustered index scans of the SalesOrderHeader table.  Moreover, notice that this plan uses scalar stream aggregates instead of the hash aggregates in the original plan.  Finally, in this example, the optimizer chose scans, but if the tables involved were larger and the predicates were more selective, it would have chosen index seeks to avoid scanning the entire table.

61 CTE Guidelines A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE statement Multiple CTE query definitions can be defined in a nonrecursive CTE A CTE can reference itself and previously defined CTEs in the same WITH clause More than one WITH clause is not allowed

62 Recursive CTE Guidelines
Must contain at least one anchor member and one recursive member Anchor members must be combined by one of these set operators: UNION ALL, UNION, INTERSECT, or EXCEPT The number of columns in the anchor and recursive members must be the same. The data type of a column in the recursive member must be the same as the data type of the corresponding column in the anchor member The FROM clause of a recursive member must refer only one time to the CTE expression_name Certain items are not allowed in the CTE_query_definition of a recursive member All columns returned by the recursive CTE are nullable regardless of the nullability of the columns returned by the participating SELECT statements. An incorrectly composed recursive CTE may cause an infinite loop. Use MAXRECURSION to limit the number of recursion levels allowed. A view that contains a recursive common table expression cannot be used to update data Cursors may be defined on queries using CTEs. Tables on remote servers may be referenced in the CTE. The following guidelines apply to defining a recursive common table expression: The recursive CTE definition must contain at least two CTE query definitions, an anchor member and a recursive member. Multiple anchor members and recursive members can be defined; however, all anchor member query definitions must be put before the first recursive member definition. All CTE query definitions are anchor members unless they reference the CTE itself. Anchor members must be combined by one of these set operators: UNION ALL, UNION, INTERSECT, or EXCEPT. UNION ALL is the only set operator allowed between the last anchor member and first recursive member, and when combining multiple recursive members. The number of columns in the anchor and recursive members must be the same. The data type of a column in the recursive member must be the same as the data type of the corresponding column in the anchor member. The FROM clause of a recursive member must refer only one time to the CTE expression_name. The following items are not allowed in the CTE_query_definition of a recursive member: SELECT DISTINCT GROUP BY HAVING Scalar aggregation TOP LEFT, RIGHT, OUTER JOIN (INNER JOIN is allowed) Subqueries A hint applied to a recursive reference to a CTE inside a CTE_query_definition.

63 Demo – CTEs Done

64 Temp tables A temporary table construct created in the tempdb database
Local – prefix with # - session-scoped A local temporary table created in a stored procedure is dropped automatically when the stored procedure is finished All other local temporary tables are dropped automatically at the end of the current session Global – prefix with ## - instance-scoped Global temporary tables are automatically dropped when the session that created the table ends and all other tasks have stopped referencing them Issue SELECT, INSERT, UPDATE, DELETE against them Create indexes against them

65 Table variables Primarily used for temporary storage of a set of rows returned as the result set of a table-valued function A table variable behaves like a local variable. It has a well-defined scope. Automatically cleaned up at the end of the function, stored procedure, or batch in which they are defined.

66 Table variable limitations
No statistics, will not trigger recompiles If more than 100 rows, may want to use a temp table If joining to other tables, use RECOMPILE hint to get correct cardinality No cost-based optimization Temp tables preferred for queries with joins, parallelism decisions, and index selection choices Queries that modify table variables do not generate parallel query execution plans Indexes can’t be created explicitly on table variables, and no statistics are kept on table variables

67 Demo – Temp objects

68 What are functions? Encapsulated T-SQL Great for code re-use
Can have a huge performance impact when they're called from a SELECT or WHERE clause

69 Types of User Defined Functions
Returns a single value of a single data type Scalar Returns a resultset from a single SELECT statement Inline Table Valued Returns a resultset using a defined table variable, allowing more complex T-SQL Multi-statement Table Valued

70 Scalar Functions Great for code encapsulation
9: Designing and Implementing User-Defined Functions Scalar Functions Great for code encapsulation Return a single data value of the data type defined in the function Can return any data type except text, ntext, image, timestamp, rowversion, cursor, or table Can be called in a SELECT statement or from an EXECUTE command You can pass column values into the function in the SELECT statement Mention that user-defined scalar functions return a single data value of the type defined in the RETURNS clause. Finally mention that the return type can be any data type except rowversion, cursor and table. Mention that scalar functions that are created in managed code have slightly different limitations on returned data types. Do not, however, dwell on managed code at this point as it is covered in module 12.

71 Calling the function Query is executed
This slide is to show how the function is called from a SELECT statement, and show the results of the function in the column

72 What is the performance impact?
Where is the function? This slide shows the execution plan, which makes no reference to the function, and the executions of the function as observed by capturing the sp_statement_completed event in an Extended Events session. XE shows us the executions

73 Inline Table-Valued Functions
Module 11: Using Table Expressions Course 10774A Inline Table-Valued Functions Can be thought of as a parameterized view Returns a result set Declare return type as TABLE Define inline SELECT statement following RETURN A single SELECT statement is allowed in the UDF body Often the best option for defining UDFs

74 Writing Queries That Use Inline Table-Valued Functions
Module 11: Using Table Expressions Course 10774A Writing Queries That Use Inline Table-Valued Functions Table-valued functions (TVFs) are named table expressions with definitions stored in a database TVFs return a virtual table to the calling query Unlike views, TVFs support input parameters

75 Retrieving from Inline Table-Valued Functions
Module 11: Using Table Expressions Course 10774A Retrieving from Inline Table-Valued Functions SELECT from function Use two-part name Pass in parameters USE CROSS/OUTER APPLY to pass in values from columns in a table

76 Calling the function Query is executed

77 What is the performance impact?
Where is the function? XE shows us the executions

78 Multistatement Table-Valued Functions
9: Designing and Implementing User-Defined Functions Multistatement Table-Valued Functions Definition of returned table must be supplied Function body is enclosed by BEGIN and END Allows for more complex T-SQL logic Table variable is populated within function body and then returned This DOES create an object in tempdb for each call to the function!!

79 Calling the function Query is executed

80 What is the performance impact?
XE shows us the executions

81 MSTVFs and row estimates
MSTVFs have a fixed cardinality guess of “100” in SQL Server 2014 and 2016, and “1” for earlier versions We have a MSTVF Table Scan that has a fixed estimate of 100 rows. But for this example, there are 527,592 flowing through this MSTVF Table Scan as seen in Live Query Statistics via the “ of 100” actual of estimated – so our fixed estimate is significantly skewed. For the Nested Loops operation, we’re still assuming only 100 rows are flowing through the outer reference. Given the high number of rows actually being returned by the MSTVF, we’re likely better off with a different join algorithm altogether. For the Hash Match operation, notice the small warning symbol, which in this case is indicating a spill to disk.

82 SQL Server 2017 introduces interleaved execution
Notice that the MSTVF table scan now reflects an accurate cardinality estimate. Also notice the re-ordering of this table scan and the other operations. And regarding join algorithms, we have switched from a Nested Loop operation to a Hash Match operation instead, which is more optimal given the large number of rows involved. Also notice that we no longer have spill-warnings, as we’re granting more memory based on the true row count flowing from the MSTVF table scan.

83 Types of User Defined Functions
Returns a single value of a single data type Scalar Returns a resultset from a single SELECT statement Inline Table Valued Returns a resultset using a defined table variable, allowing more complex T-SQL Multi-statement Table Valued

84 When to use each function type
When you need the same logic applied to every row in a result set Scalar Use one SELECT statement to return a table result set Inline Table Valued Use more complex logic to return a table result set Multi-statement Table Valued

85 Performance Impact of User Defined Functions
9: Designing and Implementing User-Defined Functions Performance Impact of User Defined Functions Inline Table Valued Functions Code is often rewritten by the optimizer to be a JOIN Often results in the best performance choice of all 3 types of UDFs Scalar and Multistatement TVF SQL Server does not re-write the query to be a JOIN like it does with an in-line TVF Very common cause of performance problems Multi-statement TVFs create a very heavy load on tempdb Each function call creates a table variable in tempdb With scalar user-defined functions, the code that defines the function is not incorporated directly into the surrounding query. Performance problems with these functions are well-known in the SQL Server community. Particular impacts are caused when the functions are executed for each row in a table. CROSS APPLY is used to call a table-valued function for each row in a table.

86 Demo - Functions Done

87 Module 16: Executing Stored Procedures
Course 10774A Dynamic SQL Dynamic SQL is T-SQL code assembled and executed at run time Provides flexibility for administrative and programming tasks Two methods for dynamically executing SQL statements: EXECUTE/EXEC command can accept a string as input in parentheses. No parameters may be passed in. System stored procedure sp_executesql (preferred) supports parameters. Breaks permission chaining Permissions on the base table are required Beware of risks from unvalidated inputs in dynamic SQL! Otherwise SQL injection attacks may occur See the section "Using EXECUTE with a Character String" in Books Online: See "SQL Injection" in Books Online:

88 Dynamic SQL using EXECUTE
Accepts string to be executed Does not allow for parameterization This can open more opportunities for SQL Injection attacks Generally a less ideal option than using sp_executesql

89 Dynamic SQL using sp_executesql
Module 16: Executing Stored Procedures Course 10774A Dynamic SQL using sp_executesql Accepts string as code to be run Supports input, output parameters for query Allows parameterized code while minimizing risk of SQL injection Can perform better than EXECUTE due to query plan reuse See Books Online for discussions of query plan reuse and more coverage of sp_executesql:

90 When to use dynamic SQL Handling multiple OR clauses in a WHERE statement Example: a stored procedure supporting a dynamic search screen in an application Dealing with parameter sniffing Could lead to plan cache bloat Which can be mitigated with the Optimize for ad hoc workloads server property

91 Simple --Simple query - no parameters SELECT ProductID, LocationID, Shelf, Bin, Quantity FROM Production.ProductInventory --Rewritten as dynamic SQL nvarchar(1000) = N'SELECT ProductID, LocationID, Shelf, Bin, Quantity FROM Production.ProductInventory' EXECUTE It’s OK to use EXECUTE () here – there are no parameters, so don’t worry about ad hoc optimization, or injection

92 With input parameters --Declare external variables nvarchar(max) --The variable that will be the SQL statement nvarchar(1000) --Used to build string, not used in sp_executesql INT --The variable for the WHERE clause = 'ProductID, LocationID, Shelf, Bin, Quantity' --Set external variables = Assigning a value to that variable = N'SELECT + ' FROM Production.ProductInventory WHERE ProductID --Execute sp_execute SQL, passing in: --1. The variable name of the SQL statement --2. A string containing the name and data type of the variable for the WHERE clause --3. The values for the WHERE clause EXEC

93 With output parameters
nvarchar(max) --The variable that will be the SQL statement INT --The variable for the WHERE clause INT --The output variable --Set external variables = Assigning a value to that variable = = SUM(Quantity) FROM Production.ProductInventory WHERE ProductID GROUP BY ProductID' --Execute EXECUTE INT = OUTPUT;

94 Demo – Dynamic SQL Dynamic SQL.sql

95


Download ppt "T-SQL Performance Tuning"

Similar presentations


Ads by Google