Labels

Tuesday 31 May 2016

SQL Server Performance Tuning Part 4

Working on Performance Tuning is very tough task specially on large scale data hence the minor changes will give dramatic (+ Ve or -Ve) impact on performance.

Before going to tune the query as an experience developer you should aware on

If your application stops working suddenly, it may not be a database issue. For example, maybe you have a network problem. Investigate a bit before you approach the DBA!

The below are the few generic points for tuning.

Stored Procedure Level Tuning Tips

1. Include SET NOCOUNT ON statement:

2. Use schema name with object name:

3. Do not use the prefix “sp_” in the stored procedure name:

4. Use IF EXISTS (SELECT 1) instead of (SELECT *):

5. Use the sp_executesql stored procedure instead of the EXECUTE statement.

6. Try to avoid using SQL Server cursors whenever possible specially avoid cursors over temporary tables.

7. Keep the Transaction as short as possible:

8. Use TRY-Catch for error handling to get the accurate info.

9.  Use the sp_executesql stored procedure instead of temporary stored procedures.

10. Try to avoid using temporary tables inside your stored procedures.

Using temporary tables inside stored procedures reduce the chance to reuse the execution plan.

11. Try to avoid using DDL (Data Definition Language) statements inside your stored procedure.

Using DDL statements inside stored procedures also reduce the chance to reuse the execution plan.

12. Add the WITH RECOMPILE option to the CREATE PROCEDURE statement if you know that your query will vary each time it is run from the stored procedure.


13. Use SQL Server Profiler to determine which stored procedures have been recompiled too often.

SQL Server Performance Tuning Part 3

Before going to tune the query as an experience developer you should aware on

If your application stops working suddenly, it may not be a database issue. For example, maybe you have a network problem. Investigate a bit before you approach the DBA!

The below are the few generic points for tuning.

Transaction Level Tuning Tips

1. Avoid long-running transactions.

2.  Avoid transactions that require user input to commit.

3.  Access heavily used data at the end of the transaction.

4.  Try to access resources in the same order.

5. Use isolation level hints to minimize locking. For more information about isolation level please click here


6. Ensure that explicit transactions commit or roll back.

SQL Server Performance Tuning Part 2

Working on Performance Tuning is very tough task specially on large scale data hence the minor changes will give dramatic (+ Ve or -Ve) impact on performance.

Working on Performance Tuning is very tough task specially on large scale data hence the minor changes will give dramatic (+ Ve or -Ve) impact on performance.

Before going to tune the query as an experience developer you should aware on

If your application stops working suddenly, it may not be a database issue. For example, maybe you have a network problem. Investigate a bit before you approach the DBA!

The below are the few generic points for tuning.

Index Level Performance Tuning

1. Create indexes based on use. i.e don't create the index on the column where data type length is >=1000.

2.  Keep clustered index keys as small as possible.

3.  Consider range data for clustered indexes.

4. Create an index on all foreign keys.

5. Create highly selective indexes.

6.  Create a covering index for often-used, high-impact queries.

7. Use multiple narrow indexes rather than a few wide indexes.

8. Create composite indexes with the most restrictive column first otherwise it will leads key lockups in execution plan.

9. Consider indexes on columns used in WHERE, ORDER BY, GROUP BY, and DISTINCT clauses.

10.  Remove unused indexes.

11. Use the Index Tuning Wizard to identify the columns required index.


Algorithm or Tuning Mantra for SQL Code





SQL Server Performance tuning - Part 1

Working on Performance Tuning is very tough task specially on large scale data hence the minor changes will give dramatic (+ Ve or -Ve) impact on performance.

Before going to tune the query as an experience developer you should aware on

If your application stops working suddenly, it may not be a database issue. For example, maybe you have a network problem. Investigate a bit before you approach the DBA!

The below are the few generic points for tuning.

Query Level Tuning


1. Return only the rows and columns needed.

2. Avoid expensive operators such as NOT LIKE in filtered clauses.

3.  Avoid explicit or implicit functions in WHERE clauses.

4.  Use locking and isolation level hints to minimize locking.

5. Use stored procedures or parameterized queries.

6. Minimize cursor use.

7. Use temporary tables and table variables appropriately i.e keep heavy transactions table and function results in the  temp table table with required columns and then create the index on this temp table.

8. Limit query and index hint use.

9. Fully qualify database objects i.e keep <Database Name>.<Schema Name>.<Table Name>.



Monday 30 May 2016

Stored Procedures in SQL Server


                                                                STORED PROCEDURES
                                                                                                                                               
* To implement business logic which should be executed in the database server we can use SPs.
* It is a program, present in compiled format.
* Max size of SP is 250 MB
* It can take value(s) from front end part with input parameter.
* Once the SP is executed we can take values back to front end part with output parameters.
* A SP can receive max 1024 parameters.
* The aim of SP is to move business logic closer to data.

