Tuesday, March 12, 2013

SQL SERVER – Stored Procedure Optimization Tips – Best Practices



We will go over how to optimize Stored Procedure with making simple changes in the code. Please note there are many more other tips, which we will cover in future articles.
  • Include SET NOCOUNT ON statement: With every SELECT and DML statement, the SQL server returns a message that indicates the number of affected rows by that statement. This information is mostly helpful in debugging the code, but it is useless after that. By setting SET NOCOUNT ON, we can disable the feature of returning this extra information. For stored procedures that contain several statements or contain Transact-SQL loops, setting SET NOCOUNT to ON can provide a significant performance boost because network traffic is greatly reduced.
-->
CREATE PROC dbo.ProcName
AS
SET
NOCOUNT ON;
--Procedure code here
SELECT column1 FROM dbo.TblTable1
-- Reset SET NOCOUNT to OFF
SET NOCOUNT OFF;
GO
  • Use schema name with object name: The object name is qualified if used with schema name. Schema name should be used with the stored procedure name and with all objects referenced inside the stored procedure. This help in directly finding the complied plan instead of searching the objects in other possible schema before finally deciding to use a cached plan, if available. This process of searching and deciding a schema for an object leads to COMPILE lock on stored procedure and decreases the stored procedure’s performance. Therefore, always refer the objects with qualified name in the stored procedure like
SELECT * FROM dbo.MyTable -- Preferred method
-- Instead of
SELECT * FROM MyTable -- Avoid this method
--And finally call the stored procedure with qualified name like:
EXEC dbo.MyProc -- Preferred method
--Instead of
EXEC MyProc -- Avoid this method
  • Do not use the prefix “sp_” in the stored procedure name: If a stored procedure name begins with “SP_,” then SQL server first searches in the master database and then in the current session database. Searching in the master database causes extra overhead and even a wrong result if another stored procedure with the same name is found in master database.
  • Use IF EXISTS (SELECT 1) instead of (SELECT *): To check the existence of a record in another table, we uses the IF EXISTS clause. The IF EXISTS clause returns True if any value is returned from an internal statement, either a single value “1” or all columns of a record or complete recordset. The output of the internal statement is not used. Hence, to minimize the data for processing and network transferring, we should use “1” in the SELECT clause of an internal statement, as shown below:
IF EXISTS (SELECT 1 FROM sysobjects
WHERE name = 'MyTable' AND type = 'U')
  • Use the sp_executesql stored procedure instead of the EXECUTE statement.
    The sp_executesql stored procedure supports parameters. So, using the sp_executesql stored procedure instead of the EXECUTE statement improve the re-usability of your code. The execution plan of a dynamic statement can be reused only if each and every character, including case, space, comments and parameter, is same for two statements. For example, if we execute the below batch:
DECLARE @Query VARCHAR(100)
DECLARE @Age INT
SET
@Age = 25
SET @Query = 'SELECT * FROM dbo.tblPerson WHERE Age = ' + CONVERT(VARCHAR(3),@Age)
EXEC (@Query)
If we again execute the above batch using different @Age value, then the execution plan for SELECT statement created for @Age =25 would not be reused. However, if we write the above batch as given below,
DECLARE @Query NVARCHAR(100)
SET @Query = N'SELECT * FROM dbo.tblPerson WHERE Age = @Age'
EXECUTE sp_executesql @Query, N'@Age int', @Age = 25
the compiled plan of this SELECT statement will be reused for different value of @Age parameter. The reuse of the existing complied plan will result in improved performance.
  • Try to avoid using SQL Server cursors whenever possible: Cursor uses a lot of resources for overhead processing to maintain current record position in a recordset and this decreases the performance. If we need to process records one-by-one in a loop, then we should use the WHILE clause. Wherever possible, we should replace the cursor-based approach with SET-based approach. Because the SQL Server engine is designed and optimized to perform SET-based operation very fast. Again, please note cursor is also a kind of WHILE Loop.
  • Keep the Transaction as short as possible: The length of transaction affects blocking and deadlocking. Exclusive lock is not released until the end of transaction. In higher isolation level, the shared locks are also aged with transaction. Therefore, lengthy transaction means locks for longer time and locks for longer time turns into blocking. In some cases, blocking also converts into deadlocks. So, for faster execution and less blocking, the transaction should be kept as short as possible.
  • Use TRY-Catch for error handling: Prior to SQL server 2005 version code for error handling, there was a big portion of actual code because an error check statement was written after every t-sql statement. More code always consumes more resources and time. In SQL Server 2005, a new simple way is introduced for the same purpose. The syntax is as follows:
