使用MemSQL上的列存储的稀疏矩阵

时间:2015-12-08 16:33:47

标签: memsql

我是列存储db系列的新手,有些概念对我来说还不是很清楚。我想使用MemSQL来存储稀疏矩阵。

表格看起来像这样:

CREATE TABLE matrix (
r_id INT,
c_id INT,
cell_data VARCHAR(10),
KEY (`r_id`, `c_id`) USING CLUSTERED COLUMNSTORE,
);

查询:

  1. SELECT c_id, cell_data FROM matrix WHERE r_id=<val>;即整行
  2. SELECT r_id, cell_data FROM matrix WHERE c_id=<val>;即全栏
  3. SELECT cell_data FROM matrix WHERE r_id=<val1> AND c_id=<val2>;,即一个单元格
  4. UPDATE matrix SET cell_data=<val> WHERE r_id=<val1> AND c_id=<val2>;
  5. INSERT INTO matrix VALUES (<v1>, <v2>, <v3>);
  6. 查询1和2大致相同,3和4也同样频繁。 Q1,2中的一个与Q3,4,5中的一个相同(即Q1,2:Q3,4,5~ = 1:1)。

    我确实意识到一次插入一行一行会为每个插入创建一个Row segment group,从而降低性能。我无法批量插入。此外,我不能使用内存行存储(矩阵太大)。

    我有三个问题:

    1. 如果仅更改cell_data(即Q4),单行插入的问题是否也会涉及更新?

    2. 是否可以使用内存行表来执行INSERT(?和UPDATE?)操作并定期将内容批处理到列表?

      • 如果我需要最新的数据(?UNION ALL?),我将如何执行Q1,2?
      • 是否可以避免为两个表执行Q3(?这意味着两次往返?)?
    3. 我担心Q1和Q2的执行速度。群集密钥是否适合那些人。我不确定如何将记录与上表一起存储。

1 个答案:

答案 0 :(得分:1)

1。 是的,单行更新也表现不佳 - 它们本质上是删除和插入。

2。 是的,实际上我们会在幕后自动执行此操作 - 最近插入的数据(如果它太小而无法成为一个好的柱状段)保存在内存中的行存储形式中,并且读取查询本质上是查看UNION所有数据和面向列的数据。然后我们批量处理这些数据以写入面向列的形式。

如果这不能很好地运行,根据您的工作负载,您可能会从将某些数据显式保存在rowstore表中而不是依赖于上述行为中受益,在这种情况下:

2a上。是的,要查看您将使用UNION ALL的最新数据

2B。数据可以在任何一个表中,因此您必须同时查询两者(例如Q1,2使用UNION ALL工作)。这不是两次往返,只有一次。

3。 您可以在当前架构中的columnstore key -r中首先按r或c排序。这使得对行的查询效率很高,但对列的查询效率非常低,它们可能必须基本扫描整个表(取决于数据中的模式)。不幸的是,columnstore表不支持使用多个键,因此没有好办法解决这个问题。一个潜在的hacky解决方案是维护表的两个副本,一个用密钥(r,c),一个用密钥(c,r) - 这基本上是手动维护两个索引。

根据您描述的工作量,听起来您正在进行许多单行查询(Q3,4,5,占工作量的50%),哪个rowstore比columnstore更适合(参见http://docs.memsql.com/latest/concepts/columnstore/)。不幸的是,如果它不适合内存,那么除了增加更多内存之外,其他方法并不是很好。