6

我有数据,它是一个整数值矩阵,表示带状分布曲线。我正在优化 SELECT 性能而不是 INSERT 性能。最多有 100 个波段。我将主要通过对一段时间内的波段求和或平均来查询这些数据。

我的问题是,我可以通过在每个波段使用 1 列的表中展平这些数据,或者通过使用表示波段值的单列来实现更好的性能吗?

扁平化数据

UserId ActivityId DateValue Band1 Band2 Band3....Band100
10001  10002      1/1/2013  1     5     100      200

或归一化

UserId ActivityId DateValue Band BandValue
10001  10002      1/1/2013  1    1
10001  10002      1/1/2013  2    5
10001  10002      1/1/2013  3    100

示例查询

SELECT AVG(Band1), AVG(Band2), AVG(Band3)...AVG(Band100)
FROM ActivityBands
GROUP BY UserId
WHERE DateValue > '1/1/2012' AND DateValue < '1/1/2013'
4

4 回答 4

8

以标准化格式存储数据。

如果你没有从这个方案中获得可接受的性能,而不是反规范化,首先考虑你在表上有什么索引。您可能缺少一个索引,该索引会使它的执行类似于非规范化表。接下来,尝试编写查询以从规范化表中检索数据,以使结果集看起来像非规范化表,并使用该查询创建索引视图。这将为您提供与非规范化表相同的选择性能,但保留适当规范化的良好数据组织优势。

于 2013-05-14T02:39:23.297 回答
4

非规范化恰好优化了一种访问数据的方法,而牺牲了(几乎所有)其他方法。

如果您只有一种对性能至关重要的访问方法,则非规范化可能会有所帮助;尽管适当的索引选择有更大的好处。但是,如果您对数据有多个性能关键的访问路径,则最好寻求其他优化。

创建适当的聚集索引;将您的非聚集索引放在 SSD 上。增加服务器上的内存;都是可以提高所有* 访问性能的技术,而不是在各种访问之间进行权衡。

于 2013-05-14T02:49:01.483 回答
2

如果您要访问每行中的所有(或大部分)波段,那么非规范化形式会更好。根据我的经验要好得多。

原因很简单。页面中的数据大小要小得多,因此需要读取的页面要少得多才能满足查询。每行存储一个波段的开销约为 4 个整数或 32 个字节。所以,100 个波段大约是 3200 字节。在单个记录中,记录大小为 100*4+8 或约 408 字节。如果您的查询正在读取大量记录,这会显着降低 I/O 要求。

有一个警告。如果您只阅读一条记录,那么 100 条记录适合在 SQL 中的单个页面上,而一条记录适合在单个页面上。在这两种情况下,单页读取的 I/O 可能相同。好处是您阅读了越来越多的数据。

您的示例查询正在读取数百或数千行,因此非规范化应该有利于这样的查询。

于 2013-05-14T02:43:27.860 回答
1

如果您想非常快速地获取数据,那么您应该展平表格并使用索引来改进与您建议的类似的广泛列范围的选择。但是,如果您对构建数据以进行快速更新感兴趣,那么将 3 级或 4 级规范化与大量表连接结合使用应该会提供更好的性能。

于 2013-05-14T02:30:31.590 回答