Archive

Posts Tagged ‘performance’

Native Dynamic SQL in SQL Server (Late Binding)

May 2nd, 2009 Administrator 3 comments

I was trying to figure out how to use Native Dynamic SQL in SQL Server (using late binding) for performance reasons. With late binding, you are able to reuse cached execution plans and therefore can get better performance. This also keeps you from having from having to create the same query multiple times in a stored procedure just to allow for different filter criteria. You can build the SQL on the fly, bind the parameters and execute the SQL on the fly.

Here’s what I ended up with.


USE [database]

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE PROCEDURE [dbo].[proc]

@Parm1 INT,

@Parm2 INT,

@Parm3 DATETIME,

AS

SET NOCOUNT ON

DECLARE

@SELECT NVARCHAR(1000),

@FROM NVARCHAR(1000),

@WHERE NVARCHAR(1000),

@ORDERBY NVARCHAR(1000),

@SQL NVARCHAR(4000),MAX SIZE for dynamic SQL is 4000 characters

@DYNSQLPARMLIST NVARCHAR(250),

@vParm3 CHAR(10)

 

-1 implies ALL. Set -1s to NULL for COALESCE functions in SQL

IF @Parm1 = -1 SET @Parm1 = NULL

IF @Parm2 = -1 SET @Parm2 = NULL

 

SET @vParm3 = CONVERT(char, @Parm3, 101) /*Just a placeholder for easier dyn sql conversion*/

 

/*For some reason, dynamic sql can’t handle s or linefeeds in this section, so they’re all on one line with spaces separating them*/

/*Note, the DATETIME parameter is not in CHAR format. Again, this is just because I’m building a string for the SQL*/

SET @DYNSQLPARMLIST = N’@dynParm1 INT, @dynParm2 INT, @dynParm3 CHAR(10)

 

/*Build the SQL. Note the parameters match the parameters in the @DYNSQLPARMLIST variable. @dynParm1, not @Parm1*/

SET @SELECT =SELECT *

SET @FROM =FROM table1 with (nolock)

SET @WHERE =WHERE column1 = COALESCE(@dynParkID, column1)if null, set column = to itself (no filter)

AND column2 = COALESCE(@dynInformationTypeID, column2)

AND column3 > cast(@dynParm3 as datetime)

SET @ORDER =ORDER BY 1?

 

SET @SQL =

@SELECT + ‘ ‘ +

@FROM + ‘ ‘ +

@WHERE + ‘ ‘ +

@ORDERBY

 

EXECUTE sp_executesql

@SQL,

@DYNSQLPARMLIST,

@dynParm1 = @Parm1,

@dynParm2 = @Parm2,

@dynParm3 = @vParm3

 

SET NOCOUNT OFF

For more information, check out this page: http://ping.fm/mOmXI

VN:F [1.5.8_856]

Rating: 4.0/5 (1 vote cast)
VN:F [1.5.8_856]
Rating: 0 (from 0 votes)

Using Statistics to Improve Query Performance in SQL Server

May 1st, 2009 NothingMan No comments

Like all other query optimizers, SQL uses statistics to create query plans that improve query performance. The optimizer generally generates the necessary statistics for a high quality query plan, however, in a few cases, you need to create additional statistics or modify the query design for “optimal” results.

Query Optimization Statistics are objects that contain statistical information about the distribution of values in one or more columns of a table or indexed view. The query optimizer uses these statistics to estimate the cardinality, or number of rows, in the query result. These cardinality estimates enable the query optimizer to create a high-quality query plan. For example, the query optimizer could use cardinality estimates to choose the index seek operator instead of the more resource-intensive index scan operator, and in doing so improve query performance.

You can create statistics objects with filters to improve query performance for queries that select from well-defined subsets of data. They use a filter predicate to select the subset of data that is included in the statistics. Well-designed filtered statistics can improve the query execution plan compared with full-table statistics.

Syntax

CREATE STATISTICS statistics_name
ON { table_or_indexed_view_name } ( column [ ,...n ] )
  [ WHERE <filter_predicate> ]
  [ WITH
  [ [ FULLSCAN
   | SAMPLE number { PERCENT | ROWS }
   | STATS_STREAM = stats_stream ] [ , ] ]
  [ NORECOMPUTE ]
] ;

<filter_predicate> ::=
  <conjunct> [AND ]

<conjunct> ::=
  <disjunct> | <comparison>

<disjunct> ::=
  column_name IN (constant ,…)

<comparison> ::=
  column_name <comparison_op> constant

<comparison_op> ::=
  IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !<

SAMPLES

USE AdventureWorks;
GO
CREATE STATISTICS ContactMail1
  ON Person.Contact (ContactID, EmailAddress)
  WITH SAMPLE 5 PERCENT;

OR

IF EXISTS (SELECT name FROM sys.stats
  WHERE name = N'ContactPromotion1'
  AND object_id = OBJECT_ID(N'Person.Contact'))
DROP STATISTICS Person.Contact.ContactPromotion1
GO
CREATE STATISTICS ContactPromotion1
  ON Person.Contact (ContactID, EmailAddress, EmailPromotion)
WHERE EmailPromotion = 2
WITH SAMPLE 50 PERCENT;
GO

For more information, see http://msdn.microsoft.com/en-us/library/ms188038.aspx

For information about when to CREATE STATISTICS, see http://msdn.microsoft.com/en-us/library/ms188038.aspx

VN:F [1.5.8_856]

Rating: 4.0/5 (1 vote cast)
VN:F [1.5.8_856]
Rating: 0 (from 0 votes)

Creating Index with the INCLUDE clause to Increase Performance

April 30th, 2009 NothingMan No comments

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 491520 bytes) in /home1/golfcomp/public_html/rickcaminiti/wp-content/plugins/gd-star-rating/code/t2/templates.php on line 155