【问题标题】:Cassandra performance on clustered column sorting vs secondary indexCassandra 在聚集列排序与二级索引上的性能
【发布时间】:2015-11-09 21:58:11
【问题描述】:

我的架构是:

A)

CREATE TABLE friend_list (
    userId uuid,
    friendId uuid,
    accepted boolean, 
    ts_accepted timestamp,
    PRIMARY KEY ((userId) ,accepted, ts_accepted)
   ) with clustering order by (accepted desc, ts_accepted desc);

B)

CREATE TABLE friend_list (
        userId uuid,
        friendId uuid,
        accepted boolean, 
        ts_accepted timestamp,
        PRIMARY KEY (userId , ts_accepted)
       ) with clustering order by (ts_accepted desc);
CREATE INDEX ON friend_list (accepted);

这将为查询提供最佳性能:

SELECT * FROM friend_list WHERE userId="---" AND accepted=true;

据我了解,Cassandra 会自动按 ASC 顺序对聚集的列进行排序,如果我们需要更改默认排序顺序以实现高效查询,我们指定 DESC。

使用我的架构 A,我将“接受”作为聚集键,但我需要对其进行不必要的排序,因为我必须将“ts_accepted”排序为 DESC。 这种不需要的“已接受”排序会影响性能吗?

如果是这样,假设我将“接受”作为模式 B 中的二级索引。我知道二级索引对于低基数值(布尔值)并不坏。但查询仍然可能存在一些性能问题。

请告诉我实现此查询的有效方法。

【问题讨论】:

标签: cassandra cassandra-2.0 query-performance nosql


【解决方案1】:

我会选择A。

如果您可以避免使用二级索引,请避免使用它(例外:您知道这将是一项可以从中受益的火花工作)。如果您仍然需要二级索引,请重新设计您的模型。如果您仍然需要它,请在内心感到恐惧,然后考虑一下。

您担心的聚类订单成本不合适。 Cassandra 存储无论如何排序的聚类列...ASC 或 DESC 不会改变任何事情。您正在使用更多的空间,但是对于您的查询,您想点击“接受”,所以这是合理的。我猜 ts_accepted 是出于其他原因需要吗?这里唯一的问题是,如果您在查询中需要或有权访问 ts_accepted,则需要提供一个接受的相等过滤器。性能方面,我认为没有问题。

对于 B,极低基数列(如布尔值)上的索引很糟糕。考虑数据是如何存储的——对于每个节点,Cassandra 维护一个表,其中键是值(真/假),值是该节点与键匹配的所有数据的键。这有可能成为一个非常广泛的专栏。如果您要为单独的表格建模,您会这样做吗?不,你也不应该用索引来做这件事。

我不知道其余的数据,但如果您想找到已被接受的朋友,为什么还要使用布尔值呢?您可以使用 ts_accepted 列来推断布尔值。如果它们有值,就会被接受,对吧?

您应该注意的一件事是您不能更新作为 pk 一部分的列。

最后,您正在为查询点击分区键 (UserId)。这对您的查询非常有用。这意味着它将恰好命中一个分区。根据您的用例(和条目的大小),加载整个分区并过滤客户端/应用程序端甚至可能是可行的。当然,这取决于预期的朋友列表大小,以及您需要/愿意做的数据大小、网络流量和应用程序处理。例如,加载 100 个条目并过滤接受的应用端,以及通过过滤 db 端加载 50 个条目可能具有相似的性能数字。

【讨论】:

    【解决方案2】:

    这将为查询提供最佳性能: SELECT * FROM friend_list WHERE userId="---" AND accepted=true;

    架构 (A) 将为您提供更好的查询性能。

    我需要对它进行不必要的排序,因为我必须将 'ts_accepted' 排序为 DESC

    如果首先按“接受”排序的结果顺序不影响您的代码逻辑(记录顺序正确则无需创建索引)

    架构问题 (B)

    在接受的基础上创建索引将创建一个隐藏列族,其 Schema 类似

    CREATE TABLE friend_list_accept_idx (
            accepted boolean,
            userId uuid, 
            ts_accepted timestamp,
            PRIMARY KEY (accepted),userId , ts_accepted)
           );
    

    这对您来说是不必要的维护开销。在 cassandra 中避免使用索引总是好的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-07
      • 2011-07-02
      • 2015-11-09
      • 2023-03-23
      • 2011-03-24
      • 2023-04-08
      • 1970-01-01
      • 2012-05-12
      相关资源
      最近更新 更多