Advantages

                * To move business logic closer to data.
                * To implement high performance i.e no need the logic to compile again and again
                * To reduce n/w traffic i.e no need to send business logic to server again and again.
                * Easy enhancements.
                * Re-usability.
                * Reduces task of administration.
                * Providing security.

Types of SPs

                * System Defined

                                Ex:          sp_help, sp_helptext, sp_rename

    * User Defined

                                * Created by the developer.
                                * T-SQL SPs.
                                * CLR SPs.

Steps to create SP

1. Creating SP
                create proc/procedure <SP_Name>
                (
                                parameters
                )
                as
                begin
                                ----
                                ----
                                ----
                end

2. Executing SP
                Exec <SP_Name> [parameter values]

WAP without parameters

CREATE PROCEDURE p1
AS
BEGIN
 PRINT 'SQL and Sai Technologies'
END


Execution:
                           EXEC p1

Ex:          Create procedure which returns sum of 2 integers

Step1:   Creating SP

               CREATE PROCEDURE sum_sp
         AS
        BEGIN
 DECLARE @a INT
  ,@b INT
  ,@sum INT

 SET @a = 10
 SET @b = 20
 SET @sum = @a + @b

 PRINT @sum
        END

Step 2:   Calling SP

             EXEC sum_sp

FAQ:- Diff between S.P and View?

                View                                                     Stored Procedure
                                                                               
1) It consists of only SELECT cmd.              1) It can have any commands.
2) It cannot take parameters.                          2) It can take parameters.
3) We can call the view with select                3) Execute statement
    statement.
4) It is a stored query.                                     4) It is a reusable code component.

Note:
                1) To view the s.p definition

                                sp_helptext <spname>
                Ex:
                                sp_helptext dept_Noe_sp

                2) S.P definition is stored in syscomments table hence we can view it as follows.
                select text from syscomments where id=object_id('dept_noe_sp')

Stored Procedure Lifecycle

1) At the time of creation its details are stored in
                                                Sysobjects
                                                Syscomments
                                                Sysdepends
Note:
                To find the objects used in a stored procedure
                select name as objectName,xtype as object_Type from sysobjects where id=(select depid from sysdepends where id=(select id       from sysobjects where name='dept_noe_sp'))

2) First time calling
                                                * Compiled
                                                * Execution plan is generated.
                                                * Compiled code with execution plan is stored in   procedure  cache.
                                                * Executed.

3) Next time calling
                                                * Executed.
Note:
                To view the details of cached batches
                DBCC PROCCACHE

Procedure Cache

The procedure cache is used to cache the compiled and executable plans to speed up the execution of the batches.
The entries in a procedure cache are at a batch level. The procedure cache includes the following entries:
                * Compiled plans
                * Execution plans
                * Algebraic tree
                * Extended procedures

Working with Parameters

* Input Parameters

                                * These are used to pass data to the stored procedure at the time of calling.
                                * These are default type of parameters.
                                * We can initialize value for input parameter.
                                syn:
                                                @pname type [INPUT[=value]]
                                Ex:
                                                1) @eno int
                                                2) @premium Money Input
                                                3) @salary Money=1000

Note: If we initialize input parameter it becomes optional parameter. i.e at the time of calling s.p no need to mention value for this  parameter.

Ex:- Create a stored procedure which takes 2 integers and displays sum.

CREATE PROCEDURE Sum_sp (
 @a INT
 ,@b INT
 )
AS
BEGIN
 DECLARE @c INT --declaring local variable

 SET @c = @a + @b

 PRINT @c
END --end of SP

--calling s.p

EXEC Sum_sp 10,20
or
EXEC Sum_sp @a = 50 ,@b = 40 --it allows to pass values in any order as well as provides  better clarity.

Using Optional Parameters

* If we initialize value to input parameter then it becomes optional parameter.
Ex:

Step 1

CREATE PROCEDURE EMP1_SP (@dno INT = NULL)
AS
BEGIN
 IF @dno IS NULL
  SELECT *
  FROM EMP
 ELSE
  SELECT *
  FROM emp
  WHERE deptno = @dno
END

Step2

EXEC EMP1_SP      -- calling s.p without passing value for @dno which takes null
EXEC EMP1_sp @dno = 10 -- calling s.p for a particular dept details.

Working with OUTPUT parameters

These parameters are used to return values from the subprogram i.e return values from subprogram to client application. Here we can explicitly specify OUT keyword.

Ex: A procedure with OUTPUT parameter

CREATE PROCEDURE proc4 (
 @x INT
 ,@y INT @z INT OUTPUT
 )
AS
BEGIN
 SET @x = @x + @y
END

Execution:

DECLARE @a INT

EXECUTE proc2 500
 ,250
 ,@a OUTPUT

PRINT @a
Ex 2:

