เหตุใดข้อความค้นหา EXISTS ของฉันจึงทำการสแกนดัชนีแทนที่จะค้นหาดัชนี


15

ฉันกำลังปรับปรุงการค้นหาให้ดีที่สุด

สำหรับแบบสอบถามด้านล่าง

SET STATISTICS IO ON;
DECLARE @OrderStartDate DATETIME2 = '27 feb 2016';
DECLARE @OrderEndDate  DATETIME2 = '28 feb 2016';

SELECT  o.strBxOrderNo
        , o.sintOrderStatusID
        , o.sintOrderChannelID
        , o.sintOrderTypeID
        , o.sdtmOrdCreated
        , o.sintMarketID
        , o.strOrderKey
        , o.strOfferCode
        , o.strCurrencyCode
        , o.decBCShipFullPrice
        , o.decBCShipFinal
        , o.decBCShipTax
        , o.decBCTotalAmount
        , o.decWrittenTotalAmount
        , o.decBCWrittenTotalAmount
        , o.decBCShipOfferDisc
        , o.decBCShipOverride
        , o.decTotalAmount
        , o.decShipTax
        , o.decShipFinal
        , o.decShipOverride
        , o.decShipOfferDisc
        , o.decShipFullPrice
        , o.lngAccountParticipantID
        , CONVERT(DATE, o.sdtmOrdCreated, 120) as OrderCreatedDateConverted
FROM    tablebackups.dbo.tblBOrder o
WHERE   o.sdtmOrdCreated >= @OrderStartDate
        AND o.sdtmOrdCreated < @OrderEndDate
        AND EXISTS  (
            SELECT  *
            FROM    tablebackups.dbo.tblBOrderItem oi 
            WHERE   oi.strBxOrderNo = o.strBxOrderNo
            AND     oi.decCatItemPrice > 0
        )
OPTION (RECOMPILE);

ฉันได้สร้างดัชนีตัวกรองต่อไปนี้:

-- table dbo.tblBorderItem
CREATE NONCLUSTERED INDEX IX_tblBOrderItem_decCatItemPrice_INCL 
ON dbo.tblBorderItem 
( 
     strBxOrderNo ASC
    , sintOrderSeqNo ASC
    , decCatItemPrice   
)   
INCLUDE 
(
    blnChargeShipping
    , decBCCatItemPrice
    , decBCCostPrice
    , decBCFinalPrice
    , decBCOfferDiscount
    , decBCOverrideDiscount
    , decBCTaxAmount
    , decCostPrice
    , decFinalPrice
    , decOfferDiscount
    , decOverrideDiscount
    , decTaxAmount
    , decWasPrice
    , dtmOrdItemCreated
    , sintOrderItemStatusId
    , sintOrderItemType
    , sintQuantity
    , strItemNo
)  
WHERE decCatItemPrice > 0 
WITH (DROP_EXISTING = ON, FILLFACTOR = 95);

ดัชนีนี้ไม่ได้ใช้เฉพาะกับแบบสอบถามนี้โดยเฉพาะมีแบบสอบถามอื่น ๆ ที่ใช้ดัชนีเดียวกันนี้ดังนั้นคอลัมน์ INCLUDED

สำหรับการค้นหานี้โดยเฉพาะอย่างยิ่งผมแค่อยากจะตรวจสอบ (มี) หากมีการสั่งซื้อมีรายการใด ๆ decCatItemPrice > 0ที่

SQL Server กำลังทำการสแกนดัชนีตามที่คุณเห็นในภาพด้านล่าง

  • สถิติเพิ่งได้รับการอัพเดต
  • ตารางรายการมีการทดสอบ 41,208 แถว

โปรดทราบว่าฉันไม่ได้เลือกคอลัมน์ใด ๆ จากตารางรายการ

ตารางรายการนี้มี 164,309,397 รายการสด ฉันต้องการหลีกเลี่ยงการสแกนที่นั่น

คำถาม:

ทำไม SQL Server ไม่ค้นหาดัชนี?

