Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Stored procedure tunning
1. Working
with
Stored Procedure
Free Powerpoint Templates
@Virendra Yaduvanshi 1
2. SELECT statements - Try to use only the required number of
columns in the SELECT clause instead of using *. Using *
returns all columns, which unnecessarily create a fat
recordset.
Don’t use the * when selecting data
SELECT * FROM dbo.MyTable
Explicitly name each column you want to be returned in your
SELECT statement
SELECT Name, Description, DateEntered FROM dbo.MyTable
This allows you to add new columns to your table without
breaking your code Minimizes network traffic by only returns
the columns you need.
Free Powerpoint Templates
@Virendra Yaduvanshi 2
3. SQL-92 - Always try to use ANSI 92 syntax. Till now the
old syntax is working the old syntax will be deprecated
in the next release of MS SQL server.
As an example, for joining, use
SELECT * FROM employee e1
INNER JOIN employee _dtl e2
ON e1.id = e2.id
Instead of
SELECT * FROM employee e1, employee_dtl e2
WHERE e1.id = e2.id
Free Powerpoint Templates
@Virendra Yaduvanshi 3
4. CREATE TABLE vs. SELECT INTO - Select * INTO works
fine for small tables, but when dealing with large record sets or
long-running queries, it creates locks on the system objects
within the tempdb database. As a result, other queries and
procedures that need to create objects within the tempdb
database will have to wait for the long-running query to
complete. This is because when an object is created, an
exclusive lock is taken against the
sysobjects, syscolumns, sysindexes tables.
Update: This problem has been greatly reduced from the MS
SQL 7.0.
Also, SELECT INTO not only copies data but also it copies
the table structure, hence it performs slower.
Free Powerpoint Templates
@Virendra Yaduvanshi 4
5. Try to use table variables instead of Temporary Tables -
Temp tables can cause stored procedures to recompile. (From
SQL 2005, using temporary table not always causing
recompilations. But adding rows to temporary tables may
cause recompilations). But table variables were designed
specifically to guard against stored procedure recompiles
during execution.
If the result set is not containing a huge number of records
then you should stick to table variable, otherwise temp table
has its advantages. There is a misconception that temp tables
always use the tembdb database but table variable do not.
Table variables also use tempdb after a certain size
Free Powerpoint Templates
@Virendra Yaduvanshi 5
6. Use proper indexes - You can use the help of the data
tuning advisor, but it does not gives the proper result all
the time. Index scans and index seeks are much faster
than table scans. So identify the table scans from the
execution plans. But when a table returns smaller
number rows, then it is better to use a table scan.
Free Powerpoint Templates
@Virendra Yaduvanshi 6
7. Subquery vs JOINs - This is a famous debate in many
online forums. In fact most sub queries can be expressed
as an equivalent form of JOIN. I have a good rule of
thumb: subquery is faster when we have to retrieve data
from large number of tables because it becomes tedious
to join more tables. JOIN is faster to retrieve data from
database when we have less number of tables. But try to
avoid correlated sub queries because it makes the query
much slower.
Free Powerpoint Templates
@Virendra Yaduvanshi 7
8. Avoid using cursors - Using cursors make the program
slower as it works against SET based SQL. Try to use
temporary table/table variables with identity column and
then iterate all the tables using WHILE loop and a looping
counter, which will map with the identity column.
Free Powerpoint Templates
@Virendra Yaduvanshi 8
9. Avoid DISTINCT and ORDER BY - If you don't need the
DISTINCT/ORDER BY clause, then try to avoid so.
Unnecessary DISTINCT or ORDER BY clauses cause extra
work for the database engine. Hence making performance
slower. (Sometimes ORDER BY helps to speed up the
operation).
Free Powerpoint Templates
@Virendra Yaduvanshi 9
10. CAST and CONVERT - Try to use CAST instead of
CONVERT. CAST is ANSI-92 standard but CONVERT works
in MS SQL server only. Also, some CONVERT styles may be
deprecated in future MS SQL releases. It is better to use
CONVERT only when you need to format the DATETIME
datatype with the style option. CAST cannot do this.
Free Powerpoint Templates
@Virendra Yaduvanshi 10
11. More WHERE clause hints - Avoid unnecessary
conditions in the WHERE Clause. Also try to avoid a
function in the WHERE clause as it presents SQL
engine to do index seek. Even it forces SQL full index
scans or even table scans.
Also, try to avoid IN. While checking the existence of
some values, then use EXISTS instead of IN. IN counts
the NULL values also, but EXISTS not. EXISTS returns
Boolean(Yes/No) but IN returns all values hence result
set for IN is heavier than EXISTS.
Here, teacher and student table has 1:M relationship
and I want to find the teachers who have students. Both
the queries have the same result but the second query
will run faster because of EXISTS operator.
SELECT name FROM teacher
WHERE teacher_id IN (SELECT teacher_id FROM student)SELECT name
FROM teacher WHERE EXISTS (SELECT 1 FROM student where
teacher.teacher_id = student.teacher_id)
Free Powerpoint Templates
@Virendra Yaduvanshi 11
12. Capturing Both @@ROWCOUNT and @@ERROR After
an UPDATE Statement
declare @rowcnt int,
@error int
UPDATE dbo.titles set price = price * 1.10
where type = 'fiction'
select @rowcnt = @@ROWCOUNT, @error = @@ERROR
if @rowcnt = 0
print 'no rows updated'
if @error <> 0
raiserror ('Update of titles failed', 16, 1)
return
Free Powerpoint Templates
@Virendra Yaduvanshi 12
13. Variables - Use as few as possible
variables. It frees spaces in cache.
Free Powerpoint Templates
@Virendra Yaduvanshi 13
14. Dynamic Queries - Try to minimize the usage of
dynamic queries. If you are using a dynamic query like:
SELECT * FROM mydb.dbo.emp where empid = @eid
then there is no problem. You can supply a value for
the @eid parameter and there is no recompilation of the
execution plan in the database cache. But if you are
using a SQL query like
SELECT * FROM emp where empid = " + @eid and
supply a parameter (say 100), then the cache will keep
the execution plan for the value of 100 only. If the id
changes (to say 101), it will recompile the statement.
Hence, this approach is slower than the previous one.
(You can get the exact value of the SQL statement from
Profiler)
Free Powerpoint Templates
@Virendra Yaduvanshi 14
15. Fully Qualified Names - Always use the fully qualified
name when calling stored procedures. This would be
the format database_name.schema_name.table_name.
For example, use EXEC master.dbo.Your_Proc_name
instead of EXEC Your_Proc_name This is a very
common mistake, which causes an extra trip to the
procedure cache to get the execution plan for
execution. Also try to use the schema name while
creating a procedure. Like: CREATE PROCEDURE
dbo.Your_Proc_name instead of CREATE PROCEDURE
Your_Proc_name
Free Powerpoint Templates
@Virendra Yaduvanshi 15
16. SET NOCOUNT ON - This suppresses the message that
shows number of rows affected by SQL statement.
Otherwise this can cause extra network traffic and can
have some serious impact on performance when the
procedure is called frequently.
Its recommend to use SET NOCOUNT ON for the shake
of performance unless there is a very good reason for
using it.
Free Powerpoint Templates
@Virendra Yaduvanshi 16
17. Naming Procs
Do NOT use sp_xxx as a naming convention.
Causes additional searches and added I/O.
SQL Server will scan the procedure cache for Master,
no matter what database the procedure was executed from
SQL Server will then acquire an exclusive COMPILE lock to
perform a second search in the local database
If a user stored procedure has same name as an sp_xxx stored
procedure in MASTER, then the user procedure will NEVER be used.
Free Powerpoint Templates
@Virendra Yaduvanshi 17
18. The sp_ prefix - Don't use the "sp_" prefix in a stored
procedure name as the "sp_" prefix is reserved for
system stored procedures. Any stored procedure that
has the "sp_" prefix will cause an extra lookup in the
MASTER database If a stored procedure uses same
name in both the user database and a system
database, the stored procedure in the user database will
execute but first it will find the procedure in resource
database and then the user database (for SQL server
2005/2008/2012) hence causing an extra burden to the
server.
Free Powerpoint Templates
@Virendra Yaduvanshi 18
19. sp_executeSQL and the KEEPFIXED PLAN options- Both sp_executesql and
the KEEPFIXED PLAN option avoid the recompilation of a stored procedure. If
you want to provide parameterized dynamic SQL, then go for sp_executesql
instead of EXEC(proc_name). Here the execution plan for the procedure is
stored with the variable name in cache memory. When the variable values
are supplied, then the values are simply mapped to the query, hence no
need for a recompilation.
Update: Keep in mind that recompilations are not always bad. Sometimes,
using an old and inefficient plan can make the procedure more slower.
Use the OPTION KEEPFIXED PLAN hint while selecting records from
temporary tables. If the query contains this hint, then its plan is not
recompiled
CREATE PROCEDURE my_proc
AS
CREATE TABLE #t (a int )
SELECT * FROM #t
INSERT #t SELECT * from retest
SELECT COUNT(*) FROM #t WHERE a = 37
OPTION (KEEPFIXED PLAN)
As an example of sp_executesql, we can write:
sp_executesql N'SELECT * FROM mydb.dbo.emp where empid = @eid',
N'@eid int', @eid=40
Free Powerpoint Templates
@Virendra Yaduvanshi 19
20. Calling Procs
Use stored procedure calls rather than embedded SQL
EXEC versus SP_EXECUTESQL
same behavior with regard to batches, the scope of names,
and database context
EXEC compiles entire SQL at one time
SP_EXECUTE compiles and executes as an execution plan
separate from the execution plan of the batch that called
sp_executesql itself.
SP_EXECUTESQL executes a Transact-SQL statement or
batch that can be reused many times, or that has been built
dynamically, using a single execution plan.
Often better than EXEC.
Free Powerpoint Templates
@Virendra Yaduvanshi 20
21. SELECT vs SET - A single SELECT statement
can assign values to different variables and is
much faster than multiple SET statements
assigning values to multiple different variables.
SELECT @Var1 = @Var1 + 1, @Var2 = @Var2 – 1
instead of
SET @Var1 = @Var1 + 1SET @Var2 = @Var2 - 1
Free Powerpoint Templates
@Virendra Yaduvanshi 21
22. WHERE clauses - In a WHERE clause, the various
operators used directly affect how fast a query can
run. Here are the conditional operators used in the
WHERE clause, ordered by their precedence.
=, >, <, >=, <=, <>, !=, !>, !<
Free Powerpoint Templates
@Virendra Yaduvanshi 22
23. Include Column List in INSERT Statement
Explicitly name the columns you are going to insert
with your INSERT statement
Do This
INSERT INTO A (COLA, COLB) VALUE(‘A’, ’B’);
Don’t do this
INSERT INTO A VALUE(‘A’, ’B’)
This allows you change the format of your table by
adding or removing columns without breaking your
INSERT statement.
Free Powerpoint Templates
@Virendra Yaduvanshi 23
24. Avoid using wildcard at the beginning of your search criteria
…WHERE LastName LIKE ‘%sen’
Doing this causes an index scan
Place a prefix in front of wildcard to SQL can use index seek to
find the records for your search criteria:
…WHERE LastName LIKE ‘L%sen’.
Might consider implementing full text search if you doing lots of
string searching
Free Powerpoint Templates
@Virendra Yaduvanshi 24
25. Scalar Function Calls in Column List and WHERE clause
Don’t execute scalar function in column list in a SELECT
statement or WHERE clause, if the scalar value function
returns data
Doing this causes cursor like performance
Function will be called for ever row returned
Replace scalar function with:
JOIN logic
inline table value function
view
Free Powerpoint Templates
@Virendra Yaduvanshi 25
26. Referencing Column Names in Function Calls Within WHERE Clause
Don’t use column names within a function call
SELECT * FROM MyTable
WHERE DATEADD(DAY,15,MyDate) = ‘05/01/2009’
Column that are used in functions are seen as expressions
instead of columns, therefore indexes can not be used
Doing this causes SQL Server to do an index scan or table scan
Instead move the column name outside the function call if possible
SELECT * FROM MyTable
WHERE MyDate = DATEADD(DAY,-15,’05/1/2009’)
Free Powerpoint Templates
@Virendra Yaduvanshi 26
27. Transactions
Avoid nested transactions. They aren’t truly nested:
COMMIT only saves data from the outermost transaction
ROLLBACK nukes ALL transactions, both innermost and
outermost
Orphaned Transactions
Errors don’t usually abort a transaction except for deadlocks
Returning from a procedure or batch does NOT commit a
transaction. Once a transaction is started, it remains open until:
The transaction is committed
The transaction is rolled back
The connection ends
Use @@TRANCOUNT or
sys.dm_tran_active_transactions to look for
orphaned transactions when entering a new routine
Keep transactions as short as possible!
Keep transactions explicit!
Remember lock escalation!
Free Powerpoint Templates
@Virendra Yaduvanshi 27
28. DDL/DML in Stored Procedure
Mixing DDL and DML operations causes a recompile
Certain operations on temporary tables cause a recompile
Refer to temp tables created locally
Don’t declare cursors that reference a temp table
Don’t create temp tables while in a loop
Free Powerpoint Templates
@Virendra Yaduvanshi 28
29. Interleaving DML/DDL Statements
Objects that dont's exist at procedure first execution cannot
be optimized until statement execution.
Upon execution of a DDL statement the procedure gets
recompiled to recompile the plans for the DML.
Don't interleave DDL and DML, Seperate it.
All DDL at the beginning of the proc, All DML later.
Try not to create tables conditionally ( IF create ... ELSE
create ...)
Use KEEP PLAN on SELECT statement id Data changes
more than 6 times but the plan should not change.
Free Powerpoint Templates
@Virendra Yaduvanshi 29
30. Queries with LIKE
Queries on production systems should NOT use
SELECT * FROM…
Main reason is that any time the underlying table is changed,
all query plans stored in the cache must be rebuilt
The SQL tools allow very quick scripting – so no excuses!
Queries that use the LIKE clause have two simple rules:
LIKE can use indexes if the pattern starts with a character
string, such as WHERE lname LIKE ‘w%’
LIKE cannot use an index if the pattern starts with a leading
wildcard, such as WHERE lname LIKE ‘%alton’
Free Powerpoint Templates
@Virendra Yaduvanshi 30
31. Queries with Functions & Calculations in the WHERE clause
Avoid using functions or calculations on the column
in a WHERE clause because it causes SQL Server
to ignore any index on the column:
WHERE qty * 12 > 10000
WHERE ISNULL(ord_date, ‘Jan 01,2001’) > ‘Jan 01, 2002 12:00:00 AM’
Instead, move the function or calculation to the SARG:
WHERE qty > 10000/12
WHERE ord_date IS NOT NULL AND ord_date > ‘Jan 01, 2002
12:00:00 AM’
Free Powerpoint Templates
@Virendra Yaduvanshi 31
32. Modifying Procedures
DROP and RECREATE
Loses the dependency chain stored in sysdepends
Loses the permissions already granted
Invalidates all plans
ALTER PROC
Loses the dependency chain stored in sysdepends
Retains the permissions
Invalidates all plans
To retain the dependency chain you must also
ALTER all procedures that depend on the
procedure being altered.
Free Powerpoint Templates
@Virendra Yaduvanshi 32
33. Temp Table Usage
Temp Table can create excessive recompilations for
procedures. Consider creating permanent tables (with
indexes) and manipulating data there.
Consider dropping and re-creating or rebuilding indexes as
part of the procedure instead!
Try not to create tables conditionally (IF create… ELSE
create…)
Use Profiler to see if there are significant recompiles
Use KEEP PLAN on SELECT statements if data changes
more than 6 times but the plan should not change
Free Powerpoint Templates
@Virendra Yaduvanshi 33
34. Table Variable Usage
Scope is limited to the local proceduretransaction
Does not cause excessive recompiles due to local
only access
No re-resolution on CREATE/ALTER
Temp Tables need re-resolution for nested procedures
Only Key Indexes can be created
Definition of Table allows PRIMARY KEY/UNIQUE
constraint indexes
Use TEMP TABLES if large volumes of data will be
manipulated – create the right indexes for access
Population
Does not support INSERT EXEC
Does not support SELECT INTO
Free Powerpoint Templates
@Virendra Yaduvanshi 34