สร้างคำแนะนำแผนเพื่อแคช (ผลการสปูลขี้เกียจ) CTE


19

ปกติแล้วฉันจะสร้างคำแนะนำแผนโดยการสร้างแบบสอบถามที่ใช้แผนที่ถูกต้องและคัดลอกไปยังแบบสอบถามที่คล้ายกันซึ่งไม่ได้ อย่างไรก็ตามบางครั้งก็เป็นเรื่องยากโดยเฉพาะอย่างยิ่งหากแบบสอบถามไม่เหมือนกันทั้งหมด วิธีที่ถูกต้องในการสร้างคำแนะนำแผนคืออะไร?

SQLKiwi ได้กล่าวถึงการร่างแผนใน SSIS มีวิธีหรือเครื่องมือที่มีประโยชน์เพื่อช่วยในการจัดทำแผนดีสำหรับ SQL Server หรือไม่?

ตัวอย่างที่เป็นปัญหาคือ CTE: SQLFiddle

with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;

มีวิธีใดบ้างที่จะทำให้ผลลัพธ์นั้นมี 3 guids ที่แตกต่างกันและไม่มีอีกต่อไป? ฉันหวังว่าจะสามารถตอบคำถามได้ดีขึ้นในอนาคตโดยรวมถึงคำแนะนำแผนกับแบบสอบถามชนิด CTE ที่มีการอ้างอิงหลายครั้งเพื่อเอาชนะปัญหา SQL Server CTE บางข้อ


คำตอบ:


14

มีวิธีใดบ้างที่จะทำให้เกิดผลลัพธ์ที่มี 3 guids ที่แตกต่างกันและไม่มีอีกต่อไป? ฉันหวังว่าจะสามารถตอบคำถามได้ดีขึ้นในอนาคตโดยรวมถึงคำแนะนำแผนกับแบบสอบถามชนิด CTE ที่มีการอ้างอิงหลายครั้งเพื่อเอาชนะปัญหา SQL Server CTE บางข้อ

ไม่ใช่วันนี้. นิพจน์ทั่วไปที่ไม่ใช่แบบเรียกซ้ำ (CTE) จะถูกใช้เป็นคำจำกัดความของมุมมองในบรรทัดและขยายเข้าไปในแผนผังคิวรีแบบโลจิคัลในแต่ละที่ที่ถูกอ้างอิง (เช่นเดียวกับนิยามมุมมองปกติ) ก่อนการปรับ ต้นไม้ตรรกะสำหรับแบบสอบถามของคุณคือ:

LogOp_OrderByCOL: Union1007 ASC COL: Union1015 ASC 
    LogOp_Project COL: Union1006 COL: Union1007 COL: Union1014 COL: Union1015
        LogOp_Join
            LogOp_ViewAnchor
                LogOp_UnionAll
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const

            LogOp_ViewAnchor
                LogOp_UnionAll
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
                    LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const

สังเกตุ View View Anchors สองตัวและการเรียกหกครั้งไปยังฟังก์ชันที่แท้จริงnewidก่อนที่จะเริ่มการปรับให้เหมาะสม อย่างไรก็ตามหลายคนคิดว่าเครื่องมือเพิ่มประสิทธิภาพควรจะสามารถระบุได้ว่าต้นไม้ย่อยที่ขยายออกมานั้นเป็นวัตถุอ้างอิงเดียวและทำให้มันง่ายขึ้น นอกจากนี้ยังมีการร้องขอการเชื่อมต่อหลายครั้งเพื่ออนุญาตการทำให้เป็นรูปธรรมชัดเจนของ CTE หรือตารางที่ได้รับ

การใช้งานทั่วไปที่มากขึ้นจะทำให้เครื่องมือเพิ่มประสิทธิภาพพิจารณา materializing นิพจน์ทั่วไปโดยพลการเพื่อปรับปรุงประสิทธิภาพ ( CASEด้วยแบบสอบถามย่อยเป็นอีกตัวอย่างหนึ่งที่ปัญหาสามารถเกิดขึ้นได้ในวันนี้) Microsoft Research เผยแพร่บทความ (PDF) ในช่วงเวลาดังกล่าวในปี 2550 แม้ว่าจะยังไม่มีการนำมาใช้งานจนถึงปัจจุบัน ในขณะนี้เราถูก จำกัด ให้เป็นรูปธรรมชัดเจนโดยใช้สิ่งต่างๆเช่นตัวแปรตารางและตารางชั่วคราว

