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 8077403
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T15:27:59+00:00 2026-06-05T15:27:59+00:00

I have this query… SELECT Distinct([TargetAttributeID]) FROM (SELECT distinct att1.intAttributeID as [TargetAttributeID] FROM AST_tblAttributes

  • 0

I have this query…

SELECT Distinct([TargetAttributeID]) FROM
    (SELECT distinct att1.intAttributeID as [TargetAttributeID]
        FROM AST_tblAttributes att1
        INNER JOIN
        AST_lnkProfileDemandAttributes pda
        ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID

    union all

    SELECT distinct ca2.intAttributeID as [TargetAttributeID] FROM
        AST_lnkCapturePolicyAttributes ca2
        INNER JOIN
        AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
        WHERE ec2.dteCreatedDate >= @cutoffdate) x

Execution Plan for the above query

The two inner distincts are looking at 32 and 10,000 rows respectively. This query returns 5 rows and executes in under 1 second.

If I then use the result of this query as the subject of an IN like so…

SELECT attx.intAttributeID,attx.txtAttributeName,attx.txtAttributeLabel,attx.txtType,attx.txtEntity FROM
    AST_tblAttributes attx WHERE attx.intAttributeID 
    IN
    (SELECT Distinct([TargetAttributeID]) FROM
    (SELECT Distinct att1.intAttributeID as [TargetAttributeID]
        FROM AST_tblAttributes att1
        INNER JOIN
        AST_lnkProfileDemandAttributes pda
        ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID
    union all
    SELECT  Distinct ca2.intAttributeID as [TargetAttributeID] FROM
        AST_lnkCapturePolicyAttributes ca2
        INNER JOIN
        AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
        WHERE ec2.dteCreatedDate >= @cutoffdate) x)

Execution Plan for the above query

Then it takes over 3 minutes! If I just take the result of the query and perform the IN “manually” then again it comes back extremely quickly.

However if I remove the two inner DISTINCTS….

SELECT attx.intAttributeID,attx.txtAttributeName,attx.txtAttributeLabel,attx.txtType,attx.txtEntity FROM
    AST_tblAttributes attx WHERE attx.intAttributeID 
    IN
    (SELECT Distinct([TargetAttributeID]) FROM
    (SELECT att1.intAttributeID as [TargetAttributeID]
        FROM AST_tblAttributes att1
        INNER JOIN
        AST_lnkProfileDemandAttributes pda
        ON pda.intAttributeID=att1.intAttributeID AND pda.intProfileID = @intProfileID
    union all
    SELECT ca2.intAttributeID as [TargetAttributeID] FROM
        AST_lnkCapturePolicyAttributes ca2
        INNER JOIN
        AST_lnkEmployeeCapture ec2 ON ec2.intAdminCaptureID = ca2.intAdminCaptureID AND ec2.intTeamID = 57
        WHERE ec2.dteCreatedDate >= @cutoffdate) x)

Execution Plan for the above query

..then it comes back in under a second.

What is SQL Server thinking? Can it not figure out that it can perform the two sub-queries and use the result as the subject of the IN. It seems as slow as a correlated sub-query, but it isn’t correlated!!!

In Show Estimate Execution plan there are three Clustered Index Scans each with a cost of 100%! (Execution Plan is here)

Can anyone tell me why the inner DISTINCTS make this query so much slower (but only when used as the subject of an IN…) ?

UPDATE

Sorry it’s taken me a while to get these execution plans up…

Query 1

Query 2 (The slow one)

Query 3 – No Inner Distincts

  • 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-06-05T15:28:00+00:00Added an answer on June 5, 2026 at 3:28 pm

    Honestly I think it comes down to the fact that, in terms of relational operators, you have a gratuitously baroque query there, and SQL Server stops searching for alternate execution plans within the time it allows itself to find one.

    After the parse and bind phase of plan compilation, SQL Server will apply logical transforms to the resulting tree, estimate the cost of each, and choose the one with the lowest cost. It doesn’t exhaust all possible transformations, just as many as it can compute within a given window. So presumably, it has burned through that window before it arrives at a good plan, and it’s the addition of the outer semi-self-join on AST_tblAttributes that pushed it over the edge.

    How is it gratuitously baroque? Well, first off, there’s this (simplified for noise reduction):

    select distinct intAttributeID from (
       select distinct intAttributeID from AST_tblAttributes ....
       union all
       select distinct intAttributeID from AST_tblAttributes ....
       )
    

    Concatenating two sets, and projecting the unique elements? Turns out there’s operator for that, it’s called UNION. So given enough time during plan compilation and enough logical transformations, SQL Server will realize what you really mean is:

    select intAttributeID from AST_tblAttributes ....
    union
    select intAttributeID from AST_tblAttributes ....
    

    But wait, you put this in a correlated subquery. Well, a correlated subquery is a semi-join, and the right relation does not require logical dedupping in a semi-join. So SQL Server may logically rewrite the query as this:

    select * from AST_tblAttributes
    where intAttributeID in (
      select intAttributeID from AST_tblAttributes ....
      union all
      select intAttributeID from AST_tblAttributes ....
      )
    

    And then go about physical plan selection. But to get there, it has to see though the cruft first, and that may fall outside the optimization window.


    EDIT:

    Really, the way to explore this for yourself, and corroborate the speculation above, is to put both versions of the query in the same window and compare estimated execution plans side-by-side (Ctrl-L in SSMS). Leave one as is, edit the other, and see what changes.

    You will see that some alternate forms are recognized as logically equivalent and generate to the same good plan, and others generate less optimal plans, as you bork the optimizer.**

    Then, you can use SET STATISTICS IO ON and SET STATISTICS TIME ON to observe the actual amount of work SQL Server performs to execute the queries:

    SET STATISTICS IO ON
    SET STATISTICS TIME ON
    
    SELECT ....
    SELECT ....
    
    SET STATISTICS IO OFF
    SET STATISTICS TIME OFF
    

    The output will appear in the messages pane.

    ** Or not–if they all generate the same plan, but actual execution time still varies like you say, something else may be going on–it’s not unheard of. Try comparing actual execution plans and go from there.

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

Sidebar

Related Questions

I have this query: SELECT * FROM sample INNER JOIN test ON sample.sample_number =
I have this query in Mysql SELECT z.virtuemart_product_id,z.product_name,d.product_price FROM x5lui_virtuemart_products x inner join x5lui_virtuemart_products_en_gb
I have this query: SELECT Auctions.ID FROM Auctions INNER JOIN Products ON Auctions.ProductID =
I have this query: SELECT page.id, revision.title, revision.number FROM page INNER JOIN revision ON
I have this query SELECT l.licitatii_id, l.nume, l.data_publicarii, l.data_limita FROM licitatii_ue l INNER JOIN
I have this query: SELECT DISTINCT(b.friend_id) AS possible_id FROM friends_friends a JOIN friends_friends b
I have this query: SELECT p.id, r.status, r.title FROM page AS p INNER JOIN
I have this query: SELECT DISTINCT phone, department FROM `users` WHERE ((SUBSTRING(phone,1,3) = '399')
I have this query SELECT distinct username, time FROM `sadaat`.`wp_loginlog` where username != 'admin'
I have this query: select distinct id,name from table1 For a given ID, the

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.