在SQL中存储/查询特定树结构的更好方法是什么?

时间:2012-09-29 21:57:10

标签: mysql sql tree indexing

enter image description here

我们得到了这个数据模型。知道有限的树深度,我们当前的表与模型是1:1,具有父节点的外键。 ChannelStationMeasurementChannelStation。 90%的查询是:

select value from measurements where
fk_station=X and fk_channel=Y and timestamp>=A and timestamp<=B
order by timestamp asc

其余10%在其他带时间戳的表上类似,但由于缺少fk_channel而更简单。

我们面临的问题: [station,channel,timestamp]表中有数亿个独特的Measurement行并且正在增长。时间戳索引是如此巨大,而且排序条款太慢了,我们不得不按 Station Id 开始拆分它;所以我们有表Measurement_<Station Id>并且省略了Station外键。它有很大帮助,但仍有一些表有数千万行。在负载峰值中,我们获得了大约80000个查询/分钟,并且对这些较大的表的查询显然更加懒散。我们仍然从一个MySQL / ISAM实例运行,没有任何花哨的优化黑客。文件系统大约150GB。

  1. 有没有明显不同/更好的方式来存储这样的数据模型?
  2. 目前的结构,我们在这个尺寸/负载下遇到这种性能打嗝是否正常?机器是今天的平均hw,没有嵌入式原子也没有8+核心野兽
  3. Measurement表分拆正确的事情吗?我们不是SQL专家,但查询和所需的索引似乎很明显,我们甚至没有考虑“优化”它。分裂帮了很多,但其他东西也可能太多了
  4. 还有其他加速索引的方法吗?有点愚蠢的是我们必须一遍又一遍地做同样的索引,得到相同结果的子集。我们不会使用任何其他索引,甚至不会更改为desc。这是非常专业的设备。如果索引以某种方式“本地订单”会很好: - )
  5. 是否有助于分发/分割分割的Measurement表?正如我所说,一些表仍然很大,问题感觉是关于索引大小的分布无济于事,所以也许只是降低查询负载......

2 个答案:

答案 0 :(得分:1)

在mysql这样的关系数据库中考虑的简单规则:

  1. 获取太多数据永远不会很快。聚合它可以。 - 您的示例查询未聚合任何内容。让我想知道你是否在你的应用程序中处理并聚合那些。提示:使用列存储引擎进行聚合,例如。 infinidb,它也支持查询执行中的并行性,innodb没有。
  2. 对大量数据进行排序永远不会很快 - 问问自己,如果查询返回100K记录,那么您的处理作业/前端网格等消耗了多少? Web用户是否可以在屏幕上消耗100K数据。不是真的,然后限制它。此外,按自动增量ID而不是时间戳排序。关系数据库引擎不适合排序大量数据,你很快就会达到上限。

答案 1 :(得分:0)

是否有可能在多个表上拆分测量数据可以减小尺寸?如果90%的查询超过过去24小时的时间戳,那么您可能希望微调该数据,并将其余查询存储在单独的表甚至数据库中。我相信测量应该只有一个FK只有通道,它只有它的ID作为PK,而一个FK到站。