SQLKiwi ได้กล่าวถึงการร่างแผนใน SSIS มีวิธีหรือเครื่องมือที่มีประโยชน์เพื่อช่วยในการจัดทำแผนดีสำหรับ SQL Server หรือไม่?

นี่เป็นเพียงความคิดที่ต้องการในส่วนของฉันและไปได้ดีกว่าความคิดในการปรับเปลี่ยนแนวทางการวางแผน ในความเป็นจริงแล้วเป็นไปได้ที่จะเขียนเครื่องมือเพื่อจัดการกับ XML โชว์แผนโดยตรง แต่หากไม่มีเครื่องมือเพิ่มประสิทธิภาพเฉพาะโดยใช้เครื่องมือน่าจะเป็นประสบการณ์ที่น่าหงุดหงิดสำหรับผู้ใช้ (และนักพัฒนานึกถึง)

ในบริบทเฉพาะของคำถามนี้เครื่องมือดังกล่าวจะยังไม่สามารถทำให้เนื้อหา CTE เป็นจริงในแบบที่ผู้บริโภคหลายคนสามารถใช้ (เพื่อป้อนข้อมูลทั้งสองไปยัง cross cross ในกรณีนี้) เครื่องมือเพิ่มประสิทธิภาพและเครื่องมือดำเนินการรองรับผู้ใช้หลายคน แต่เพื่อจุดประสงค์เฉพาะ - ไม่มีสิ่งใดที่สามารถนำไปใช้กับตัวอย่างเฉพาะนี้ได้

ในขณะที่ฉันไม่แน่ใจฉันมีลางสังหรณ์ที่ค่อนข้างแรงที่สามารถติดตาม RelOps ได้ (Nested Loop, Lazy Spool) แม้ว่าแบบสอบถามจะไม่เหมือนกับแผน - ตัวอย่างเช่นถ้าคุณเพิ่ม 4 และ 5 ลงใน CTE มันยังคงใช้แผนเดิมต่อไป (ทดสอบ - ดูเหมือนบน SQL Server 2012 RTM Express)

ที่นี่มีความยืดหยุ่นพอสมควร รูปร่างที่กว้างของแผน XML ถูกใช้เพื่อเป็นแนวทางในการค้นหาแผนขั้นสุดท้าย (แม้ว่าจะมีหลายแอ็ตทริบิวต์ที่ถูกละเว้นอย่างสิ้นเชิงเช่นประเภทการแบ่งพาร์ติชันในการแลกเปลี่ยน) และกฎการค้นหาปกติก็ค่อนข้างผ่อนคลายเช่นกัน ตัวอย่างเช่นการตัดแต่งต้นของทางเลือกโดยพิจารณาจากต้นทุนถูกปิดใช้งานการแนะนำ cross joins อย่างชัดเจนจะได้รับอนุญาตและการดำเนินการสเกลาร์จะถูกละเว้น

มีรายละเอียดมากเกินกว่าจะเจาะลึกได้ แต่การวางตำแหน่งของตัวกรองและคอมพิวเตอร์คำนวณ Scalars ไม่สามารถบังคับได้และภาคแสดงของแบบฟอร์มcolumn = valueจะเป็นแบบทั่วไปดังนั้นแผนการที่มีX = 1หรือX = @Xสามารถนำไปใช้กับแบบสอบถามที่มีX = 502หรือX = @Yหรือความยืดหยุ่นนี้สามารถช่วยในการค้นหาแผนธรรมชาติที่จะบังคับ

ในตัวอย่างที่เฉพาะเจาะจงค่าคงที่ยูเนี่ยนทั้งหมดสามารถนำมาใช้เป็นการสแกนแบบคงที่ได้ตลอดเวลา จำนวนอินพุตไปยัง Union All ไม่สำคัญ


3

