这是一个非常基本的问题,但它实际上已经困扰我好几天了。有没有一种好方法可以获取 Cassandra 中给定表的
COUNT(*)
的等价物?
我将把数亿行移动到 C* 中进行一些负载测试,并且在通过网络移动大量数据之前,我希望至少获得一些示例 ETL 作业的行计数。
我最好的想法是基本上用 Python 循环每一行并自动递增计数器。有没有更好的方法来确定(甚至估计)C* 表的行大小?我还浏览了 Datastax Ops Center,看看是否可以确定那里的行大小。如果可以的话,我不明白这怎么可能。
还有其他人需要获得 C* 中的表的
count(*)
吗?如果是这样,你是怎么做的?
是的,您可以使用
COUNT(*)
。这是文档。
使用 COUNT(*) 的 SELECT 表达式返回与查询匹配的行数。或者,您可以使用 COUNT(1) 来获得相同的结果。
统计users表的行数:
SELECT COUNT(*) FROM users;
您可以使用复制来避免 cassandra 超时通常发生在 count(*) 上
cqlsh -e "copy keyspace.table_name (first_partition_key_name) to '/dev/null'" | sed -n 5p | sed 's/ .*//'
nodetool tablestats
对于快速获取行估计(和其他表统计信息)非常方便。
nodetool tablestats <keyspace.table>
对于特定表格
您可以使用
dsbulk count
来检索表的总数。我在读取超时的情况下处理了上述所有命令,最后能够使用下面的命令获取计数
例如,
dsbulk count -k <keyspace_name> -t <table_name>
有关 dsbulk 的更多信息可以在这里
找到如果您不需要精确的计数,您还可以从
nodetool cfhistograms
获得一些估计值(这些值是估计值)。
如果您正在运行 DSE,也可以使用 Spark。
$nodetool settimeout read 360000
cqlsh -e "SELECT COUNT(*) FROM table;" --request-timeout=3600
我一直在使用 Elasticsearch,这可以解决这个问题...假设您愿意使用 Elassandra 而不是 Cassandra。
搜索系统维护许多统计数据,在最后一次更新后的几秒钟内,它应该很好地了解表中有多少行。
这是一个“匹配所有查询”请求,可为您提供信息:
curl -XGET \
-H 'Content-Type: application/json' \
"http://127.0.0.1:9200/<search-keyspace>/_search/?pretty=true" \
-d '{ "size": 1, "query": { "match_all": {} } }'
其中
<search-keyspace>
是 Elassandra 创建的键空间。它通常被命名为类似
<keyspace>_<table>
的名称,因此如果您有一个名为 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 获得的数字才是正确的。否则它总是一个近似结果。
var t = new Table<T>(session);
var count = t.Count().Execute();
例如:
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;
替换
KEYSPACE
以获取该
KEYSPACE
中所有表的详细信息。