Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7516621
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T01:11:24+00:00 2026-05-30T01:11:24+00:00

In a database I have less than 200,000 records in a table, and in

  • 0

In a database I have less than 200,000 records in a table, and in a stored procedure I am referencing a couple of views that perform several LEFT JOINs and other joins.

One of the views used contains four LEFT OUTER JOINs, another two contain several INNER JOINs just linking tables/data.

When viewing the sproc execution plan, I saw that one query was taking up 39% of the execution time. The suggestion in green was to create a nonclustered index on two fields of the master table, which I did (already contained a clustered index, as it contains an auto-incrementing PK).

After adding this, the execution time didn’t drop that much, and is currently hovering around 2.5 seconds.

Is this to be expected?

I am partial to keeping things (although maybe not normalized) in large master tables, thus eliminating the need for views/joins.

Would it be bests to refactor the db in this way, at this time?

UPDATE

This sproc runs through about 14 different rules to find matches. If a match is found, content is appended to a global parameter. Thus, to check for each rule, there is a separate query.

Instead of having 14 or so queries in the one sproc, I created separate sprocs and called them using EXEC, passing in (along with other parameters) and returning that global parameter.

I performed an execution plan with SET SHOWPLAN_ALL ON.

The first culprit (shows total subtree cost of 4.408248)

   SELECT @ExternalTagName = etbs.ExternalTagName, @ExternalTagID = etbs.ExternalTagID, @ExternalPixelValue = etbs.ExternalPixelValue, @TriggerAlpha = ISNULL(SUM(dbo.FindInString(etbs.TriggerValue, @DocumentUrl)), '')   FROM vw_ETBS etbs   WHERE etbs.SystemBehaviouralSegmentID = 9  -- page url contains   AND etbs.AccountContainerID = @AccountContainerID   AND etbs.IsEnabled = 1    AND etbs.TriggerValue = @TriggerAlpha   GROUP BY ExternalPixelValue, etbs.ExternalTagID, etbs.ExternalTagName     --INSERT INTO DebugTable (DebugKey, DebugValue)   --VALUES ('after sql', 'test')  79  259 1   NULL    NULL    67  NULL    63.26242    NULL    NULL    NULL    4.408248    NULL    NULL    SELECT  0   NULL
       |--Compute Scalar(DEFINE:([Expr1016]=CONVERT_IMPLICIT(varchar(6000),[ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue],0), [Expr1017]=CONVERT_IMPLICIT(varchar(512),isnull([Expr1015],(0)),0))) 79  260 259 Compute Scalar  Compute Scalar  DEFINE:([Expr1016]=CONVERT_IMPLICIT(varchar(6000),[ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue],0), [Expr1017]=CONVERT_IMPLICIT(varchar(512),isnull([Expr1015],(0)),0))   [Expr1016]=CONVERT_IMPLICIT(varchar(6000),[ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue],0), [Expr1017]=CONVERT_IMPLICIT(varchar(512),isnull([Expr1015],(0)),0)    63.26242    0   6.326241E-06    3293    4.408248    [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID], [Expr1016], [Expr1017]    NULL    PLAN_ROW    0   1
            |--Compute Scalar(DEFINE:([Expr1015]=CASE WHEN [Expr1029]=(0) THEN NULL ELSE [Expr1030] END))   79  261 260 Compute Scalar  Compute Scalar  DEFINE:([Expr1015]=CASE WHEN [Expr1029]=(0) THEN NULL ELSE [Expr1030] END)  [Expr1015]=CASE WHEN [Expr1029]=(0) THEN NULL ELSE [Expr1030] END   63.26242    0   0.004639106 4063    4.408242    [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID], [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue], [Expr1015]   NULL    PLAN_ROW    0   1
                 |--Stream Aggregate(GROUP BY:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID]) DEFINE:([Expr1029]=COUNT_BIG([ROTags-Shopify-Alpha].[dbo].[FindInString]([Expr1019],CONVERT_IMPLICIT(varchar(max),[@DocumentUrl],0))), [Expr1030]=SUM([ROTags-Shopify-Alpha].[dbo].[FindInString]([Expr1019],CONVERT_IMPLICIT(varchar(max),[@DocumentUrl],0))), [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue]=ANY([ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue]))) 79  262 261 Stream Aggregate    Aggregate   GROUP BY:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID]) [Expr1029]=COUNT_BIG([ROTags-Shopify-Alpha].[dbo].[FindInString]([Expr1019],CONVERT_IMPLICIT(varchar(max),[@DocumentUrl],0))), [Expr1030]=SUM([ROTags-Shopify-Alpha].[dbo].[FindInString]([Expr1019],CONVERT_IMPLICIT(varchar(max),[@DocumentUrl],0))), [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue]=ANY([ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue])    63.26242    0   0.004639106 4063    4.408242    [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID], [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue], [Expr1029], [Expr1030]   NULL    PLAN_ROW    0   1
                      |--Sort(ORDER BY:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName] ASC, [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID] ASC))  79  263 262 Sort    Sort    ORDER BY:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName] ASC, [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID] ASC) NULL    7679.125    0.01126126  0.311861    4125    4.403603    [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID], [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue], [Expr1019]   NULL    PLAN_ROW    0   1
                           |--Nested Loops(Inner Join, OUTER REFERENCES:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[VisitorTriggeredTagID], [Expr1028]) WITH UNORDERED PREFETCH)   79  264 263 Nested Loops    Inner Join  OUTER REFERENCES:([ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[VisitorTriggeredTagID], [Expr1028]) WITH UNORDERED PREFETCH   NULL    7679.125    0   0.03209874  4133    4.076795    [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagName], [ROTags-Shopify-Alpha].[dbo].[VisitorTriggeredExternalTag].[ExternalTagID], [ROTags-Shopify-Alpha].[dbo].[ExternalTagList].[ExternalPixelValue], [Expr1019]   NULL    PLAN_ROW    0   1

SELECT @ExternalTagName = ExternalTagName, @ExternalTagID = ExternalTagID, @ExternalPixelValue = ExternalPixelValue, @TriggerNumeric = COUNT(*)
FROM vw_ETBS
WHERE SystemBehaviouralSegmentID = 10       -- direct traffic
AND AccountContainerID = @AccountContainerID    
AND vw_ETBS.IsEnabled = 1
GROUP BY ExternalPixelValue, ExternalTagID, ExternalTagName

vw_ETBS:

SELECT [lots of individual fields]
FROM    dbo.VisitorTriggeredExternalTag LEFT OUTER JOIN
        dbo.PageVisitEvents ON dbo.VisitorTriggeredExternalTag.PageVisitEventID = dbo.PageVisitEvents.PageVisitEventID LEFT OUTER JOIN
        dbo.ExternalTagBehaviouralSegments ON dbo.VisitorTriggeredExternalTag.ExternalTagID = dbo.ExternalTagBehaviouralSegments.ExternalTagID LEFT OUTER JOIN
        dbo.ExternalTagList ON dbo.ExternalTagBehaviouralSegments.ExternalTagID = dbo.ExternalTagList.ExternalTagID LEFT OUTER JOIN
        dbo.AccountContainers ON dbo.ExternalTagList.AccountContainerID = dbo.AccountContainers.AccountContainerID
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T01:11:25+00:00Added an answer on May 30, 2026 at 1:11 am

    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
    

    For More info refer this Link U will get better idea.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have this stored procedure in my database: ALTER PROCEDURE [dbo].[sp_FTSearchLocation] @SearchFor nvarchar(200) =
I have sets of strings in a database. Each set will have less than
In my database I have tables that define types for example Table: Publication Types
I have a database table containing credit card records. One of the fields is
We have a database that has a bunch of records with some bad data
We have a operation in which more than 100.000 records are read from a
I have a database DB and I want to delete records from table MyRecords
I have a SQL query that takes less than a second to execute when
I am going to have a database with several (less than 10) main tables.
I heard that decision tables in relational database have been researched a lot in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.