cassandra 按二级索引搜索一行 returns null
cassandra search a row by secondary index returns null
我创建了一个TABLE和索引如下
CREATE TABLE refresh_token (
user_id bigint,
refresh_token text,
access_token text,
device_desc text,
device_type text,
expire_time timestamp,
org_id bigint,
PRIMARY KEY (user_id, refresh_token)
) WITH CLUSTERING ORDER BY (refresh_token ASC)
CREATE INDEX i_access_token ON demodb.refresh_token (access_token);
在我插入或删除大约数百万的数据后times.I我发现当我使用以下查询时无法return任何数据。其实数据里有这一行
当我通过 PRIMARY KEY 查询时
select * from refresh_token where user_id=405198 and refresh_token='E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298';
它returns数据:
select * from refresh_token where user_id=405198 and refresh_token='E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298';
user_id | refresh_token | access_token | device_desc | device_type | expire_time | org_id
---------+------------------------------------------------------------------+------------------------------------------------------------------+-------------+-------------+--------------------------+--------------
405198 | E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298 | E82B57D9D64BECDB16D4F3F9F81AC0EF7AF2C4B460CB0F33C9CEFA5846BA7BE1 | null | null | 2016-06-07 14:09:52+0800 | 481036337156
但是当我通过二级索引查询时,它 return 为空。
select * from refresh_token where access_token ='E82B57D9D64BECDB16D4F3F9F81AC0EF7AF2C4B460CB0F33C9CEFA5846BA7BE1';
user_id | refresh_token | access_token | device_desc | device_type | expire_time | org_id
---------+---------------+--------------+-------------+-------------+-------------+--------
谢谢
仅建议对基数较低的字段使用二级索引。您的 access_token 字段看起来具有非常高的基数(甚至可能对所有百万行都是唯一的)。这是 Cassandra 中已知的反模式。
高基数字段适用于分区键之类的内容,因为它们会散列到已知位置。但是二级索引没有散列,而是通过每个节点上的本地数据结构找到的。当有很多不同的值被索引时,这些本地数据结构变得笨重且效率低下。我怀疑您在匹配 access_token 的节点大海捞针之前遇到了内部超时。
如果您需要通过 access_token 查找数据,我建议创建第二个 table,其中 access_token 是分区键并使用它来查找相应的 user_id 和 refresh_token。这样,您将使用 access_token 作为哈希值,并获得可靠且快速的查找。
我创建了一个TABLE和索引如下
CREATE TABLE refresh_token ( user_id bigint, refresh_token text, access_token text, device_desc text, device_type text, expire_time timestamp, org_id bigint, PRIMARY KEY (user_id, refresh_token) ) WITH CLUSTERING ORDER BY (refresh_token ASC) CREATE INDEX i_access_token ON demodb.refresh_token (access_token);
在我插入或删除大约数百万的数据后times.I我发现当我使用以下查询时无法return任何数据。其实数据里有这一行
当我通过 PRIMARY KEY 查询时
select * from refresh_token where user_id=405198 and refresh_token='E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298';
它returns数据:
select * from refresh_token where user_id=405198 and refresh_token='E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298'; user_id | refresh_token | access_token | device_desc | device_type | expire_time | org_id ---------+------------------------------------------------------------------+------------------------------------------------------------------+-------------+-------------+--------------------------+-------------- 405198 | E82B57D9D64BECDBD6B5602A72816BD19016323504F803116F66A32598E04298 | E82B57D9D64BECDB16D4F3F9F81AC0EF7AF2C4B460CB0F33C9CEFA5846BA7BE1 | null | null | 2016-06-07 14:09:52+0800 | 481036337156
但是当我通过二级索引查询时,它 return 为空。
select * from refresh_token where access_token ='E82B57D9D64BECDB16D4F3F9F81AC0EF7AF2C4B460CB0F33C9CEFA5846BA7BE1'; user_id | refresh_token | access_token | device_desc | device_type | expire_time | org_id ---------+---------------+--------------+-------------+-------------+-------------+--------
谢谢
仅建议对基数较低的字段使用二级索引。您的 access_token 字段看起来具有非常高的基数(甚至可能对所有百万行都是唯一的)。这是 Cassandra 中已知的反模式。
高基数字段适用于分区键之类的内容,因为它们会散列到已知位置。但是二级索引没有散列,而是通过每个节点上的本地数据结构找到的。当有很多不同的值被索引时,这些本地数据结构变得笨重且效率低下。我怀疑您在匹配 access_token 的节点大海捞针之前遇到了内部超时。
如果您需要通过 access_token 查找数据,我建议创建第二个 table,其中 access_token 是分区键并使用它来查找相应的 user_id 和 refresh_token。这样,您将使用 access_token 作为哈希值,并获得可靠且快速的查找。