ไม่มีวิธี (SQL Server เวอร์ชันจนถึง 2012) เพื่อใช้สปูลเดียวสำหรับ CTE ทั้งสองครั้ง รายละเอียดสามารถพบได้ในคำตอบของ SQLKiwi ด้านล่างเป็นสองวิธีในการทำให้ CTE เป็นจริงขึ้นสองครั้งซึ่งไม่สามารถหลีกเลี่ยงได้สำหรับลักษณะของการสืบค้น ตัวเลือกทั้งสองส่งผลให้นับ guid สุทธิแตกต่างจาก 6

ลิงค์จากความคิดเห็นของ Martin ไปยังเว็บไซต์ Quassnoi ในบล็อกเกี่ยวกับแผนการนำ CTEเป็นแรงบันดาลใจบางส่วนสำหรับคำถามนี้ มันอธิบายวิธีที่จะทำให้เป็นรูปธรรม CTE เพื่อจุดประสงค์ของแบบสอบถามย่อยที่มีความสัมพันธ์กันซึ่งถูกอ้างอิงเพียงครั้งเดียวแม้ว่าความสัมพันธ์สามารถทำให้ประเมินได้หลายครั้ง ไม่ได้ใช้กับแบบสอบถามในคำถาม

ตัวเลือก 1 - คู่มือการวางแผน

จากคำแนะนำจากคำตอบของ SQLKiwi ฉันได้ตัดคำแนะนำไปยังค่าต่ำสุดเปลือยที่จะยังคงทำงานอยู่เช่นConstantScanโหนดเท่านั้นที่แสดงรายการตัวดำเนินการสเกลาร์ 2 ตัวที่สามารถขยายไปยังหมายเลขใด ๆ ได้อย่างเพียงพอ

;with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other
OPTION(USE PLAN
N'<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="11.0.2100.60" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="1" StatementEstRows="1600" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.0444433" StatementText="with cte(guid,other) as (&#xD;&#xA;  select newid(),1 union all&#xD;&#xA;  select newid(),2 union all&#xD;&#xA;  select newid(),3&#xD;&#xA;select a.guid, a.other, b.guid guidb, b.other otherb&#xD;&#xA;from cte a&#xD;&#xA;cross join cte b&#xD;&#xA;order by a.other, b.other;&#xD;&#xA;" StatementType="SELECT" QueryHash="0x43D93EF17C8E55DD" QueryPlanHash="0xF8E3B336792D84" RetrievedFromCache="true">
          <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
          <QueryPlan NonParallelPlanReason="EstimatedDOPIsOne" CachedPlanSize="96" CompileTime="13" CompileCPU="13" CompileMemory="1152">
            <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" />
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="157240" EstimatedPagesCached="1420" EstimatedAvailableDegreeOfParallelism="1" />
            <RelOp AvgRowSize="47" EstimateCPU="0.006688" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1600" LogicalOp="Inner Join" NodeId="0" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="0.0444433">
              <OutputList>
                <ColumnReference Column="Union1163" />
              </OutputList>
              <Warnings NoJoinPredicate="true" />
              <NestedLoops Optimized="false">
                <RelOp AvgRowSize="27" EstimateCPU="0.000432115" EstimateIO="0.0112613" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="40" LogicalOp="Sort" NodeId="1" Parallel="false" PhysicalOp="Sort" EstimatedTotalSubtreeCost="0.0117335">
                  <OutputList>
                    <ColumnReference Column="Union1080" />
                    <ColumnReference Column="Union1081" />
                  </OutputList>
                  <MemoryFractions Input="0" Output="0" />
                  <Sort Distinct="false">
                    <OrderBy>
                      <OrderByColumn Ascending="true">
                        <ColumnReference Column="Union1081" />
                      </OrderByColumn>
                    </OrderBy>
                    <RelOp AvgRowSize="27" EstimateCPU="4.0157E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="40" LogicalOp="Constant Scan" NodeId="2" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.0157E-05">
                      <OutputList>
                        <ColumnReference Column="Union1080" />
                        <ColumnReference Column="Union1081" />
                      </OutputList>
                      <ConstantScan>
                        <Values>
                          <Row>
                            <ScalarOperator ScalarString="newid()">
                              <Intrinsic FunctionName="newid" />
                            </ScalarOperator>
                            <ScalarOperator ScalarString="(1)">
                              <Const ConstValue="(1)" />
                            </ScalarOperator>
                          </Row>
                          <Row>
                            <ScalarOperator ScalarString="newid()">
                              <Intrinsic FunctionName="newid" />
                            </ScalarOperator>
                            <ScalarOperator ScalarString="(2)">
                              <Const ConstValue="(2)" />
                            </ScalarOperator>
                          </Row>
                        </Values>
                      </ConstantScan>
                    </RelOp>
                  </Sort>
                </RelOp>
                <RelOp AvgRowSize="27" EstimateCPU="0.0001074" EstimateIO="0.01" EstimateRebinds="0" EstimateRewinds="39" EstimatedExecutionMode="Row" EstimateRows="40" LogicalOp="Lazy Spool" NodeId="83" Parallel="false" PhysicalOp="Table Spool" EstimatedTotalSubtreeCost="0.0260217">
                  <OutputList>
                    <ColumnReference Column="Union1162" />
                    <ColumnReference Column="Union1163" />
                  </OutputList>
                  <Spool>
                    <RelOp AvgRowSize="27" EstimateCPU="0.000432115" EstimateIO="0.0112613" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="40" LogicalOp="Sort" NodeId="84" Parallel="false" PhysicalOp="Sort" EstimatedTotalSubtreeCost="0.0117335">
                      <OutputList>
                        <ColumnReference Column="Union1162" />
                        <ColumnReference Column="Union1163" />
                      </OutputList>
                      <MemoryFractions Input="0" Output="0" />
                      <Sort Distinct="false">
                        <OrderBy>
                          <OrderByColumn Ascending="true">
                            <ColumnReference Column="Union1163" />
                          </OrderByColumn>
                        </OrderBy>
                        <RelOp AvgRowSize="27" EstimateCPU="4.0157E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="40" LogicalOp="Constant Scan" NodeId="85" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.0157E-05">
                          <OutputList>
                            <ColumnReference Column="Union1162" />
                            <ColumnReference Column="Union1163" />
                          </OutputList>
                          <ConstantScan>
                            <Values>
                              <Row>
                                <ScalarOperator ScalarString="newid()">
                                  <Intrinsic FunctionName="newid" />
                                </ScalarOperator>
                                <ScalarOperator ScalarString="(1)">
                                  <Const ConstValue="(1)" />
                                </ScalarOperator>
                              </Row>
                              <Row>
                                <ScalarOperator ScalarString="newid()">
                                  <Intrinsic FunctionName="newid" />
                                </ScalarOperator>
                                <ScalarOperator ScalarString="(2)">
                                  <Const ConstValue="(2)" />
                                </ScalarOperator>
                              </Row>
                            </Values>
                          </ConstantScan>
                        </RelOp>
                      </Sort>
                    </RelOp>
                  </Spool>
                </RelOp>
              </NestedLoops>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>'
);

