首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当使用复合聚集索引时,Server跳转是否会离开?

当使用复合聚集索引时,Server跳转是否会离开?
EN

Stack Overflow用户
提问于 2009-10-23 21:05:46
回答 2查看 1.8K关注 0票数 4

考虑以下复合聚集索引:

代码语言:javascript
运行
复制
CREATE UNIQUE CLUSTERED INDEX ix_mytable ON mytable(a, b)

显然,b上的单独索引将使搜索特定值b的速度加快。

但是,如果b上的单独索引是而不是,那么在我看来,复合索引仍然可以用于查找具有特定值的元组,而不是表扫描,方法是遍历a的离散值树,对b进行局部搜索,跳转到a的下一个值,等等。

这就是Server的工作方式吗?(例如,如果MSSQL对具有多列的索引使用单个哈希值,则不会发生这种情况。)

是的,而且由于其他原因已经需要综合指数,而且a的离散值的数目足够小,性能/空间的权衡可能会偏离对b的单独的指数。

(本例并不真正需要上面的唯一和聚集约束,但它们表示的是不涉及b的单独索引的b的最快检索--前者为a的每个循环提供了一个快捷方式,后者在查找中消除了某种程度的间接搜索)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-23 21:14:58

不,没有跳过一团'a‘。只有在指定了最左边的列时,才能使用索引,否则需要使用完整的扫描。

Oracle有所谓的“索引跳过扫描”运算符。

票数 8
EN

Stack Overflow用户

发布于 2013-07-11 15:15:14

代码语言:javascript
运行
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1615893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档