BEGIN TRY
--Your t-sql code goes here
END TRY
BEGIN CATCH
--Your error handling code goes here
END CATCH
Reference: Pinal Dave (http://blog.SQLAuthority.com)

-->

Thursday, December 20, 2012

UI Design using Bootstrap

CSS Design UI using bootstrap Link: http://twitter.github.com/bootstrap/index.html

Sunday, September 23, 2012

Select 4th row in Sqlserver

Hi This is Simple example for getting 2nd or 4th row record frome SQL Server. Code: SELECT items FROM (SELECT ROW_NUMBER() OVER (ORDER BY items) AS RowNum, items FROM Tablename) sub WHERE RowNum = 4

Wednesday, April 25, 2012

Replace Square box in SQL table

In Sql Table some Column have value of Square box, if you want to remove that box please use below SQL Query:

 select REPLACE(ColumnName,char(13),'') from YourTable

 If You want to use in Where condition trim that Square box use this :

 where REPLACE(ColumnName,char(13),'')in ('ColumnValue')
-->

Thursday, December 8, 2011

Microsoft Sample code

Hi This like will help to get Microsoft sample codes:

http://code.msdn.microsoft.com/

.Net Video tutorial in Tamil
http://www.youtube.com/user/reach2arunprakash/

Saturday, December 3, 2011

Bulk Upload in Sql server (using from OpenXML)

C# Code:

xml = " xml += " Element='SaveMyData' ";
xml += "EmpID='" + 1 + "' ";
xml += "EmpName='" + vijay + "' ";
xml += "EmpValue='" + 100 + "' />
";

IN SQL Server Stored Procedure:

CREATE PROCEDURE [dbo].[MyStoredProcedure]
@ActionType Varchar(20),
@XML text
AS
BEGIN
SET NOCOUNT ON
Declare @intRow int
Exec sp_xml_preparedocument @intRow Output, @xml
IF @ActionType ='Insert'
BEGIN

//Insert Query with Where condition

Insert into EmpEmployee (EmpID,EmpName,EmpValue)
Select xEmpID,xEmpName,xEmpValue
from OpenXML(@intRow,'/root/row[@Element="SaveMyData"]')
With
( xEmpID int '@EmpID', xEmpName varchar (50) '@EmpName', xEmpValue varchar (50) '@EmpValue', ) where xEmpID not in (select EmpID from EmpEmployee where EmpID=xEmpID,EmpName=xEmpName)

//Update Query with Where condition

Update EmpEmployee (EmpID=xEmpID,EmpName=xEmpName,EmpValue=xEmpValue)
from OpenXML(@intRow,'/root/row[@Element="SaveMyData"]') With ( xEmpID int '@EmpID', xEmpName varchar (50) '@EmpName', xEmpValue varchar (50) '@EmpValue', ) where EmpID=xEmpID and EmpName=xEmpName)

End
exec sp_xml_removedocument @intRow
END

Tuesday, November 22, 2011

Windows Application Error Handling & Check Allready Application Running

Windows Application Error Handling :

In the windows entire application or while opening an application if you get any exception means the below code will help you to capture the error log. The application error or exception handling you can identify the error message. This will help you to understand the problem in your windows application using C#.Net. The below code is start up point of the win application. The program.cs class only first fire in the application.



Application Error Log


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
 
namespace MyProject
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 

 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
          
            Control.CheckForIllegalCrossThreadCalls = true;
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
 
            //get the name of current process, i,e the process 
            //name of this current application
 
            string currPrsName = Process.GetCurrentProcess().ProcessName;
 
            //Get the name of all processes having the 
            //same name as this process name 
            Process[] allProcessWithThisName= Process.GetProcessesByName(currPrsName);
 
            //if more than one process is running return true.
            //which means already previous instance of the application 
            //is running
            if (allProcessWithThisName.Length > 1)
            {
                MessageBox.Show("The Application Already Running", "MY APP", MessageBoxButtons.OK);
                Application.Exit();
               // allProcessWithThisName[0].Kill();
                System.Diagnostics.Process.GetCurrentProcess().Kill();
            }
            else
            {  
                frmMain mainForm = new frmMain(); //this takes ages 
                Application.Run(mainForm);
            }
        }
 
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject != null)
                ErrorLog((Exception)e.ExceptionObject);
        }
 
        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            if (e.Exception != null)
                ErrorLog(e.Exception);
        }            
 
    }
}





 //Windows application Error Log

using System.IO;
       
 public static void ErrorLog(string sMessage)
        {
            StreamWriter objSw = null;
            try
            {
                string sFolderName = Application.StartupPath + @"\Logs\";
                if (!Directory.Exists(sFolderName))
                    Directory.CreateDirectory(sFolderName);
                string sFilePath = sFolderName + "Error.log";

                objSw = new StreamWriter(sFilePath, true);
                objSw.WriteLine(DateTime.Now.ToString() + " " + sMessage + Environment.NewLine);

            }
            catch (Exception ex)
            {
                Comman.ErrorLog("Error -" + ex.Message);
            }
            finally
            {
                if (objSw != null)
                {
                    objSw.Flush();
                    objSw.Dispose();
                }
            }
        }





Check Allready Application Running:

string currPrsName = Process.GetCurrentProcess().ProcessName;

//Get the name of all processes having the
//same name as this process name
Process[] allProcessWithThisName
= Process.GetProcessesByName(currPrsName);

//if more than one process is running return true.
//which means already previous instance of the application
//is running
if (allProcessWithThisName.Length > 1)
{
MessageBox.Show("Application Already Running", "Test", MessageBoxButtons.OK);
Application.Exit();
}
else
{
Application.Run(new frmMain());
}

-->