The problem of SELECT assignment and order by conflict

Source: Internet
Author: User
Tags filter define execution query scalar

Problem Description:
By using the SELECT statement, polling the data in the table, and processing the variable data, if there is an order by statement, the desired result is not obtained, but the order by is removed and the result is normal.
Specific problem performance refer to the following questions to reproduce the code

Problem Recurrence Code
--Test data
DECLARE @T TABLE (id int,value nvarchar (16))
INSERT into @T SELECT
1, N ' Good man ' UNION all SELECT
2, N ' bad guys ' UNION all SELECT
3, N ' eat ' UNION all SELECT
4, N ' rubbish '

--Assigning value processing
DECLARE @str nvarchar (4000)
SET @str = N ' I'm not a good person, not a garbage '
SELECT @str = REPLACE (@str, value, n ' <u> ' + value + N ' </u> ')
From @T
WHERE CHARINDEX (value, @str) > 0
--order by CHARINDEX (value, @str) DESC
SELECT @str

/*-Results (when an assignment-processing statement comments out an ORDER by)
I am not a <u> good person </u> and not <u> garbage </u>
-- */

/*-Results (when an assignment-processing statement adds an order by)
I am not a <u> good person </u>
-- */

Problem Analysis:
The results of two processing statements are different, and by looking at their execution plans, you should see why.
SET Showplan_all on
Outputs two execution plans for executing statements (only the Stmttext section, where interested readers can learn about other parts when testing on their own computers)

Stmttext Step
DECLARE @str nvarchar (4000) SET @str = N ' I'm not a good person, not a garbage '  
SELECT @str = REPLACE (@str, value, n ' <u> ' + value + N ' </u> ') from @T WHERE CHARINDEX (value, @str) > 0 4
|-- Compute Scalar (DEFINE: [Expr1002]=replace ([@str], @t.[value], ' <u> ' +@t.[value]+ ')) 3
|-- Filter (WHERE: (CHARINDEX (@t.[value), [@str], NULL) >0) 2
|-- Table Scan (OBJECT: (@T)) 1
DECLARE @str nvarchar (4000) SET @str = N ' I'm not a good person, not a garbage '  
SELECT @str = REPLACE (@str, value, n ' <u> ' + value + N ' </u> ') from @T WHERE CHARINDEX (value, @str) > 0 O Rder by CHARINDEX (value, @str) DESC 5
|-- Sort (Order BY: ([Expr1003] DESC)) 4
|-- Compute Scalar (DEFINE: [Expr1002]=replace ([@str], @t.[value], ' <u> ' +@t.[value]+ ' </u> '), [expr1003]= CHARINDEX (@t.[value], [@str], NULL)) 3
|-- Filter (WHERE: (CHARINDEX (@t.[value), [@str], NULL) >0) 2
|-- Table Scan (OBJECT: (@T)) 1

when there is an ORDER BY clause, for the Select @str = for this assignment, SQL Server considers that the assignment processing will only retain the processing result of the last record, and the ordered by clause determines the data sequence, You know that the last record is that, so only the last record of the order by is processed. (Readers can test by themselves, adjust the order by sequence to see if the result matches my inference)
when there is no ORDER BY clause, because the data sequence cannot be determined, SQL Server must scan each piece of data that satisfies the condition to get the result. So each scan of a record is processed once, so the result is the
 
Problem resolution that we predicted:
Modify the processing statement so that the query optimizer uses the execution method that is consistent with the results we need to solve the problem.
for the processing statements in the example, you can adjust the following:
DECLARE @str nvarchar (4000)
SET @str = N ' I am not a good person, nor garbage '
SELECT @str = REPLACE (@str, Value, n ' <u> ' + value + N ' </u> ')
from (
    SELECT top PERCENT
         value
    from @T
    WHERE CHARINDEX (value, @str ) > 0
    Order by CHARINDEX (value, @str) DESC
) A
SELECT @str
 
Add:
The conclusion of this question is only The author of the query analysis of a deduction, there is no corresponding official documents can be proved, so you are welcome to express their views



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.