【问题标题】:Efficient Ad-hoc SQL OLAP Structure高效的 Ad-hoc SQL OLAP 结构
【发布时间】:2010-08-12 20:48:24
【问题描述】:

多年来,我阅读了很多人关于如何从他们的 SQL(Microsoft SQL Server,只是为了让我们都在同一个页面上......)查询中获得更好性能的意见。但是,它们似乎都与高性能 OLTP 设置或数据仓库 OLAP 设置(cubes-galore...)紧密相关。但是,我今天的情况有点在 2 的中间,因此我犹豫不决。

我有 [Contacts]、[Sites]、[SiteContacts]([Sites] 和 [Contacts] 的联结表)、[SiteTraits] 和 [ContractTraits] 的一般数据库结构。我有近 300 万个联系人,其中大约 50 个字段(在 [Contacts] 和 [ContactTraits] 之间)仅与联系人相关,并且约有 60 万个站点与大约 150 个字段(在 [Sites] 和 [SiteTraits] 之间)仅与站点相关.基本上它是一个相当大的扁平化表格或视图……大多数列是 intbitchar(3) 或短 varchar(s)。我的问题是这些列中有很大一部分可供用户在即席查询中使用,并且可以尽快使用,因为主要的 UI 将是一个网站。我知道最常见的过滤器,但即使对它们进行大量索引,我认为这仍然是一个野兽……这些数据是只读的;数据在白天完全没有变化,数据库只会在计划的停机时间内用最新信息刷新。所以我认为这种情况就像一个具有 OLTP 数据库读取要求的 OLAP 数据库。

我看到 3 个选项; 1. 将表分解成更小的可分割单元,对所有内容进行子查询, 2. 制作一个平面表,然后在索引上真正进入城镇 3. 创建一个 OLAP 多维数据集并根据我没有放置的过滤器值对其余部分进行子查询作为立方体尺寸,和。我对 OLAP 多维数据集做的不多,所以坦率地说,我什至不知道这是否是一种选择,但从我过去对它们所做的事情来看,我认为这可能是一种选择。另外,为了澄清我所说的“子查询所有内容”的意思,而不是在外部选择上有一个 WHERE 子句,每个表都会有一个(如果适用)被带入查询,然后表是INNER JOINed,消除一个非常大的笛卡尔积。至于一个大表的第二个选项,我听说并看到了与该方法相冲突的结果,因为它可以节省连接,但同时表扫描需要更长的时间。

有什么想法吗?我需要分享我正在吸烟的东西吗?我认为如果每个人都投入 2 美分,这可能会变成一个很好的讨论。哦,如果是这种情况,请随时告诉我,如果我对 OLAP 多维数据集的想法不满意,我也是新手。

在此先感谢所有的意见和帮助,以解决我遇到的这个困境。

【问题讨论】:

    标签: sql sql-server database tsql database-design


    【解决方案1】:

    您可能希望将此视为关系数据仓库。您可以将关系数据库表设计为星型模式(或雪花模式)。这种设计非常类似于OLAP立方体的逻辑结构,但物理结构在关系型数据库中。

    在星型模式中,您将拥有一个或多个事实表,它们代表某种交易并且通常与日期相关联。不过,我不确定在这种情况下交易可能是什么。事实可能是网站与联系人和表格的关联。

    事实表将引用描述事实的维度表。维度可能是站点和联系人。一个维度包含属性,例如联系人姓名、联系人地址等。如果您熟悉 OLAP 立方体,那么这将是一个熟悉的逻辑架构。

    在您的架构中添加大量索引并不是什么大问题。数据库大部分是只读的,除了刷新时间。在更新索引时,您不必担心读取性能。因此,该架构可以容纳所需的所有索引(只要您可以投入足够的停机时间来刷新数据)。

    【讨论】:

    • 我同意这一点 - 我们在维度上建模,这为同时涉及未知数量维度的临时查询提供了良好的查询性能。如果您在已经有维度的模型之上构建多维数据集,那很好 - 我们只是在没有任何花哨的 OLAP 的 RDBMS 引擎中使用(非规范化星型模式)维度模型。
    • 此外,我认为,对于这些相对适中的数据量(数百万与数十亿),您可以每天进行多次完全刷新。从而避免变更数据捕获或任何此类问题。
    • 我对多维数据集方法的犹豫是,有时我只想要一个计数(比如说不同数量的 ContactId),或者我实际上可能需要返回数据(姓名、地址、职位标题、电话号码等.) 这可能是数据库中除了内部 id 和键之外的所有字段...我是否只使用结果,如果 ContactIds 则只说不同的列表,在传统的 t-SQL 选择中像使用 IN 或当需要返回实际数据而不仅仅是计数时,加入/加入数据库的非规范化版本?
    【解决方案2】:

    我同意鲍勃的回答:抛出一个 OLAP 前端并通过多维数据集进行查询。这将是一个好的想法的原因是多维数据集在查询(通常是预先计算的)多维聚合方面非常高效,并且它们以面向列的格式存储数据,这对于数据分析更有效。

    多维数据集下方的关系数据非常适合进行详细钻探,以找到提供特定聚合值的单个事实。但是直接查询关系数据总是会很慢,因为那些用户感兴趣用于分析的聚合只能通过扫描大量数据来产生。 OLAP 在这方面做得更好。

    【讨论】:

      【解决方案3】:

      根据我的经验,OLAP/SSAS 对聚合查询很有效,但对粒度数据却没有那么高。

      最常见的查询是什么?对于单个数据或聚合?

      【讨论】:

      • 嗯,有些是计数,所以这是我的聚合方案,但是当实际数据需要返回到屏幕或向客户端发送数据文件时,它会像普通 SQL 一样拉数据询问。 OLAP/SSAS 方法是否最适合计数场景,但我应该避免在数据拉取场景中使用它吗?如何从多维数据集中获取 ID 并在我的数据中使用它们来拉取 t-sql?使用这两种方法的最佳方法是每种方法的特定优势吗?想法?
      【解决方案4】:

      如果 SiteContacts 的粒度与联系人的粒度非常接近(即大约 300 万条记录 - 大多数联系人仅与单个站点相关联),您可能会从单个表中获得最佳性能(具有大量适当的索引, 显然; 还应考虑分区)。

      另一方面,如果大多数联系人与许多网站相关联,则最好坚持使用与您当前架构相近的内容。

      OLAP 往往会在聚合数据上产生最佳结果 - 听起来好像对这些数据执行的聚合相对较少。

      星型架构由带有维度的事实表组成 - 根据站点和联系人之间的关系,听起来好像您要么有一个巨大的维度表,要么有两个带有无事实事实表的大维度(听起来像是矛盾的说法) ,但在 Kimball 的方法中有所介绍)链接它们。

      【讨论】:

      • “听起来好像对这些数据进行的聚合相对较少” 好吧,当计数(联系人、站点或两者的数量)是产品的一半时,这是一个聚合。当应用程序正在寻找实际返回的数据时,不,那里没有太多聚合。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多