【问题标题】:SQL Server aggregates for very large tablesSQL Server 聚合非常大的表
【发布时间】:2009-10-02 20:08:24
【问题描述】:

我们有一个包含 1700 万行的表,其中包含产品属性,假设它们是:

brandID、sizeID、colorID、price、shapeID

我们需要按品牌和尺寸查询聚合。目前我们通过执行以下操作来查询和过滤这些数据:

select brandID, sizeID, count(*) 
from table where colorID in (1,2,3) and price=10 and shapeID=17
--"additional complex where clause here"
group by brandID, sizeID
order by brandID, sizeID

我们会报告这些数据。问题是,运行这个查询需要 10 秒左右(这是一个非常简单的例子),尽管返回的实际数据只有几百行。

我认为我们已经达到了索引该表的能力,所以我认为任何数量的索引都不会让我们获得近乎即时的结果。

我对 OLAP 或其他分析服务知之甚少,但 SQL Server 有什么可以预过滤或预聚合此表以便执行上述查询(或类似返回等效数据)? 或者在一个非常大的表上处理任意 where 子句的最佳方法是什么?

【问题讨论】:

  • 您能否告诉我们数据的频率和新鲜度,即“有人每 15 分钟运行一次,数据需要保持最新”或“很多人整天都在运行,但我们'很高兴看到昨天的数据'(多维数据集或索引视图的主要候选者)

标签: sql sql-server tsql olap


【解决方案1】:

我认为这是 olap 立方体的完美候选者。我有数百万行的事实数据。我正在做您上面描述的那种查询,并且查询会在几分钟内返回。我把它移到了一个 OLAP 多维数据集中,现在查询几乎是即时的。 olap 有一些学习曲线。我强烈建议您找到有关一些简单立方体构建的教程,以了解它。多年来,DBA 的同事一直在告诉我有关多维数据集的内容,但我一直没有完全理解。现在我不知道为什么我这么长时间没有它。

除了 OLAP,您可能还想研究索引视图,但如果您以多种方式对数据进行切片,那可能不可行。

【讨论】:

  • 如果我错了,请纠正我,但是需要刷新 OLAP 多维数据集(或重新编译,我不记得正确的词)才能更新数据。因此,如果 Jody Powlette 需要实时数据,它可能不是最佳解决方案。
  • 以星型模式加载数据可以被认为是“穷人的 OLAP”。
  • 我同意马特的观点。是的,他们确实需要重新处理并重新部署更新,但如果 Jody 所说的这张表被用于报告,他们可以根据需要安排这些特定更新,而不会中断服务和访问。
  • 另外,对于这么大的数据,您需要确保对多维数据集进行分区(可能按月)。这样,当您每天都添加数据时,您只需重新处理当前月份。
【解决方案2】:

如果没有详细说明您的表结构和物理环境以及(非)聚集索引等。我首先要查找的瓶颈是查询的“显示执行计划”,还有数据库引擎优化顾问和 SQL 探查器。希望这可以帮助。

【讨论】:

    【解决方案3】:

    取决于您的索引和架构

    无论如何,这个查询的索引应该是其中之一

    CREATE INDEX IX_foo ON table (shapeID, price, colorID) INCLUDE (brandID, sizeID)
    CREATE INDEX IX_foo ON table (shapeID, price, colorID, brandID, sizeID)
    

    但是,您在此处添加了“额外的复杂 where 子句”,这会影响一个好的答案

    我的想法:

    • WHERE 子句很重要,因为它可以减少行数
    • ORDER BY 不如聚合/WHERE 重要
    • 覆盖查询以删除键查找

    额外的东西:

    • (1,2,3) 中的 colorID 不正确,因为它是 OR
    • 确保参数数据类型与列数据类型完全匹配以避免隐式转换
    • 您可以稍微交换 shapeID、Price 和 colorID 以查看最佳选择(或创建一些索引并查看使用哪个索引)
    • 您是否有服务器瓶颈(例如在 SQL Express 上运行等)?

    【讨论】:

      【解决方案4】:

      如果您使用的是 SQL 2008 并且有一些特定的常用过滤,请考虑使用过滤索引(可能与 gbn 建议的 INCLUDE 索引结合使用)。

      假设您只有五个 sizeID 值。您可以将当前索引分解为多个过滤索引(例如,“WHERE sizeID = 1”)。

      将过滤与 INCLUDE 结合使用可以使您的查询返回快得多

      参考:Exploring SQL Server 2008’s Filtered Indexes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-28
        • 1970-01-01
        • 1970-01-01
        • 2022-06-11
        • 2018-02-02
        • 2015-02-20
        • 2021-07-17
        • 1970-01-01
        相关资源
        最近更新 更多