cassandra 中的主键和索引

Pie*_*rre 4 cassandra

cassandra 新手,仍在学习中。

create table url (
  id_website int,
  url varchar,
  data varchar,
  primary key(url, id_website)
);
Run Code Online (Sandbox Code Playgroud)

嗨,我有一个网站的网址表。

我不希望所有 url 都在同一个节点上,这就是为什么主键首先是 url,所以它将是分区键。

大多数情况下,我将检索特定 url 的数据,例如:“url = ? 和 id_website = ?”

但是,当我想检索网站的部分/所有 url 时,性能如何:

select * from url where id_website = 1 allow filtering limit XX;
Run Code Online (Sandbox Code Playgroud)

我认为此查询将在所有节点上分派,然后对 id_website=1 进行表扫描,直到达到限制,然后合并并发回我的客户端。

但是这种扫描是使用索引并有效还是一一读取 id_website 列的值并进行比较(无效)?我确实设置了主键的 id_website 部分,所以我希望它被索引,但我真的不知道。

我们是否在 cassandra 上有一些工具,比如 mysql 的 EXPLAIN 来检查查询是否使用索引。

谢谢。

——

编辑

以 id_website 作为分区键创建第二个表(并批量写入/删除)

我不想使用这个解决方案,因为我可能有一个或两个非常庞大的网站,并且有数百万个网址(还有数百万个网址很少的其他网站)。

如果我在 id_website 上有一个分区键,并且这两个或三个网站停留在同一个节点上,则可能会导致存储问题,或者处理这些网站的节点可能被请求过多而其他网站一无所获。我想将数据传播到所有节点。这就是为什么我坚持要在 url 上进行分区。

您在 id_website 上创建二级索引(它为您创建一个表)

这个解决方案怎么样?如果我理解,每个节点都会有一个表索引它基于 id_website 存储的行(所以不是其他节点的行)。所以我可以将我的 url 分布在许多节点上,我不会让一个节点处理包含特定网站的所有 url 的大索引。

现在当我使用我的查询

select * from url where id_website = 1 allow filtering limit XX;
Run Code Online (Sandbox Code Playgroud)

每个节点收到查询,但是这次不用遍历分区(url 列),可以直接在索引中查找属于id_website 的url,并返回行(或者什么都不返回)。对 ?

这个解决方案的反面是每次请求完成时,它都会命中每个节点,但是,由于新的索引,它应该很快?

Car*_*ini 5

你走对了。使用允许过滤,您只是要求 cassandra 扫描所有节点:非常无效。id_website已在每个分区内建立索引,但由于您没有告诉 Cassandra 去哪里,他必须访问所有分区(所有节点),即使是那些不包含所选信息id_website的分区——一旦 Cassandra 命中一个分区,就知道如何查找这些信息和不需要扫描整个分区来取回数据。

要在 Cassandra 中解决这个问题,您必须进行非规范化,在这种情况下,您可以通过两种可能的方式进行处理:

  1. 以 id_website 作为分区键创建第二个表(并批量写入/删除)
  2. 您在 id_website 上创建二级索引(它为您创建一个表)

**根据问题编辑**

你说的是对的:二级索引作为“本地索引”处理——每个节点只为它拥有的数据创建一个本地索引表。以下是关于二级索引的好读物(你已经理解了)

创建索引后,您必须ALLOW FILTERING从查询中删除。

HTH, 卡罗

  • 我告诉你,如果你有 3000 个“url”表分区,其中 1000 个包含 id_website=1 的信息,cassandra 将查询所有 3000 个分区,其中 2000 个将以空值回复,剩下的 1000 个将不会“扫描”分区,因为 id_website 已在分区内编入索引。 (2认同)