ตัวเลือก 2 - การสแกนระยะไกล

ด้วยการเพิ่มค่าใช้จ่ายของแบบสอบถามและการแนะนำการสแกนระยะไกลผลลัพธ์จะปรากฏขึ้น

with cte(guid,other) as (
  select *
  from OPENQUERY([TESTSQL\V2012], '
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3') x)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;

2

คุณไม่สามารถตัดแผนปฏิบัติการ xml ออกจากศูนย์ได้ การสร้างโดยใช้ SSIS เป็นนิยายวิทยาศาสตร์ ใช่มันคือ XML ทั้งหมด แต่มาจากจักรวาลที่แตกต่างกัน เมื่อดูที่บล็อกของพอลในหัวข้อนั้นเขาพูดว่า "ในแบบที่ SSIS อนุญาต ... " ดังนั้นคุณอาจเข้าใจผิด? ฉันไม่คิดว่าเขาจะพูดว่า "ใช้ SSIS เพื่อสร้างแผน" แต่ "จะไม่เป็นการดีหากคุณสามารถสร้างแผนโดยใช้ส่วนติดต่อแบบลากและวางเช่น SSIS" บางทีสำหรับคำถามง่ายๆคุณอาจจัดการเรื่องนี้ได้ แต่มันอาจจะยืดยาวก็ได้ งานยุ่งที่คุณอาจพูด

ถ้าฉันสร้างแผนสำหรับคำแนะนำการใช้แผนหรือคู่มือแผนฉันมีสองวิธี ตัวอย่างเช่นฉันอาจลบระเบียนออกจากตาราง (เช่นในสำเนาของ db) เพื่อมีอิทธิพลต่อสถิติและสนับสนุนให้เครื่องมือเพิ่มประสิทธิภาพในการตัดสินใจที่แตกต่างกัน ฉันยังใช้ตัวแปรตารางแทนทุกตารางในแบบสอบถามดังนั้นเครื่องมือเพิ่มประสิทธิภาพคิดว่าทุกตารางมี 1 บันทึก จากนั้นในแผนที่สร้างขึ้นให้แทนที่ตัวแปรตารางทั้งหมดด้วยชื่อตารางดั้งเดิมและสลับเป็นแผน อีกตัวเลือกหนึ่งคือการใช้ตัวเลือก WITH STATS_STREAM ของ UPDATE STATISTICS เพื่อหลอกข้อมูลสถิติซึ่งเป็นวิธีการที่ใช้ในการโคลนสำเนาเฉพาะฐานข้อมูลสถิติเช่น

UPDATE STATISTICS 
    [dbo].[yourTable]([PK_yourTable]) 
WITH 
    STATS_STREAM = 0x0100etc, 
    ROWCOUNT = 10000, 
    PAGECOUNT = 93

ฉันใช้เวลาในการจัดการกับแผนการดำเนินการ xml ในอดีตและฉันได้พบว่าในที่สุด SQL ก็ไป "ฉันไม่ได้ใช้" และเรียกใช้แบบสอบถามว่ามันต้องการอยู่แล้ว

สำหรับตัวอย่างเฉพาะของคุณฉันแน่ใจว่าคุณรู้ว่าคุณสามารถใช้ set rowcount 3 หรือ TOP 3 ในแบบสอบถามเพื่อรับผลลัพธ์นั้น แต่ฉันเดาว่าไม่ใช่จุดของคุณ ที่ถูกต้องคำตอบจริงๆจะเป็น: ใช้ตาราง temp ฉันจะ upvote ว่า) ไม่ได้คำตอบที่ถูกต้องก็จะเป็น "ชั่วโมงการใช้จ่ายวันแม้ตัดแผนปฏิบัติการ XML ของคุณเองที่คุณพยายามที่จะหลอกลวง Optimzer เข้าไปทำหลอดขี้เกียจสำหรับ CTE ซึ่งอาจไม่ได้ทำงานอยู่แล้วจะดูฉลาดแต่จะเป็นไปไม่ได้ที่จะรักษา "

ไม่ใช่ความคิดที่ไม่สร้างสรรค์เพียงความคิดของฉัน - หวังว่าจะช่วยได้


อย่างจริงจังแผนการ XML เป็นจุดอ่อน?! ฉันคิดว่านั่นคือจุดทั้งหมดหรือไม่ หากพวกเขาไม่ถูกต้องก็ควรโยน
crokusek

ฉันอ้างถึงเหตุการณ์แผนไม่สำเร็จ
wBob

2

มีวิธีใดบ้าง ...

ในที่สุดใน SQL 2016 CTP 3.0 มีวิธีชนิด:)

