为快速即席查询构建100M记录表的好方法是什么?

时间:2012-04-27 07:34:24

标签: sql database database-design search nosql

场景非常简单,一个包含10列(分析数据类型)的表中有大约100M条记录,我需要能够对这10列的任意组合执行查询。例如:

  • 过去3个月内有a = 3 && b > 100的记录数是多少?

基本上所有的查询都是 X 中有Y 属性X的记录数,其中{{1}}可以是这10列的任意组合。

数据将继续存在,它不仅仅是预先给定的100M记录集,而是随着时间的推移而增长。

由于列选择可以完全随机,因此很可能无法为常用组合创建索引。

问题分为两部分:

  • 我应该如何在SQL数据库中构建它以尽可能快地进行查询,以及我可以采取哪些一般性步骤来提高性能?
  • 是否有任何类型的NoSQL数据库针对此类搜索进行了优化?我只能想到ElasticSearch,但我不会在这个大型数据集上表现得很好。

6 个答案:

答案 0 :(得分:1)

如果没有索引,您调整RDBMS以支持此类处理的选项将受到严格限制。基本上你需要大规模并行和超快速套件。但显然你没有存储实际数据,所以RDBMS是不合适的。

追求平行路线,行业标准为Hadoop。您仍然可以通过Hive使用SQL样式查询。

另一个noSQL选项是考虑一个柱状数据库。这些是在不使用多维数据集的情况下组织分析数据的替代方法。他们擅长快速加载数据。 Vectorwise是竞技场中的最新玩家。我没有亲自使用它,但是昨晚伦敦数据聚会的某个人对我赞不绝口。 Check it out

当然,远离SQL数据库 - 无论走向何方 - 都会产生陡峭的学习曲线。

答案 1 :(得分:0)

您应该构建一个SSAS多维数据集并使用MDX进行查询。

多维数据集具有“聚合”,这意味着提前计算结果。依赖于如何配置多维数据集(以及聚合),您可以在度量值组中使用SUM属性(例如A)多维数据集A有多少条记录,它只会读取聚合而不是读取所有表并计算它。

答案 2 :(得分:0)

就Oracle而言,这很可能被构造为一个区间分区表,在您可能查询的每一列上都有本地位图索引,并且通过直接路径插入或分区交换添加新数据。

可以使用一组物化视图优化对常用列组合的查询,可能使用汇总或多维数据集查询。

答案 3 :(得分:0)

使用SQL解决方案快速运行这些查询使用这些经验法则。虽然有很多警告,但您使用的实际SQL引擎与解决方案非常相关。

我假设您的数据是整数,日期或短期缩放器。长串等改变游戏。我还假设您只使用固定比较(=,<,>,<>等)

a)如果每个查询中都存在时间间隔Y,请确保将其编入索引,除非Y谓词选择了大部分行。确保行以“Y”顺序存储,以便它们彼此相邻地打包在磁盘上。无论如何,对于新数据,这将自然发生。如果Y谓词非常紧(即几百行),那么这可能就是你需要做的全部。

b)你在做“选择”或“选择计数()”吗?如果不是“select *”,那么垂直分区可能会有所帮助,具体取决于引擎和其他索引。

c)为值广泛分布的每列创建单列索引,并且没有太多重复项。索引YEAR_OF_BIRTH通常可以,但索引FEMALE_OR_MALE通常不好 - 尽管这是高度数据库引擎特定的。

d)如果您有像FEMALE_OR_MALE这样的列并且“Y谓词”很宽,那么您会遇到另一个问题 - 从大多数行中选择女性数量的计数将会发生变化。您可以尝试编制索引,但取决于引擎。

e)如果可能的话,尝试使列“非空” - 通常每行节省1位,可以简化内部优化器操作。

f)更新/插入。创建索引通常会损害插入性能,但如果您的速率足够低,则可能无关紧要。只有100M行,我假设你的插入率相当低。

g)多段密钥会有所帮助,但你已经说过它们不行了。

h)获取高速磁盘(RPM) - 这些类型的查询的问题通常是IO(TPC-H基准测试是关于IO的,你听起来像是“H”问题)

还有更多选项,但这取决于您希望花费多少精力来“尽可能快地进行查询”。有很多No-SQL和其他选项可以解决这个问题,但我会将这部分问题留给其他人。

答案 4 :(得分:0)

除了上述建议外,请考虑查询更新的物化视图。我想我只是在桌面上用cube()物化视图创建一个select,count(*)组。

这将为您提供一个完整的多维数据集。在一个小型测试台上玩这个,以了解多维数据集汇总的工作方式。查看Joe Celko的书籍以获取一些示例,或者只是点击您的特定RDBMS文档以获取示例。

如果您必须始终能够查询表中最高达微秒的数据,那么您会陷入困境。但是如果你能放松这个要求,你会发现物化视图立方体是一个相当不错的选择。

您是否绝对确定您的用户会以统一的方式点击所有10列?在过去的这种情况下,我过早地对自己进行了过度优化,结果却发现用户确实在他们的大多数报告中使用了一两列,并且那些滚动到那些一两个colunmns的'足够好'。

答案 5 :(得分:0)

如果无法从数据创建OLAP多维数据集,您是否可以根据X和Y的唯一组合创建摘要表。如果时间段Y具有足够高的粒度,则可以合理地使用汇总表小。显然取决于数据。

此外,您应该捕获用户运行的查询。通常情况下,用户说他们想要所有可能的组合,在实践中很少发生这种情况,并且大多数用户查询可以从预先计算的结果中得到满足。这里的摘要表将是一个选项,您可以使用此选项获得一些数据延迟,但它可以工作。

如果可能,其他选项是查看硬件。过去使用固态驱动器(例如Fusion-IO)我的结果很好。这可以大大减少查询时间。这不是优秀设计的替代品,但凭借良好的设计和合适的硬件,它运作良好。