我是建立索引的新手,并对最佳实践有疑问。
其核心是以下3个表:
表A
〜100,000行
对于给定的项目,例如产品,关于它的一些信息
ArticleId [int] (PK)
... some static info columns
表B
〜100,000 * K
行,其中K
将随着我们每隔几个月更新表B而增加。包含不确定的变量,但可以更改每次迭代。
UploadId [int] -- one for each K iterations
ArticleId [int] (FK on table A)
GroupingA [nvarchar](255)
GroupingB [nvarchar](255)
表C
〜5000万行,销售数据
ArticleId [int] (FK on table A)
Date [date]
Sales [int]
由于表很大,我很警惕我们可能需要一些高质量的索引,否则查询性能会受到影响。我读过,在字符类型上使用聚簇索引不是一个好主意。
主要查询之一是加入B&C并按以下方式汇总数据直至达到GroupingA
和GroupingB
的级别:
SELECT
C.[Date],
B.[GroupingA], B.[GroupingB],
SUM(C.Sales) AS Sales
FROM
C
INNER JOIN
B ON C.[ArticleId] = B.[ArticleId]
WHERE
B.Upload.Id = 1 -- example
GROUP BY
C.[Date], B.[GroupingA], B.[GroupingB]
对于表C,我做了一个UNIQUE CLUSTERED INDEX ... on (Date, ArticleId)
。对于表B,我打算为UNIQUE CLUSTERED INDEX ... on (UploadId, ArticleId)
做一个。
将聚集索引或非聚集索引放在B.[GroupingA], B.[GroupingB]
上是个好主意吗?它们将在分组中大量使用,因此我担心不对它们进行索引可能会很慢。我是否也应该将其与自己组成的identity()
ID一起用于查找?任何想法或链接都很棒:)
此外,将来我们可能会有更多的分组,例如GroupingC,..等。在此先感谢!
我的SQL Server版本:
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64) Aug 22 2017 17:04:49
Copyright (C) 2017 Microsoft Corporation Express Edition (64-bit)
on Windows 10 Pro 10.0 <X64> (Build 17134: ) (Hypervisor)
答案 0 :(得分:1)
发表评论的时间有点长。
这些列上的索引不会帮助您进行查询。您的汇总是合并两个表中的列,因此无法通过索引对其进行改进。
您可以为B(upload_id, article_id)
和c(article_id, date, sales)
编制索引。
您也许可以用以下方式表达查询内容:
select C.[Date], B.[GroupingA], B.[GroupingB]
sum(C.Sales) as Sales
from (select c.articleid, sum(c.sales) as sales
from c
group by c.articleid
) c join b
b
on C.ArticleId = B.ArticleId
where B.Upload_Id = 1 -- example
group by C.[Date], B.[GroupingA], B.[GroupingB];
但是,除非内部一级显着减少数据量并且可以利用c(articleid, sales)
上的索引,否则二级聚合将无济于事。