Develop a SP which takes empno and returns the provident fund and Professional tax at 12% and 50% respectively on the salary?

CREATE procedue deductions (
 @empno INT
 ,@pf MONEY OUTPUT
 ,@pt MONEY OUTPUT
 )
AS
BEGIN
 DECLARE @sal MONEY

 SELECT @sal = sal
 FROM emp
 WHERE empno = @empno

 SET @pf = @sal * 0.12
 SET @pt = @sal * 0.05
END

Execution:

DECLARE @vdf MONEY
 ,@vpt MONEY

EXEC deductions 1005
 ,@vpf OUTPUT
 ,@vpt OUTPUT

PRINT @vpf
PRINT @vpt

Develop a stored procedure to transfer amount from one account to the other within the bank table?

CREATE PROCEDURE funds_transfer (
 @srid INT
 ,@destid INT
 ,@amt MONEY
 )
AS
BEGIN
 UPDATE bank
 SET bal = bal - @amt
 WHERE custid = @srid

 UPDATE bank
 SET bal = bal + @amt
 WHERE custid = @destid
END

Execution:

EXECUTE funds_transfer 101,102,500

Note:
In the above case if the srid or destid are not present in the table then it will deduct the amount from the other or add the amount to other. To avoid this we need to use transaction management
To manage the transaction we need to identify which statement is executed and whic one failed for this we use the function @@rowcount
@@rowcount returns nof rows effected by the last statement

Handling Errors in SP (or) Working with TRY Catch block:

                It is used to manage or handle run time errors. In SQL Server 200 and 2005 @@error is used to manage run time errors

TRY:
                It contains the instruction that might cause an exception.

CATCH:

                It execute only when run-time errors occurs.

                                FUNCTION                                                          DESCRIPTION

                ERROR_NUMBER()                                                          Returns the number of the error.
                ERROR_SERVITY()                                                           Returns the severity level.
                ERROR_STATE()                                                                Returns the error state number.
                ERROR_PROCEDURE()                                                   Returns the name of the SP or                                                                                                                    Trigger where the error occurred.
                ERROR_LINE()                                                                   Returns the line number inside                                                                                                                  the routine that caused the error
                ERROR_MESSAGE()                                                        Returns the complete text of error message.  The text include the values  supplied for any substitutable parameters such as lengths,object names or times.

Note:
Servity levels are associated with the error. Range is b/n 0 and 25 , if it is >20 then client connection is terminated.

CREATE PROCEDURE div (
 @x INT
 ,@y INT
 )
AS
BEGIN
 DECLARE @z INT

 SET @z = 0
 SET @z = @x / @y

 PRINT ' The Output is:' + Cast(@z AS VARCHAR)
END

OutPut:
               EXEC div 100 ,20
         EXEC div 100,0

To resolve it:

               CREATE PROCEDURE DIV (
 @X INT
 ,@Y INT
 )
AS
BEGIN
 BEGIN TRY
  DECLARE @Z INT

  SET @Z = 0
  SET @Z = @X / @Y

  PRINT 'TEH OUTPUT IS:' + CAST(@Z AS VARCHAR)
 END TRY

 BEGIN CATCH
  PRINT ERROR_MESSAGE()
 END CATCH
END

Note:

We can write our own user defined error messages

CREATE PROCEDURE DIV (
 @X INT
 ,@Y INT
 )
AS
BEGIN
 BEGIN TRY
  DECLARE @Z INT

  SET @Z = 0
  SET @Z = @X / @Y

  PRINT 'TEH OUTPUT IS:' + CAST(@Z AS VARCHAR)
 END TRY

 BEGIN CATCH
  PRINT ERROR_MESSAGE()
 END CATCH
END

OutPut:
                EXEC DIVIX 100 ,1

Note:
                Raiserror statement raises the error but still net statement gets executed. Now if you want to stop the execution on the same line the code has to be enclosed within try catch blocks

CREATE PROCEDURE DIVIX (
 @X INT
 ,@Y INT
 )
AS
BEGIN
 BEGIN TRY
  DECLARE @Z INT

  SET @Z = 0

  IF @Y = 1
   RAISERROR (
     'CANNOT DIVIDE BY 1'
     ,15
     ,1
     )

  SET @Z = @X / @Y

  PRINT 'THE O/P IS:' + CAST(@Z AS VARCHAR)
 END TRY

 BEGIN CATCH
  PRINT ERROR_MESAGE()
 END CATCH
END

OutPut:

EXEC DIVIX 1001 ,1
               
Restrictions:

                Only member of sysadmin,db_owner or db_ddladmin can create & execute SP


Cursors in SQL Server

                                                                 CURSORS

Cursor is the location in memory where SQL Server tables are stored.
If memory location is created by SQLServer then  it is called as implicit cursor. Select statement will uses implicit cursors and it will show all records in the table at a time as a set
If memory location is created by programmer then it is called as  an explicit cursor, the tables stored in an explicit cursor is accessed row by row.

