Does SQL Server jump leaves when using a composite clustered index?

后端 未结 2 1572
挽巷
挽巷 2021-01-20 04:14

Consider the following composite clustered index:

CREATE UNIQUE CLUSTERED INDEX ix_mytable ON mytable(a, b)

Obviously, a separate index on

相关标签:
2条回答
  • 2021-01-20 05:12
    USE AdventureWorks2008R2;
    -- Source: http://msftdbprodsamples.codeplex.com/releases/view/59211
    GO
    
    SET NOCOUNT ON;
    GO
    
    CREATE NONCLUSTERED INDEX IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
    ON [Sales].[SalesOrderHeader] ([OrderDate])
    INCLUDE (ShipDate,SubTotal)
    -- WITH(DROP_EXISTING=ON);
    GO
    
    -- Test 1
    SET STATISTICS IO ON;
    SELECT  COUNT(*)
    FROM    Sales.SalesOrderHeader h -- Index Seek on IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
    WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
    SET STATISTICS IO OFF;
    GO
    -- End of Test 1
    -- Results:
    -- Table 'SalesOrderHeader'. Scan count 1, logical reads 5, physical reads 0
    
    DROP INDEX IX_SalesOrderHeader_OrderDate_#_ShipDate_SubTotal
    ON [Sales].[SalesOrderHeader]
    GO
    CREATE NONCLUSTERED INDEX [IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal] 
    ON Sales.SalesOrderHeader 
    (
        ShipMethodID ASC,
        OrderDate ASC
    )
    INCLUDE (ShipDate,SubTotal);
    GO
    
    -- Test 2
    SET STATISTICS IO ON;
    SELECT  COUNT(*)
    FROM    Sales.SalesOrderHeader h -- Index Scan on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
    WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
    SET STATISTICS IO OFF;
    GO
    -- End of Test 2
    -- Results:
    -- Table 'SalesOrderHeader'. Scan count 1, logical reads 150, physical reads 0
    
    -- Test 3
    SET STATISTICS IO ON;
    SELECT  COUNT(*)
    FROM    Purchasing.ShipMethod sm
    INNER JOIN Sales.SalesOrderHeader h ON h.ShipMethodID=sm.ShipMethodID -- FK elimination + Index Scan on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
    WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
    SET STATISTICS IO OFF;
    GO
    -- End of Test 3
    -- Results:
    -- Table 'SalesOrderHeader'. Scan count 1, logical reads 150, physical reads 0
    
    -- Test 4
    SET STATISTICS IO ON;
    SELECT  MIN(sm.ShipMethodID) AS DummnyCol, -- To prevent FK elimination 
            COUNT(*)
    FROM    Purchasing.ShipMethod sm
    INNER JOIN Sales.SalesOrderHeader h ON h.ShipMethodID=sm.ShipMethodID -- Index Seek on IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal
    WHERE   h.OrderDate BETWEEN '2008-07-01T00:00:00.000' AND '2008-07-15T23:59:59.997';
    SET STATISTICS IO OFF;
    GO
    -- End of Test 4
    -- Results:
    -- Table 'SalesOrderHeader'. Scan count 5, logical reads 13, physical reads 0
    -- Table 'ShipMethod'. Scan count 1, logical reads 2, physical reads 0
    
    DROP INDEX [IX_SalesOrderHeader_ShipMethodID_OrderDate_#_ShipDate_SubTotal] 
    ON Sales.SalesOrderHeader;
    GO
    SET NOCOUNT OFF;
    GO
    
    0 讨论(0)
  • 2021-01-20 05:19

    No, there is no jumping over a clusters of 'a'. An index can be used only if the leftmost column is specified, otherwise a full scan needs to be employed.

    Oracle has the so called 'Index Skip Scan' operator.

    0 讨论(0)
提交回复
热议问题