-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- Written by Kimberly L. Tripp, SQLskills.com -- All Rights Reserved. -- -- For more scripts, sample code and additional training resources, -- go to http://www.SQLskills.com -- Immerse yourself in SQL Server -- -- Disclaimer - Thoroughly test this script, execute at your own risk. -- -- For better formatting, I use 4 characters instead of 8 - for tabs. -- See Tools (menu), Options (dialog), Editor (tab) -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SET STATISTICS IO ON -- Turn Graphical Showplan ON (Ctrl+K) USE CREDIT go -- Update a rows to later search on... UPDATE dbo.member SET firstname = 'Katie' WHERE member_no = 8234 go IF OBJECTPROPERTY(object_id('GetMemberInfoParam'), 'IsProcedure') = 1 DROP PROC dbo.GetMemberInfoParam go CREATE PROC dbo.GetMemberInfoParam ( @Lastname varchar(30) = NULL, @Firstname varchar(30) = NULL, @member_no int = NULL ) AS SET NOCOUNT ON SELECT m.* FROM dbo.member AS m WHERE (m.lastname LIKE @lastname OR @lastname IS NULL) AND (m.member_no = @member_no OR @member_no IS NULL) AND (m.firstname LIKE @firstname OR @firstname IS NULL) go --------------------------------------------------------------- -- Make sure to look at the plan of execution AND the I/Os. -- Both of these will run FAST but what's wrong...... EXEC dbo.GetMemberInfoParam @Lastname = 'Tripp' WITH RECOMPILE go EXEC dbo.GetMemberInfoParam @Firstname = 'Katie' WITH RECOMPILE go EXEC dbo.GetMemberInfoParam @Member_no = 9912 WITH RECOMPILE go -- What's wrong is that all of these conditions were ANDed together -- and since AND progressively limits the search the QP said... -- "I only need to look for something which is *selective*." -- Well, the most selective criteria in this query is Member_no -- so that's the best choice for an index. So - no matter which -- parameter(s) you supply you will always use the member_no -- index... Which is HORRIBLE if/when you don't pass in member_no. --------------------------------------------------------------- IF OBJECTPROPERTY(object_id('GetMemberInfoParamDSE'), 'IsProcedure') = 1 DROP PROC dbo.GetMemberInfoParamDSE go CREATE PROC dbo.GetMemberInfoParamDSE ( @Lastname varchar(30) = NULL, @Firstname varchar(30) = NULL, @member_no int = NULL ) AS SET NOCOUNT ON IF @LastName IS NULL AND @FirstName IS NULL AND @Member_no IS NULL RAISERROR ('You must supply at least one parameter.', 16, -1) DECLARE @ExecStr varchar(1000) , @MemberNoStr varchar(100) SELECT @ExecStr = 'SELECT m.* FROM dbo.member AS m WHERE ' IF @LastName IS NOT NULL SELECT @Lastname = 'm.lastname LIKE ' + QUOTENAME(@lastname, '''') IF @FirstName IS NOT NULL SELECT @Firstname = 'm.firstname LIKE ' + QUOTENAME(@firstname, '''') IF @Member_no IS NOT NULL SELECT @MemberNoStr = 'm.member_no = ' + convert(varchar(5), @member_no) SELECT @ExecStr = @ExecStr + ISNULL(@LastName, ' ') + CASE WHEN @LastName IS NOT NULL AND @FirstName IS NOT NULL THEN ' AND ' ELSE ' ' END + ISNULL(@FirstName, ' ') + CASE WHEN (@LastName IS NOT NULL OR @FirstName IS NOT NULL) AND @MemberNoStr IS NOT NULL THEN ' AND ' ELSE ' ' END + ISNULL(@MemberNoStr, ' ') EXEC(@ExecStr) go EXEC dbo.GetMemberInfoParamDSE @Lastname = 'test' , @FirstName = 'Katie' go EXEC dbo.GetMemberInfoParamDSE @Firstname = 'Katie' go EXEC dbo.GetMemberInfoParamDSE @Firstname = 'Katie' , @Member_no = 842 go EXEC dbo.GetMemberInfoParamDSE @Member_no = 9912 go EXEC dbo.GetMemberInfoParamDSE @Lastname = 'Florini' , @Member_no = 9912 go -- And if you have better index choices..... well, the above -- would have benefited from those as well. Add these -- and run the above again. CREATE INDEX MemberLastNameInd ON Member(LastName) CREATE INDEX MemberFirstNameInd ON Member(FirstName) -- but there's A LOT more to appropriate indexing than -- just creating an index for every SARG (search argument) -- Check out the msdn webcast I did recently. Review this -- blog entry for a complete list of everything: -- http://www.sqlskills.com/blogs/kimberly/PermaLink.aspx?guid=ecdcd11b-9eb7-4d88-b20c-b9225990080a -- Hope this helps! -- Have fun, -- kt