มีปัจจัย / สิ่งอื่น ๆ ที่ฉันควรพิจารณาเพื่อปรับปรุงแบบสอบถามนี้หรือไม่

(4537 row(s) affected) Table 'tblBorder'. Scan count 1, logical reads
116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob
physical reads 0, lob read-ahead reads 0. Table 'tblBorderItem'. Scan
count 1, logical reads 689, physical reads 0, read-ahead reads 0, lob
logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

นี่คือคำจำกัดความและดัชนีบนตารางtblBorderItem

    IF OBJECT_ID('[dbo].[tblBorderItem]') IS NOT NULL 
    DROP TABLE [dbo].[tblBorderItem] 
    GO
    CREATE TABLE [dbo].[tblBorderItem] ( 
    [strBxOrderNo]                VARCHAR(20)                      NOT NULL,
    [sintOrderSeqNo]              SMALLINT                         NOT NULL,
    [sintOrderItemStatusId]       SMALLINT                         NOT NULL,
    [sintNameStructureID]         SMALLINT                         NOT NULL,
    [strItemNo]                   VARCHAR(20)                      NOT NULL,
    [sintQuantity]                SMALLINT                         NOT NULL,
    [strCurrencyCode]             VARCHAR(3)                       NOT NULL,
    [decCostPrice]                DECIMAL(18,4)                    NOT NULL,
    [decCatItemPrice]             DECIMAL(18,2)                    NOT NULL,
    [decOfferDiscount]            DECIMAL(18,2)                    NOT NULL,
    [decOverrideDiscount]         DECIMAL(18,2)                    NOT NULL,
    [decFinalPrice]               DECIMAL(18,2)                    NOT NULL,
    [decTaxAmount]                DECIMAL(18,2)                    NOT NULL,
    [strBCCurrencyCode]           VARCHAR(3)                       NOT NULL,
    [decBCCostPrice]              DECIMAL(18,4)                    NOT NULL,
    [decBCCatItemPrice]           DECIMAL(18,4)                    NOT NULL,
    [decBCOfferDiscount]          DECIMAL(18,4)                    NOT NULL,
    [decBCOverrideDiscount]       DECIMAL(18,4)                    NOT NULL,
    [decBCFinalPrice]             DECIMAL(18,4)                    NOT NULL,
    [decBCTaxAmount]              DECIMAL(18,4)                    NOT NULL,
    [dtmOrdItemCreated]           DATETIME                         NOT NULL,
    [blnChargeShipping]           BIT                              NOT NULL,
    [lngTimeOfOrderQtyOnHand]     INT                                  NULL,
    [sdtmTimeOfOrderDueDate]      SMALLDATETIME                        NULL,
    [lngProdSetSeqNo]             INT                                  NULL,
    [lngProdRelationId]           INT                                  NULL,
    [lngProdRelationMemberId]     INT                                  NULL,
    [decWasPrice]                 DECIMAL(18,2)                        NULL,
    [sintOrderItemType]           SMALLINT                             NULL,
    [tsRowVersion]                TIMESTAMP                            NULL,
    [sdtmOrderItemStatusUpdated]  SMALLDATETIME                        NULL,
    CONSTRAINT   [PK_tblBOrderItem]  
PRIMARY KEY CLUSTERED    
([strBxOrderNo] asc, [sintOrderSeqNo] asc) 
WITH FILLFACTOR = 100)

    GO

    CREATE NONCLUSTERED INDEX 
    [IX_tblBOrderItem__dtmOrdItemCreated] 
       ON [dbo].[tblBorderItem] ([dtmOrdItemCreated] asc)
       WITH FILLFACTOR = 100


    CREATE NONCLUSTERED INDEX [IX_tblBOrderItem__sintOrderItemStatusId] 
       ON [dbo].[tblBorderItem] ([sintOrderItemStatusId] asc)
       INCLUDE ([sdtmOrderItemStatusUpdated], 
    [sintOrderSeqNo], [strBxOrderNo], [strItemNo])
       WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX [IX_tblBOrderItem__
sintOrderItemStatusId_decFinalPrice_
sdtmOrderItemStatusUpdated_
include_strBxOrderNo] 
   ON [dbo].[tblBorderItem] 