การใช้การตั้งค่าสถานะการสืบค้นกลับและเหตุการณ์เพิ่มเติมตามรายละเอียดโดย Dmitry Pilugin ที่นี่คุณสามารถ (โดยพลการค่อนข้าง) ออกปลาสาม guids ที่ไม่ซ้ำกันจากขั้นตอนกลางของการดำเนินการแบบสอบถาม

NB รหัสนี้ไม่ได้มีไว้สำหรับการผลิตหรือการใช้งานอย่างจริงจังในแง่ของการบังคับใช้แผน CTE เพียงดูเบา ๆ ในการติดตามสถานะใหม่และวิธีการทำสิ่งต่าง ๆ :

-- Configure the XEvents session; with ring buffer target so we can collect it
CREATE EVENT SESSION [query_trace_column_values] ON SERVER 
ADD EVENT sqlserver.query_trace_column_values
ADD TARGET package0.ring_buffer( SET max_memory = 2048 )
WITH ( MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY = 30 SECONDS, MAX_EVENT_SIZE = 0 KB, MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF , STARTUP_STATE = OFF )
GO

-- Start the session
ALTER EVENT SESSION [query_trace_column_values] ON SERVER
STATE = START;
GO

-- Run the query, including traceflag
DBCC TRACEON(2486);
SET STATISTICS XML ON;
GO

