cassandra中的主键和索引

时间:2014-10-22 11:36:34

标签: cassandra

cassandra的新手,还在学习。

create table url (
  id_website int,
  url varchar,
  data varchar,
  primary key(url, id_website)
);

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

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

我大部分时间都要检索特定网址的数据,例如:“url =?and id_website =?”

然而,当我想要检索网站的部分/所有网址时,性能如何:

select * from url where id_website = 1 allow filtering limit XX;

我认为这个查询将在所有节点上调度,然后,表扫描id_website = 1直到达到限制然后合并并发送回我的客户端。

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

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

感谢。

-

修改

  

使用id_website作为分区键创建第二个表(和   批量写/删除)

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

如果我在id_website上有分区密钥,并且这两个或三个网站停留在同一个节点上,则可能会导致存储问题,或者处理这些网站的节点可能会过多地请求,而另一个网站则什么也得不到。我想在所有节点上传播数据。这就是为什么我坚持要在网址上进行分区。

  

您在id_website上创建一个辅助索引(为其创建一个表   你)

这个解决方案怎么样?如果我理解,每个节点都有一个表,它根据id_website索引它存储的行(所以不是其他节点的行)。所以我可以将我的网址传播到许多节点,我不会有一个节点处理包含特定网站所有网址的大索引。

现在我使用我的查询

select * from url where id_website = 1 allow filtering limit XX;

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

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

1 个答案:

答案 0 :(得分:2)

你正确的方式。使用允许过滤你只是要求cassandra扫描所有节点:非常无效。 id_website在每个分区中都被编入索引,但由于您没有告诉Cassandra去哪里,他必须点击所有分区(所有节点),即使那些没有包含所选id_website信息的分区 - 一次Cassandra命中分区知道如何查找这些信息,不需要扫描整个分区来获取数据。

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

  1. 使用id_website作为分区键创建第二个表(并批量写入/删除)
  2. 您在id_website上创建了一个二级索引(为您创建一个表)
  3. **编辑问题编辑**

    你所说的是正确的:二级索引作为"本地索引" 处理 - 每个节点仅为其拥有的数据创建一个本地索引表。以下是关于二级索引的good reading(您已经了解)

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

    HTH, 卡罗