【问题标题】:How to obtain number of rows in Cassandra table如何获取 Cassandra 表中的行数
【发布时间】:2014-12-24 13:19:38
【问题描述】:

这是一个超级基本的问题,但实际上已经困扰我好几天了。有没有一种好方法可以在 Cassandra 中获得与给定表的 COUNT(*) 等效的值?

我会将数亿行移动到 C* 中以进行一些负载测试,并且我希望在通过网络移动大量数据之前至少获得一些示例 ETL 作业的行数。

我最好的想法是基本上用 Python 循环每一行并自动增加一个计数器。有没有更好的方法来确定(甚至估计)C* 表的行大小?我还浏览了 Datastax Ops Center 以查看是否可以确定那里的行大小。如果可以的话,我看不出这怎么可能。

还有其他人需要在 C* 中获取表的 count(*) 吗?如果是这样,你是怎么做的?

【问题讨论】:

标签: cassandra cassandra-2.0 datastax


【解决方案1】:

是的,您可以使用COUNT(*)。这是documentation

使用 COUNT(*) 的 SELECT 表达式返回匹配查询的行数。或者,您可以使用 COUNT(1) 来获得相同的结果。

统计用户表中的行数:

SELECT COUNT(*) FROM users;

【讨论】:

  • 我很想知道您的计数需要多长时间。也许你可以回来报告。 :)
  • 轮到你了。我们都变成了白痴。我的明天就到了。等不及了。
  • 就基准测试而言,现在我正在运行一个带有 SSD 和 32 GB 内存的 5 节点集群。对于一百万行,返回该计数 * 大约需要一分半钟。我有很多调整和微调要做。但就目前的情况而言,“直接开箱即用”,如果你愿意的话,它肯定有点慢。
  • 所以这似乎又回到了关系后的口头禅——为您的查询而设计。创建一个保留计数器的表,并在添加行时增加计数。然后查询将很快返回。我希望它大约是几毫秒。
  • 如果我需要经常对我的表执行 count(*)s,我当然同意你的看法。这只是健全性检查和控制总数。 “我给它发了一百万条记录……它们都到了吗?”那种东西
【解决方案2】:

如果您不需要精确计数,您也可以从 nodetool cfhistograms 获得一些估计值(这些值是估计值)。

如果您正在运行 DSE,您也可以使用 spark。

【讨论】:

  • 如何使用 Spark 加快计数速度?例如,我有大约十亿条记录,我正在使用 spark 来计算行数。我花了 1 小时 30 分钟才完成它。这里有更多细节stackoverflow.com/questions/40778936/…
  • 现在没有cfhistograms 选项,tablehistograms 在行数方面似乎没有提供太多有用的信息。
  • cfhistograms 和 tablehistograms 是一回事,就像我说的你得到一些一般的估计,而不是严格的计数。
【解决方案3】:

nodetool tablestats 可以非常方便地快速获取行估计(和其他表统计信息)。

nodetool tablestats <keyspace.table> 用于特定表

【讨论】:

  • 我没有看到使用 tablestats 的估计计数,COPY 似乎是一个不错的选择,但对于较大的表(磁盘上剩余的可用存储空间较少),管理空间有点困难。还有什么办法吗??
  • 我相信最初我认为“键数”就足够了,但我现在看到它指的是分区键。如果您知道列大小,您可以尝试使用 Memtable Cell Count。 docs.datastax.com/en/archived/cassandra/3.0/cassandra/tools/…
  • 我在nodetool tablestats下看不到行估计
【解决方案4】:

nodetool cfstats | grep -A 1000 KEYSPACE

替换 KEYSPACE 以获取该 KEYSPACE 中所有表的详细信息

【讨论】:

    【解决方案5】:

    您可以使用复制来避免 cassandra 超时通常发生在 count(*)

    cqlsh -e "copy keyspace.table_name (first_partition_key_name) to '/dev/null'" | sed -n 5p | sed 's/ .*//'

    【讨论】:

    • 不错!这很有帮助
    • @shubham 你能解释一下代码吗?这段代码在做什么。有没有副作用?
    【解决方案6】:

    对于那些使用 C# Linq 组件适配器的用户,您可以使用:

    var t = new Table<T>(session);
    var count = t.Count().Execute();
    

    【讨论】:

    • 什么是java驱动的等价物?你知道吗?
    【解决方案7】:
    $nodetool settimeout read 360000
    cqlsh -e "SELECT COUNT(*) FROM table;" --request-timeout=3600
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
    【解决方案8】:

    我一直在使用 Elasticsearch,这可以解决这个问题...假设您愿意使用 Elassandra 而不是 Cassandra。

    搜索系统会维护许多统计信息,并且在最后一次更新后的几秒钟内,它应该可以很好地了解您在一个表中有多少行。

    这是一个Match All Query 请求,它为您提供信息:

    curl -XGET \
         -H 'Content-Type: application/json' \
         "http://127.0.0.1:9200/<search-keyspace>/_search/?pretty=true" \
         -d '{ "size": 1, "query": { "match_all": {} } }'
    

    &lt;search-keyspace&gt; 是 Elassandra 创建的键空间。它通常被命名为&lt;keyspace&gt;_&lt;table&gt;,因此如果您有一个名为foo 的键空间和一个名为bar 的表,则该URL 将使用.../foo_bar/...。如果您想获取所有表中的总行数,则只需使用/_search/

    输出是一个如下所示的 JSON:

    {
      "took" : 124,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 519659,                <-- this is your number
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "foo_bar",
            "_type" : "content",
            "_id" : "cda683e5-d5c7-4769-8e2c-d0a30eca1284",
            "_score" : 1.0,
            "_source" : {
              "date" : "2018-12-29T00:06:27.710Z",
              "key" : "cda683e5-d5c7-4769-8e2c-d0a30eca1284"
            }
          }
        ]
      }
    }
    

    就速度而言,无论行数如何,这都需要几毫秒。我有数百万行的表格,它就像一个魅力。无需等待数小时或类似的时间。

    正如其他人所提到的,Elassandra 仍然是许多计算机大量并行使用的系统。如果您一直有很多更新,计数器将迅速变化。因此,只有当您阻止进一步更新足够长的时间以使计数器结算时,您从 Elasticsearch 获得的数字才是正确的。否则它总是一个近似的结果。

    【讨论】:

      【解决方案9】:

      对于大表的count(*),您可以在 Cassandra 之上使用 Presto。我已经测试过了,效果很好。

      请参考以下网址: 关键词搜索:Cassandra question v3.11.3 ...

      select count(*) from table1
      

      网址:Cassandra question v3.11.3 ... select count(*) from table1

      【讨论】:

        【解决方案10】:

        您可以使用dsbulk count 来检索表的总数。我在上面提到的所有命令中都遇到了读取超时,最后能够使用下面的命令获得计数

        例如,

        dsbulk count -k &lt;keyspace_name&gt; -t &lt;table_name&gt;

        关于 dsbulk 的更多信息可以找到here

        【讨论】:

        • 很好的提示!这非常有帮助!
        【解决方案11】:

        考虑对列约束使用 ALLOW FILTERING,然后对值求和。

        例如:

        SELECT count(*)
        FROM my_table
        WHERE datetime_id >= '2020-09-16' ALLOW FILTERING;
        
        SELECT count(*)
        FROM my_table
        WHERE datetime_id < '2020-09-16' ALLOW FILTERING;
        

        【讨论】:

        • 请不要这样做 - 你会杀死你的集群,否则它会超时
        猜你喜欢
        • 2014-03-03
        • 2016-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多