卡桑德拉CQLEngine允许过滤(Cassandra CQLEngine Allow Filter

2019-09-29 09:17发布

我使用Python卡桑德拉Cqlengine扩展。 我创造了许多对多表,但我收到错误user_applications模型查询过滤过程。 我readed不同的资源对于这个问题,但我没有完全理解这个问题。

来源: https://ohioedge.com/2017/07/05/cassandra-primary-key-partitioning-key-clustering-key-a-simple-explanation/

卡桑德拉允许过滤

被允许卡桑德拉滤波下面的查询效率?

数据库模型:

class UserApplications(BaseModel):
    __table_name__ = "user_applications"

    user_id = columns.UUID(required=True, primary_key=True, index=True)
    application_id = columns.UUID(required=True, primary_key=True, index=True)
    membership_id = columns.UUID(required=True, primary_key=True, index=True)

错误信息:

无法执行此查询,因为可能涉及数据过滤,因此可能具有不可预知的性能。 如果你想,尽管性能不可预测性来执行这个查询,使用允许过滤的”

Python的CQLEngine代码:

q = UserApplications.filter(membership_id=r.membership_id,
                                    user_id=r.user_id,
                                    application_id=r.application_id)

CQLEngine SQL语句:

SELECT "id", "status", "created_date", "update_date" FROM db.user_applications WHERE "membership_id" = %(0)s AND "user_id" = %(1)s AND "application_id" = %(2)s LIMIT 10000

说明表结果:

CREATE TABLE db.user_applications (
    id uuid,
    user_id uuid,
    application_id uuid,
    membership_id uuid,
    created_date timestamp,
    status int,
    update_date timestamp,
    PRIMARY KEY (id, user_id, application_id, membership_id)
) WITH CLUSTERING ORDER BY (user_id ASC, application_id ASC, membership_id ASC)
    AND bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';
CREATE INDEX user_applications_membership_id_idx ON db.user_applications (membership_id);

等待您的帮助。

Answer 1:

您收到此错误的原因是,您不添加ALLOW FILTERING标志来查询,如果添加ALLOW FILTERING ,以您的查询的末尾它应该工作。

使用ALLOW FILTERING在卡桑德拉实际查询允许卡桑德拉到它们加载后过滤掉一些行(加载后可能从表中的所有行)。 例如,在您的查询的情况下卡桑德拉可以执行这个查询的唯一途径是通过检索所有从表UserApplications行,然后过滤掉不具有对每个被限制列的要求值的人。

使用ALLOW FILTERING能有不可预知的性能结果和实际性能取决于你的表里面的数据分布。 如果你的表中包含例如100万行,其中95%的请求的值的列,您将可以指定查询依然会比较有效,你应该使用允许过滤的。 在另一方面,如果你的表中包含一个百万行,只有2行包含所请求的值,你的查询是非常低效的。 卡桑德拉将加载999,998行白白。 一般来说,如果你的查询需要添加ALLOW FILTERING那么很可能你应该重新考虑你的架构或添加辅助索引为您所查询往往列。

在你的情况我建议作出membership_id,USER_ID列,APPLICATION_ID作为复合分区键。 如果你这样做,你将不再需要加载后,任何行过滤掉,因为有三个列中的值相同的所有行会驻留在同一分区(在同一物理节点),你应该在提供三个值查询(你已经这样做在你的问题中新增了查询)。 这里是你可以做这样的方式:

CREATE TABLE db.user_applications (
    user_id uuid,
    application_id uuid,
    membership_id uuid,
    created_date timestamp,
    status int,
    update_date timestamp,
    PRIMARY KEY ((user_id, application_id, membership_id))
);


文章来源: Cassandra CQLEngine Allow Filtering