我有一个大的事实表和一个简单星型模式中的小得多的维度表:
--1.
CREATE TABLE dbo.Dim
(
Id INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
CustomerName VARCHAR(2000)
)
--index
CREATE UNIQUE NONCLUSTERED INDEX uniqueindex1 ON Dim(CustomerName);
--2.
CREATE TABLE dbo.Fact
(
...
PurchaseDate DATE
CustomerNameId INT CONSTRAINT fk1 FOREIGN KEY (CustomerNameId) REFERENCES dbo.Dim(Id)
...
)
--index
CREATE CLUSTERED COLUMNSTORE INDEX ccs ON dbo.Fact;
运行以下简单查询,过滤事实表并加入维度:
SELECT sd.CustomerName,f.*
FROM dbo.Fact f
INNER JOIN dbo.Dim sd ON sd.Id = f.CustomerNameId
WHERE f.PurchaseDate IN (
'20000506',
'20000507',
'20000508',
'20000509',
'20000501',
'20000502',
'20000503'
)
有趣的是,维度表倾向于在 4 次迭代中扫描所有 500 000 行,但最终在事实表的该日期范围内只需要几千行。
这对于较大的维度表来说是非常低效的,基本上所有的行都是一直扫描的,就像查找表索引甚至不存在一样。
预期的事情是sql server首先将事实表限制在日期范围内,然后使用这个有限的CustomerKeyId范围,它使用索引查找从小维度表中查找CustomerName。
- 这真的是星型模式的效率低下,还是我在这里想念什么?
- 换句话说,我怎么能强制 sql server 准备有限的 CustomerKeyId 表并只查找那些?(不知何故有CTE?)