我有一个应用程序,我有多个选择下拉菜单。根据这个函数,我需要从表中获取所有值。
CREATE TABLE generic_keyspace.cust_table (
account_executive text,
certification text,
customer_category text,
customer_name text,
engine_model text,
target_cost_final text,
target_price_final text,
PRIMARY KEY (account_executive, certification, customer_category, customer_name, engine_model)
) WITH CLUSTERING ORDER BY (certification ASC, customer_category ASC, customer_name ASC, engine_model ASC)
这是我的table
SELECT * from cust_table
WHERE customer_name IN ('cust1','cust2')
AND customer_category IN ('cat1','cat2')
ALLOW FILTERING;
当尝试执行此查询时,我收到一个错误
InvalidRequest: Error from server: code=2200 [Invalid query] \
message="IN restrictions are not supported on indexed columns"
我试图从主键中删除列,然后我得到另一个错误
InvalidRequest: Error from server: code=2200 [Invalid query] \
message="IN predicates on non-primary-key columns (customer_name) is not yet supported"
2条答案
按热度按时间7gyucuyw1#
ALLOW FILTERING
是一个创可贴,你不应该在生产Cassandra部署中做。ALLOWFILTERING的唯一推荐用法是当查询限于单个分区时。这里需要考虑一些严肃的数据建模问题。一般的想法是收集所有需要的读查询,然后定义表的数据模型,然后在其上存储数据。
我强烈建议你通过以下免费的基于浏览器的课程,
由于表的主键定义为compound primary key,
其中,
account_executive
是表的 * 分区键 *。certification
、customer_category
、customer_name
和engine_model
是 * 集群键 *。在聚类键内,不能跳过前面的键而使用另一个键。例如,您不能使用像
SELECT ... FROM ... WHERE account_executive = ? AND customer_category = ?;
这样的查询,因为certification
列出现在customer_category
之前。例如,您可以跳过右侧的其他聚类键列。如果你想在读查询上得到最快的响应,你将使用完整的主键作为一个整体,
查询以匹配非主键列是一种反模式,因为查询应始终导致从表中检索到连续的数据片。
可以在非主键列上创建自定义的辅助索引,以帮助提高查询的灵活性。然而,这种技术并不能保证索引的无故障,所以要知道when and when not to use an index。
根据您设计表模型的方式,以下是支持的查询,
SELECT ... FROM cust_table WHERE account_executive = ? AND certification = ? AND customer_category = ? AND customer_name = ? AND engine_model = ?;
--* 更快更高效 *SELECT ... FROM cust_table WHERE account_executive = ? AND certification = ?;
SELECT ... FROM cust_table WHERE account_executive = ? AND certification = ? AND customer_category = ?;
SELECT ... FROM cust_table WHERE account_executive = ? AND certification = ? AND customer_category = ? AND customer_name = ?;
SELECT ... FROM cust_table WHERE account_executive = ?;
你也可以在WHERE子句中执行其他条件,我建议你阅读this CQL WHERE clause understanding blog,它有点旧,但仍然与最近版本的Cassandra®有很多相关性。
cwdobuhd2#
IN()
操作符主要用于筛选分区键以检索多个分区。此外,您只能使用
IN
过滤复合主键的最后一列,前提是前面的所有列都是使用相等(=
)运算符指定的。正如您已经发现的,IN
运算符不能用于索引列。为了说明,我将使用此表作为示例:
IN()
运算符在此表中的有效用法如下:注意,
IN
运算符只用于筛选最后一列--IN
运算符不能用于WHERE
子句的任何前面的列。顺便说一下,看起来您的应用程序需要执行多个查询来检索所需的数据,并试图在共享表上执行这些查询。Cassandra是当您遇到规模问题时的首选数据库,这意味着您需要以超高速检索数据。只有通过为每个应用程序查询设计一个表来优化表的读操作时,才能实现这一点。
因此,如果您有一个根据客户名称进行筛选的应用程序查询,则需要对数据进行建模,以便按该列对表进行分区。举例来说:
如果需要按类别查询,则设计一个按类别分区的表:
作为一般性建议,不鼓励在分区键上使用
IN
操作符,因为协调器需要为列表中的每个项触发单独的读请求。如果必须,请将其使用限制为2到3个项目以获得最佳性能。在集群列上使用
IN
操作符并不成问题,因为查询仅限于单个分区,所以它只对分区内的行进行过滤。干杯!干杯!