Cassandra 文档指出,
在这些情况下不要使用索引:
- 在高基数列上,因为您随后会为少量结果查询大量记录。请参阅下面的使用高基数列索引的问题。
它继续,
如果您在具有许多不同值的高基数列上创建索引,则字段之间的查询将导致为极少的结果进行多次搜索。在包含 10 亿首歌曲的表格中,按作者(每首歌曲通常唯一的值)而不是按艺术家查找歌曲可能会非常低效。手动维护表作为索引的形式而不是使用 Cassandra 内置索引可能会更有效。对于包含唯一数据的列,为了方便起见,有时使用索引在性能方面是很好的,只要对具有索引列的表的查询量适中并且不是在恒定负载下。
但从来没有真正回答过这个问题:为什么它效率低下?我不知道“手动维护表格作为索引的形式”是什么意思。但是它与“......有时为了方便而使用索引在性能方面是很好的,只要查询量适中......”有点矛盾。
这是否只是想告诉我何时何地可以使用 PK?什么是低效?我的理解是,命中索引的查询需要查询集群中的每个¹节点,然后每个节点将在其本地索引中进行查找,然后将结果汇总。这并不一定很昂贵(每个索引查找应该相当便宜),除了我们支付网络延迟,因为我们必须等待该批次中最慢的节点。我在这里错过了什么吗?
但是,如果我有一个包含大量项目的集合——在极少数情况下——需要通过不同但几乎独特的属性来查找……这是一个合适的用途,对吧?
¹每个?IDK,如果复制意味着这可以达到集群的 1/3,复制因子是否为 3?
使用 Cassandra 索引(即“二级索引”,而不是主键),每个节点都必须查询自己的本地数据以响应查询(请参阅 Cassandra二级索引常见问题解答)。这些索引也是使用后台进程构建的。这种背景意味着索引可能会在命中方面返回假阴性(或在未命中方面返回假阳性)。
这意味着在高基数列中,该列的变化率(即添加/删除)可能非常高。因此,如果这种变化率比通过后台进程更新索引快,那么使用索引是“低效的”(索引执行的工作比应用程序需要的多,这可能经常得到错误的答案) .
就查询准确性而言,更有效的方法可能是维护第二个表,而不是二级索引。与索引相反,表的处理方式与任何其他表一样。它们更有可能为您的应用程序提供它期望的查询结果。缺点是将表作为索引维护,而不是 Cassandra“二级索引”,现在是应用程序约束(即您的应用程序代码现在必须知道从该“索引”表中插入/删除行,并且 通过应用程序级别的“协调”保持两个表同步)。
希望这可以帮助!