([sintOrderItemStatusId] asc, 
 [decFinalPrice] asc, 
 [sdtmOrderItemStatusUpdated] asc)
   INCLUDE ([strBxOrderNo])
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX [IX_tblBOrderItem__strBxOrderNo] 
   ON [dbo].[tblBorderItem] 
([strBxOrderNo] asc)
   WITH FILLFACTOR = 100


CREATE NONCLUSTERED INDEX [IX_tblBOrderItem__strItemNo] 
   ON [dbo].[tblBorderItem] ([strItemNo] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrderItem_decCatItemPrice_INCL] 
   ON [dbo].[tblBorderItem] 
([strBxOrderNo] asc, [sintOrderSeqNo] asc, [decCatItemPrice] asc)
   INCLUDE ([blnChargeShipping], 
[decBCCatItemPrice], [decBCCostPrice], [decBCFinalPrice], 
[decBCOfferDiscount], [decBCOverrideDiscount], 
[decBCTaxAmount], [decCostPrice], [decFinalPrice], 
[decOfferDiscount], [decOverrideDiscount], 
[decTaxAmount], [decWasPrice], [dtmOrdItemCreated], 
[sintOrderItemStatusId], [sintOrderItemType], 
[sintQuantity], [strItemNo])
   WHERE ([decCatItemPrice]>(0))
   WITH FILLFACTOR = 95

นี่คือคำจำกัดความและดัชนีบนตารางtblBorder

IF OBJECT_ID('[dbo].[tblBorder]') IS NOT NULL 
DROP TABLE [dbo].[tblBorder] 
GO
CREATE TABLE [dbo].[tblBorder] ( 
[strBxOrderNo]                VARCHAR(20)                      NOT NULL,
[uidOrderUniqueID]            UNIQUEIDENTIFIER                 NOT NULL,
[sintOrderStatusID]           SMALLINT                         NOT NULL,
[sintOrderChannelID]          SMALLINT                         NOT NULL,
[sintOrderTypeID]             SMALLINT                         NOT NULL,
[blnIsBasket]                 BIT                              NOT NULL,
[sdtmOrdCreated]              SMALLDATETIME                    NOT NULL,
[sintMarketID]                SMALLINT                         NOT NULL,
[strOrderKey]                 VARCHAR(20)                      NOT NULL,
[strOfferCode]                VARCHAR(20)                      NOT NULL,
[lngShippedToParticipantID]   INT                              NOT NULL,
[lngOrderedByParticipantID]   INT                              NOT NULL,
[lngShipToAddressID]          INT                              NOT NULL,
[lngAccountAddressID]         INT                              NOT NULL,
[lngAccountParticipantID]     INT                              NOT NULL,
[lngOrderedByAddressID]       INT                              NOT NULL,
[lngOrderTakenBy]             INT                              NOT NULL,
[strCurrencyCode]             VARCHAR(3)                       NOT NULL,
[decShipFullPrice]            DECIMAL(18,2)                    NOT NULL,
[decShipOfferDisc]            DECIMAL(18,2)                    NOT NULL,
[decShipOverride]             DECIMAL(18,2)                    NOT NULL,
[decShipFinal]                DECIMAL(18,2)                    NOT NULL,
[decShipTax]                  DECIMAL(18,2)                    NOT NULL,
[strBCCurrencyCode]           VARCHAR(3)                       NOT NULL,
[decBCShipFullPrice]          DECIMAL(18,4)                    NOT NULL,
[decBCShipOfferDisc]          DECIMAL(18,4)                    NOT NULL,
[decBCShipOverride]           DECIMAL(18,4)                    NOT NULL,
[decBCShipFinal]              DECIMAL(18,4)                    NOT NULL,
[decBCShipTax]                DECIMAL(18,4)                    NOT NULL,
[decTotalAmount]              DECIMAL(18,2)                    NOT NULL,
[decBCTotalAmount]            DECIMAL(18,4)                    NOT NULL,
[decWrittenTotalAmount]       DECIMAL(18,2)                        NULL,
[decBCWrittenTotalAmount]     DECIMAL(18,4)                        NULL,
[blnProRataShipping]          BIT                              NOT NULL,
[blnChargeWithFirstShipment]  BIT                              NOT NULL,
[sintShippingServiceLevelID]  SMALLINT                         NOT NULL,
[sintShippingMethodID]        SMALLINT                         NOT NULL,
[sdtmDoNotShipUntil]          SMALLDATETIME                        NULL,
[blnHoldUntilComplete]        BIT                              NOT NULL,
[tsRowVersion]                TIMESTAMP                            NULL,
CONSTRAINT   [PK_tblBOrder]  
PRIMARY KEY CLUSTERED    
([strBxOrderNo] asc) WITH FILLFACTOR = 100)