Cursor Life Cycle:

Declare:

In declare section of T-SQL program we are define cursor using following syntax
Declare cursor-name cursor for select statement
Ex: 

DECLARE cursor_emp CURSOR
FOR
SELECT *
FROM emp

Open:

Whenever we are opening the cursor automatically records are fetched from table and store it into cursor memory area

Fetch:

 We are fetching records from cursor and store it into T-SQL variables
Syn: Fetch from cursorname into variable name

Close:
                It closes the an opened cursor
                Close cursorname

Deallocate:

 Removes the cursor structure

                Deallocate cursorname

@@fetch_status:

                Retuns the state of the last cursor  fetch statement

                          Return Values                                       Description
                               
                               0                                            The fetch statement was successful.

                              -1                                            The fetch statement was failed or row                                                                                 was beyond the result set.

                               -2                                            The row fetched is missing.

Next:
                Returns the result row immediately following the current row and increments the row to the row returned.

First:
                Returns the first row in the cursor and makes it the current row.
Last:
                Returns the last row in the cursor and makes it current row.      

WAP Cursor program to print employee names and their salaries?

DECLARE empcur CURSOR FOR 
ELECT ename,sal 
     FROM   emp 

DECLARE @ename VARCHAR(20), 
        @sal   MONEY 

OPEN empcur 

FETCH next FROM empcur INTO @ename, @sal 

WHILE @@FETCH_STATUS = 0 
  BEGIN 
      PRINT 'salary of' + @ename + 'is' 
            + Cast(@sal AS VARCHAR) 

      FETCH next FROM empcur INTO @ename, @sal 
  END 

CLOSE empcur 

DEALLOCATE empcur 

 WA cursor to display emplyee monthly salry using global cursor

DECLARE empcur CURSOR global FOR 

 SELECT ename, 
         sal, 
         comm 
  FROM   emp 
DECLARE @ename    VARCHAR(50), 
        @sal      MONEY, 
        @comm     MONEY, 
        @totalsal MONEY 

OPEN empcur 

FETCH next FROM empcur INTO @ename, @sal, @comm 

WHILE @@FETCH_STATUS = 0 
  BEGIN 
      SET @totalsal =@sal + Isnull(@comm, 0) 

      PRINT @ename + 'Earns' + Cast(@totalsal AS VARCHAR) 
            + 'everymonth' 

      FETCH next FROM empcur INTO @ename, @sal, @comm 
  END 

CLOSE empcur 

Note: whenever we declare global cursor no need to deallocate it can be used for further program purpose

DECLARE @ename     VARCHAR(50), 
        @sal       MONEY, 
        @comm      MONEY, 
        @annualsal MONEY 

OPEN empcur 

FETCH next FROM empcur INTO @ename, @sal, @comm 

WHILE @@FETCH_STATUS = 0 
  BEGIN 
      SET @annualsal=( @sal + Isnull (@comm, 0) ) * 12 

      PRINT @ename + 'Earns' 
            + Cast(@annualsal AS VARCHAR) + 'Every Year' 

      FETCH next FROM empcur INTO @ename, @sal, @comm 
  END 

CLOSE empcur 

Ex:          Cursor to fetch alternate rows from emp table

DECLARE emp_cur scroll CURSOR FOR 
  SELECT empno, 
         ename 
  FROM   emp 

OPEN emp_cur 

DECLARE @empno INT, 
        @ename VARCHAR(40) 

FETCH next FROM emp_cur INTO @empno, @ename 

WHILE @@FETCH_STATUS !=- 1 
  BEGIN 
      PRINT Cast(@empno AS VARCHAR) + '   ' + @ename 

      FETCH relative 2 FROM emp_cur INTO @empno, @ename 
  END 

DEALLOCATE emp_cur 

Ex:          Write a cursor program which takes backup of all databases into d:\backups folder except system dbs
                
DECLARE backup_cur CURSOR FOR 
  SELECT NAME 
  FROM   sysdatabases 
  WHERE  NAME NOT IN( 'master', 'model', 'msdb', 'tempdb' ) 
DECLARE @filename VARCHAR(50), 
        @filepath VARCHAR(200) 
DECLARE @dbname VARCHAR(50) 

OPEN backup_cur 

FETCH next FROM backup_cur INTO @dbname 

WHILE @@fetch_status <>- 1 
  BEGIN 
      SET @filename=@dbname + '_' + CONVERT(VARCHAR, Getdate(), 112) 
                    + '.bak' 
      SET @filepath='d:\backups\' + @filename 

      BACKUP DATABASE @dbname TO DISK=@filepath 

      FETCH next FROM backup_cur INTO @dbname 
  END 

DEALLOCATE backup_cur