我在users
数据库上创建了TABLE
Cassandra 2.0.9
的最小示例。我可以使用SELECT来选择它的所有行,但我不明白为什么添加我的WHERE
子句(在索引的collumn上)返回0行。
(我也不明白为什么'COINTAINS'声明在这里引起错误,如下所示,但我们假设这不是我主要关注的问题。)
DROP TABLE IF EXISTS users;
CREATE TABLE users
(
KEY varchar PRIMARY KEY,
password varchar,
gender varchar,
session_token varchar,
state varchar,
birth_year bigint
);
INSERT INTO users (KEY, gender, password) VALUES ('jessie', 'f', 'avlrenfls');
INSERT INTO users (KEY, gender, password) VALUES ('kate', 'f', '897q7rggg');
INSERT INTO users (KEY, gender, password) VALUES ('mike', 'm', 'mike123');
CREATE INDEX ON users (gender);
DESCRIBE TABLE users;
输出:
CREATE TABLE users (
key text,
birth_year bigint,
gender text,
password text,
session_token text,
state text,
PRIMARY KEY ((key))
) WITH
bloom_filter_fp_chance=0.010000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.100000 AND
gc_grace_seconds=864000 AND
index_interval=128 AND
read_repair_chance=0.000000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
default_time_to_live=0 AND
speculative_retry='99.0PERCENTILE' AND
memtable_flush_period_in_ms=0 AND
compaction={'class': 'SizeTieredCompactionStrategy'} AND
compression={'sstable_compression': 'LZ4Compressor'};
CREATE INDEX users_gender_idx ON users (gender);
此SELECT
可以正常使用
SELECT * FROM users;
key | birth_year | gender | password | session_token | state
--------+------------+--------+-----------+---------------+-------
kate | null | f | 897q7rggg | null | null
jessie | null | f | avlrenfls | null | null
mike | null | m | mike123 | null | null
这不是:
SELECT * FROM users WHERE gender = 'f';
(0 rows)
这也失败了:
SELECT * FROM users WHERE gender CONTAINS 'f';
Bad Request: line 1:33 no viable alternative at input 'CONTAINS'
答案 0 :(得分:2)
听起来你的索引可能已经腐败了。尝试重建它。从命令提示符运行:
nodetool rebuild_index yourKeyspaceName users users_gender_idx
然而,这里更大的问题是已知二级索引表现不佳。 Some甚至已将其用作反模式。 DataStax有一个document designed to guide you in appropriate use of secondary indexes。这绝对不是其中之一。
在极低基数列上创建索引,例如布尔列,没有意义。索引中的每个值都成为索引中的一行,例如,所有错误值都会产生一个巨大的行。索引具有foo = true和foo = false的多个索引列是没有用的。
虽然性别可能不是布尔列,但它具有相同的基数。此列上的二级索引是一个糟糕的主意。
如果按性别查询是您真正需要做的事情,那么您可能需要找到一种不同的方式来建模或分区数据。例如,PRIMARY KEY (state, gender, key)
将允许您按州查询性别。
SELECT * FROM users WHERE state='WI' and gender='f';
这将使所有来自威斯康星州的女性用户回归。当然,这意味着您还必须单独查询所有状态。但最重要的是,Cassandra不能很好地处理低基数键/索引的查询,所以你必须在如何解决这些类型的问题方面发挥创意。