【发布时间】:2021-01-13 21:00:23
【问题描述】:
我们有一个包含非规范化数据的表,其中存储事件,其中包括以下字段: 产品编号 |产品名称 |子类别 ID
它们直接相互依赖,因此对于特定的 productid,Productname 和 subcategoryid 可能只有一个值。 由于我们存储事件,因此我们有许多行将包含与上述三个字段相关的相同信息。
我们现在正在设计一个查询来获取唯一的 productid、productname 和 subcategoryid。 这些查询将返回相同的实体:
select ProductId from VisitEvents
group by ProductId
就像这个:
select productid, productname, subcategoryid from visitevents
group by productid, productname, subcategoryid
但是后者要慢几个数量级。 除了第一个查询中的分组之外,还有其他方法可以投影其他字段吗?
【问题讨论】:
-
使用
Distinct而不使用Group By -
速度问题可能与索引有关。如果您在 ProductID 上有一个非聚集索引,那么它可以将其拉出,而无需点击聚集索引。此外,排序(分组所需的)非常占用处理器和内存。您的排序可能没有足够大的内存授权并且溢出到磁盘。查看您的执行计划可能表明存在问题(例如,黄色 ! 标记表示存在问题)。此外,如果您在运行前
SET STATISTICS TIME, IO ON;,它会很好地总结您的数据是如何从磁盘读取的。 -
您有建议。简短的回答是不缺少 DDL 的变化。索引可能会有所帮助。物化视图可能会有所帮助。也许现在是回顾导致非规范化的原因的好时机——因为那是真正的原因。还有一件事要考虑。大多数查询需要进行排序才能有用 - 您的查询没有 ORDER BY 子句,因此没有定义的顺序。如果顺序很重要,您的查询必须有一个 ORDER BY 子句。
-
我们在表上有一个聚集列存储索引,因此更多索引可能无济于事。 @MostafaArmandi,我尝试过不同的,这给了我完全相同的性能。
标签: sql-server performance denormalization