-- Original query
;with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other
option ( recompile )
go

SET STATISTICS XML OFF;
DBCC TRACEOFF(2486);
GO

DECLARE @target_data XML

SELECT @target_data = CAST( target_data AS XML )
FROM sys.dm_xe_sessions AS s 
    INNER JOIN sys.dm_xe_session_targets AS t ON t.event_session_address = s.address
WHERE s.name = 'query_trace_column_values'


--SELECT @target_data td

-- Arbitrarily fish out 3 unique guids from intermediate stage of the query as collected by XEvent session
;WITH cte AS
(
SELECT
    n.c.value('(data[@name = "row_id"]/value/text())[1]', 'int') row_id,
    n.c.value('(data[@name = "column_value"]/value/text())[1]', 'char(36)') [guid]
FROM @target_data.nodes('//event[data[@name="column_id"]/value[. = 1]][data[@name="row_number"]/value[. < 4]][data[@name="node_name"]/value[. = "Nested Loops"]]') n(c)
)
SELECT *
FROM cte a
    CROSS JOIN cte b
GO

-- Stop the session
ALTER EVENT SESSION [query_trace_column_values] ON SERVER
STATE = STOP;
GO

-- Drop the session
IF EXISTS ( select * from sys.server_event_sessions where name = 'query_trace_column_values' )
DROP EVENT SESSION [query_trace_column_values] ON SERVER 
GO

ทดสอบกับเวอร์ชั่น (CTP3.2) - 13.0.900.73 (x64) เพื่อความสนุกสนาน


1

ฉันพบ traceflag 8649 (บังคับให้ใช้แผนขนาน) ทำให้เกิดพฤติกรรมนี้สำหรับคอลัมน์ guid ทางซ้ายในอินสแตนซ์ 2008, R2 และ 2012 ของฉัน ฉันไม่จำเป็นต้องใช้การตั้งค่าสถานะบน SQL 2005 ที่ CTE ทำงานอย่างถูกต้อง ฉันพยายามใช้แผนที่สร้างขึ้นใน SQL 2005 ในอินสแตนซ์ที่สูงขึ้น แต่มันจะไม่ตรวจสอบ

with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other
option ( querytraceon 8649 )

ไม่ว่าจะเป็นการใช้คำใบ้การใช้คำแนะนำแผนรวมถึงคำใบ้หรือการใช้แผนที่สร้างโดยการสืบค้นพร้อมคำใบ้ในการวางแผนการใช้งานและอื่น ๆ ทั้งหมดทำงานได้ดี cte newid


ขอขอบคุณที่ลองอีกครั้ง การสืบค้นไม่ได้ดูแตกต่างไปจากการมีหรือไม่มีการตั้งค่าสถานะการติดตามนั้นใน 2008/2012 ไม่แน่ใจจริงๆว่าเป็นอินสแตนซ์ SQL Server ของฉันหรือสิ่งที่คุณพยายามแสดง ฉันยังเห็น 18 guids คุณเห็นอะไร?
孔夫子

3 guids ที่แตกต่างกันทางด้านซ้าย (คอลัมน์ guid) แต่ละครั้งทำซ้ำสามครั้ง 9 guids ที่ไม่ซ้ำกันทางด้านขวา (คอลัมน์ guidb) ดังนั้นอย่างน้อยบิตทางซ้ายก็ทำตัวตามที่คุณต้องการ lol ฉันได้เพิ่มภาพไปยังคำตอบอื่น ๆ เพื่อหวังว่าจะชี้แจงเล็กน้อย ก้าวเล็ก ๆ ฉันควรทราบใน SQL 2005 ด้วยฉันจะได้ 6 guids ที่ไม่ซ้ำใคร 3 ทางซ้าย 3 ทางขวา
wBob

เพิ่งสังเกตว่าการลบ 'ทั้งหมด' จะได้รับ 6 guids ที่ไม่ซ้ำกันด้วย 3 แต่ละด้าน
wBob

สามารถทำให้ traceflag ไม่ทำงานโดยให้ maxdop ของเซิร์ฟเวอร์ 1
wBob
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.