GO

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngAccountAddressID] 
   ON [dbo].[tblBorder] 
   ([lngAccountAddressID] asc, [sintOrderStatusID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngAccountParticipantID] 
   ON [dbo].[tblBorder] 
   ([lngAccountParticipantID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngOrderedByAddressID] 
   ON [dbo].[tblBorder] 
   ([lngOrderedByAddressID] asc, [sintOrderStatusID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngOrderedByParticipantID] 
   ON [dbo].[tblBorder] ([lngOrderedByParticipantID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngShippedToParticipantID] 
   ON [dbo].[tblBorder] 
   ([lngShippedToParticipantID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__lngShipToAddressID] 
   ON [dbo].[tblBorder] 
   ([lngShipToAddressID] asc, [sintOrderStatusID] asc)
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder__sdtmOrdCreated_sintMarketID__include_strBxOrderNo] 
   ON [dbo].[tblBorder] 
   ([sdtmOrdCreated] asc, [sintMarketID] asc)
   INCLUDE ([strBxOrderNo])
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX 
[IX_tblBOrder_sdtmOrdCreated_INCL] 
   ON [dbo].[tblBorder] 
   ([sdtmOrdCreated] asc)
   INCLUDE ([decBCShipFinal], [decBCShipFullPrice], 
            [decBCShipOfferDisc], [decBCShipOverride], 
            [decBCShipTax], [decBCTotalAmount], [decBCWrittenTotalAmount], 
            [decShipFinal], [decShipFullPrice], [decShipOfferDisc], 
            [decShipOverride], [decShipTax], [decTotalAmount], 
            [decWrittenTotalAmount], [lngAccountParticipantID], 
            [lngOrderedByParticipantID], [sintMarketID], 
            [sintOrderChannelID], [sintOrderStatusID], 
            [sintOrderTypeID], [strBxOrderNo], [strCurrencyCode], 
            [strOfferCode], [strOrderKey])
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED 
INDEX [IX_tblBOrder_sintMarketID_sdtmOrdCreated] 
   ON [dbo].[tblBorder] 
   ([sintMarketID] asc, [sdtmOrdCreated] asc)
   INCLUDE ([sintOrderChannelID], [strBxOrderNo])
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED 
INDEX [IX_tblBOrder__sintOrderChannelID_sdtmOrdCreated_INCL] 
   ON [dbo].[tblBorder] 
   ([sintOrderChannelID] asc, [sdtmOrdCreated] asc)
   INCLUDE ([decBCShipFinal], [decBCShipFullPrice], 
   [decBCShipTax], [decShipFinal], [decShipFullPrice], 
   [decShipTax], [lngAccountParticipantID], [sintMarketID], 
   [sintOrderTypeID], [strBxOrderNo], 
   [strCurrencyCode], [strOrderKey])
   WITH FILLFACTOR = 100

CREATE NONCLUSTERED INDEX [IX_tblBOrder_strBxOrderNo_sdtmOrdCreated_incl] 
   ON [dbo].[tblBorder] ([strBxOrderNo] asc, 
   [sdtmOrdCreated] asc)
   INCLUDE ([sintOrderChannelID], [sintOrderTypeID], [sintMarketID], 
   [strOrderKey], [lngAccountParticipantID], [strCurrencyCode], 
   [decShipFullPrice], [decShipFinal], [decShipTax], 
   [decBCShipFullPrice], [decBCShipFinal], 
   [decBCShipTax])

ข้อสรุป

ฉันใช้ดัชนีของฉันในระบบสดและอัปเดตกระบวนงานที่เก็บไว้ของฉันเพื่อใช้ SMALLDATETIME เพื่อให้ตรงกับประเภทข้อมูลในฐานข้อมูลสำหรับคอลัมน์ที่เกี่ยวข้อง

หลังจากนั้นเมื่อดูแผนแบบสอบถามฉันเห็นภาพด้านล่าง:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

มันเป็นสิ่งที่ฉันต้องการอย่างแท้จริง

ฉันคิดว่าเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาในกรณีนี้ทำงานได้ดีเพื่อให้ได้แผนการสืบค้นที่ดีที่สุดในทั้งสองสภาพแวดล้อมและฉันดีใจที่ฉันไม่ได้เพิ่มคำแนะนำการสืบค้นใด ๆ

ฉันเรียนรู้ด้วย 3 คำตอบที่โพสต์ ขอบคุณMax Vernon , Paul WhiteและDaniel Hutmacherสำหรับคำตอบของพวกเขา

คำตอบ:


15

หากคุณต้องการผลดีจากการเพิ่มประสิทธิภาพการค้นหาที่จะจ่ายให้ระมัดระวังเกี่ยวกับชนิดข้อมูล

ตัวแปรของคุณถูกพิมพ์เป็นdatetime2 :

DECLARE @OrderStartDate datetime2 = '27 feb 2016';
DECLARE @OrderEndDate  datetime2 = '28 feb 2016';

แต่คอลัมน์เหล่านี้ถูกเปรียบเทียบกับพิมพ์smalldatetime (ตามคำนำหน้าsdtmแนะนำ!):

[sdtmOrdCreated] SMALLDATETIME NOT NULL

ความเข้ากันไม่ได้ของประเภททำให้ยากสำหรับเครื่องมือเพิ่มประสิทธิภาพในการประมาณค่า cardinality ผ่านการแปลงประเภทดังที่แสดงในแผนการดำเนินการ xml:

<ScalarOperator ScalarString="GetRangeWithMismatchedTypes([@OrderStartDate],NULL,(22))">
<ScalarOperator ScalarString="GetRangeWithMismatchedTypes(NULL,[@OrderEndDate],(10))">

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

DECLARE @OrderStartDate smalldatetime = CONVERT(smalldatetime, '20160227', 112);
DECLARE @OrderEndDate smalldatetime = CONVERT(smalldatetime, '20160228', 112);

ตรวจสอบความถูกต้องของการประมาณการเชิงหัวใจเสมอและเหตุผลของความคลาดเคลื่อนใด ๆก่อนที่จะตัดสินใจเขียนแบบสอบถามหรือใช้คำแนะนำ

ดูบทความ SQLblog.com ของฉัน"Dynamic Seeks และ Hidden Implicit Conversion"สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการค้นหาแบบไดนามิก

อัปเดต: การแก้ไขชนิดข้อมูลทำให้คุณมีแผนค้นหาตามที่คุณต้องการ ข้อผิดพลาดการประเมินความผิดพลาดที่เกิดจากการแปลงประเภทก่อนที่จะให้แผนช้าลง


11

SQL Server ทำการสแกนดัชนีเนื่องจากคิดว่าราคาถูกกว่าการค้นหาแต่ละแถวที่ต้องการ เป็นไปได้มากว่า SQL Server นั้นถูกต้องเนื่องจากมีตัวเลือกในการตั้งค่าของคุณ

ระวัง SQL Server จริง ๆ แล้วอาจทำการสแกนช่วงในดัชนีเมื่อเทียบกับการสแกนดัชนีทั้งหมด

หากคุณให้ DDL สำหรับทั้งสองตารางพร้อมกับดัชนีอื่น ๆ ที่คุณอาจมีเราอาจช่วยให้คุณใช้ทรัพยากรน้อยลงมาก

ในฐานะที่เป็นข้อความด้านข้างไม่เคยใช้ตัวอักษรวันที่เช่นนั้น แทน:

DECLARE @OrderStartDate DATETIME2 = '27 feb 2016';
DECLARE @OrderEndDate  DATETIME2 = '28 feb 2016';

ใช้สิ่งนี้:

DECLARE @OrderStartDate DATETIME2 = '2016-02-27T00:00:00.0000';
DECLARE @OrderEndDate  DATETIME2 = '2016-02-28T00:00:00.0000';

โพสต์ของแอรอนอาจช่วยชี้แจงได้ว่า


6

หากต้องการเพิ่มคำตอบของ Max ฉันอาจลองแยกแบบสอบถามของคุณออกเป็นสองส่วน:

DECLARE @OrderStartDate DATETIME2 = {d '2016-02-27'};
DECLARE @OrderEndDate   DATETIME2 = {d '2016-02-28'};

--- Work variable declarations:
DECLARE @minOrderNo varchar(20), @maxOrderNo varchar(20);

--- Find the lowest and highest order number respectively for
--- your date range:
SELECT @minOrderNo=MIN(strBxOrderNo),
       @maxOrderNo=MAX(strBxOrderNo)
FROM    dbo.tblBOrder o
WHERE   o.sdtmOrdCreated >= @OrderStartDate AND
        o.sdtmOrdCreated <  @OrderEndDate;

--- Join orders and order items on their respective clustering keys.
SELECT    o.strBxOrderNo
        , o.sintOrderStatusID
        , o.sintOrderChannelID
        , o.sintOrderTypeID
        , o.sdtmOrdCreated
        , o.sintMarketID
        , o.strOrderKey
        , o.strOfferCode
        , o.strCurrencyCode
        , o.decBCShipFullPrice
        , o.decBCShipFinal
        , o.decBCShipTax
        , o.decBCTotalAmount
        , o.decWrittenTotalAmount
        , o.decBCWrittenTotalAmount
        , o.decBCShipOfferDisc
        , o.decBCShipOverride
        , o.decTotalAmount
        , o.decShipTax
        , o.decShipFinal
        , o.decShipOverride
        , o.decShipOfferDisc
        , o.decShipFullPrice
        , o.lngAccountParticipantID
        , CONVERT(DATE, o.sdtmOrdCreated, 120) as OrderCreatedDateConverted
FROM dbo.tblBOrder AS o
INNER /*MERGE*/ JOIN dbo.tblBOrderItem AS oi ON
    o.strBxOrderNo>=@minOrderNo AND      --- OrderNo filter on "orders"
    o.strBxOrderNo<=@maxOrderNo AND
    oi.strBxOrderNo=o.strBxOrderNo AND   --- Equijoin
    oi.strBxOrderNo>=@minOrderNo AND     --- OrderNo filter on "order items"
    oi.strBxOrderNo<=@maxOrderNo AND
    oi.decCatItemPrice > 0               --- Item price filter on "order items"
OPTION (RECOMPILE);

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

ทั้งหมดแบบสอบถาม MIN / MAX ใช้ดัชนีที่เหมาะสมที่สุดในตารางคำสั่งซื้อเพื่อระบุช่วงของหมายเลขคำสั่งซื้อ (รวมอยู่ในคีย์การทำคลัสเตอร์) จากดัชนีที่ไม่ได้ทำคลัสเตอร์ในคอลัมน์วันที่:

แผนแบบสอบถาม MIN / MAX

จากนั้นคุณสามารถผสานเข้าร่วมสองตารางในดัชนีกลุ่มที่เกี่ยวข้อง:

ผสานเข้าร่วมคำสั่งซื้อและรายการสั่งซื้อ

เห็นได้ชัดว่าฉันไม่ได้มีข้อมูลของคุณเพื่อทดสอบด้วย แต่ฉันคิดว่านี่จะเป็นทางออกที่มีประสิทธิภาพดีจริงๆ


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