这种方法可以扩展SQL查询吗?

时间:2010-03-15 14:43:27

标签: sql parallel-processing database

我有一个包含单个巨大表的数据库。目前,查询可能需要10到20分钟的任何时间,我需要将其缩短到10秒。我花了几个月尝试不同的产品,比如GridSQL。 GridSQL工作正常,但使用自己的解析器,它没有所有需要的功能。我还以各种方式优化了我的数据库,但没有得到我需要的加速。

我有一个关于如何扩展查询的理论,这意味着我利用多个节点并行运行单个查询。前提条件是数据被分区(垂直),每个节点上放置一个分区。我们的想法是获取传入的SQL查询,并且只是像在所有节点上一样运行它。将结果返回到协调器节点时,将对结果集的并集运行相同的查询。我意识到像平均值这样的聚合函数需要被重写为一个计数并对节点求和,协调器将总和的总和除以计数的总和来得到平均值。

使用此模型无法轻易解决哪些问题。我相信一个问题就是计数不同的功能。

编辑:我收到了很多很好的建议,但没有人提出这个方法。

8 个答案:

答案 0 :(得分:6)

这是一个数据量问题,不一定是架构问题。

无论是在1台机器还是1000台机器上,如果最终总结1,000,000行,您将遇到问题。

您需要对其进行反规范化,而不是对数据进行规范化。

您在评论中提到您的数据库“非常适合您的目的”,显然,它并非如此。这太慢了。

所以,必须要付出一些代价。您的完美模型不起作用,因为您需要在太短的时间内处理过多的数据。听起来你需要比原始数据更高级别的数据集。也许是数据仓库解决方案。谁知道,没有足够的信息可以说出来。

但是,您可以采取很多措施来满足具有良好响应时间的特定查询子集,同时仍允许在“10-20分钟内”响应的即席查询。

关于评论的编辑:

我不熟悉“GridSQL”或它的功能。

如果您向单个“分片”数据库发送多个相同的SQL查询,每个数据库都包含一个子集,那么简单选择查询将扩展到网络(即您最终将成为网络绑定到控制器),因为这是一个真正的,平行的,无国籍的过程。

正如您所提到的,问题变成了二次处理,特别是排序和聚合,因为这只能在最终的“原始”结果集上完成。

这意味着您的控制器最终会不可避免地成为您的瓶颈,最终,无论您如何“扩展”,您仍然需要应对数据量问题。如果将查询发送到1000个节点并且不可避免地必须对每个节点的1000行结果集进行汇总或排序,从而产生1M行,那么在单个计算机上仍然需要很长的结果时间和大量的数据处理需求。

我不知道您使用的是什么数据库,我不知道有关各个数据库的具体信息,但是您可以看到如何实际将数据划分到多个磁盘轴上,并且具有一个像样的,现代的,多-core处理器,数据库实现本身可以根据并行磁盘主轴请求处理大部分这种扩展。实际上哪些实现可以做到这一点,我不能说。我只是建议他们可以(有些人可能会这样做)。

但是,我的一般观点是,如果你正在运行,特别是聚合,那么如果你每次都在点击原始资源,那么你可能会处理过多的数据。如果您分析查询,您可能能够以各种粒度级别“预先汇总”您的数据,以帮助避免数据饱和问题。

例如,如果您要存储单个网络点击,但对基于每天的每小时的活动(而不是您可能正在记录的亚秒级数据)更感兴趣,那么仅仅汇总一天中的小时可以减少您的数据需求急剧增加。

因此,向外扩展肯定会有所帮助,但它可能不是解决问题的唯一方法,而是一个组件。数据仓库旨在解决这些类型的问题,但不适用于“临时”查询。相反,您需要合理地了解要支持的查询类型并相应地进行设计。

答案 1 :(得分:5)

一张巨大的桌子 - 这可以归一化吗?

如果您主要进行选择查询,您是否考虑过对要查询的数据仓库进行规范化,或者运行分析服务和多维数据集来为您进行预处理?

从你的问题来看,你所做的事情听起来像是一个多维数据集优化的东西,并且可以在不必编写所有管道的情况下完成。

答案 2 :(得分:4)

通过尝试自定义解决方案(网格),您会引入很多复杂性。也许,这是你唯一的解决方案,但首先你尝试partitioning the table(原生解决方案)?

答案 3 :(得分:2)

我正在认真研究OLAP解决方案。 Cube的技巧一旦建成,就可以通过许多方式进行查询,而这些方法可能没有考虑过。正如@HLGEM提到的,你有没有解决索引?

即使在数百万行中,一个好的搜索应该是对数而不是线性的。如果您有一个查询导致扫描,那么您的性能将被破坏。我们可能需要您的结构示例,看看我们是否可以提供更多帮助?

我也完全同意@Mason,您是否已经分析了您的查询并调查了查询计划以查看您的瓶颈所在。添加节点提高速度使我认为您的查询可能受CPU限制。

答案 4 :(得分:1)

我的猜测(基于我的直觉除外)是你可能从并行化中看到的任何收益都会被重新聚集和随后的结果查询所吞噬。此外,我认为写作可能会因pk / fk / constraints而变得更复杂。如果这是我的世界,我可能会在我的表(和其他视图)之上创建许多索引视图,这些视图针对我需要执行的特定查询进行了优化(我已经成功地在1000万+行表中使用过。)

答案 5 :(得分:1)

大卫,

您使用的是GridSQL的所有功能吗?您还可以使用约束排除分区,有效地将大表分成几个较小的表。根据您的WHERE子句,在处理查询时,它可能会查看更少的数据并更快地返回结果。

此外,您是否为每个物理服务器使用多个逻辑节点?以这种方式配置可以利用其他空闲内核。

如果在执行期间监视服务器,是瓶颈IO还是CPU?

此处还提到您可能希望将事实表中的行汇总到汇总表/多维数据集中。我对Tableau不太了解,它会自动使用适当的立方体并仅在必要时向下钻取吗?如果是这样的话,似乎你会在这样的事情上获得巨大收益。

答案 6 :(得分:1)

如果在每个节点上运行未分区的传入查询,为什么在运行相同查询的单个节点完成之前,任何节点都会完成?我误解了你的执行计划吗?

我认为这部分取决于您正在执行的查询的性质,特别是有多少行对最终结果集有贡献。但是你肯定需要在节点之间以某种方式对查询进行分区。

答案 7 :(得分:0)

扩展查询的方法运行正常。

事实上,我已经实现了这样一种方法: http://code.google.com/p/shard-query

它使用解析器,但它支持大多数SQL结构。

它还不支持count(distinct expr),但这是可行的,我计划在将来添加支持。

我还有一个名为Flexviews的工具(google for flexviews物化视图)

此工具允许您创建包含各种聚合函数和连接的实体化视图(汇总表)。

这些工具结合在一起可以为OLAP类型查询带来巨大的可扩展性改进。