2016-08-30 27 views
4
CREATE TABLE test (
    type text, 
    scope text, 
    name text, 
    version text, 
    alias text, 
    deleted boolean, 
    PRIMARY KEY ((type, scope, name), version) 
) WITH read_repair_chance = 0.0 
    AND dclocal_read_repair_chance = 0.1 
    AND gc_grace_seconds = 864000 
    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', 'min_threshold' : 4, 'max_threshold' : 32 } 
    AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' } 
    AND default_time_to_live = 0 
    AND speculative_retry = '99.0PERCENTILE' 
    AND min_index_interval = 128 
    AND max_index_interval = 2048; 
CREATE INDEX test_alias ON test (alias); 
CREATE INDEX test_type_index ON test (type); 

此選擇不起作用:與低基數列選擇:在受限的列中沒有二級索引支持爲運營商提供

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name' 
    and deleted = false 
allow filtering; 

,給我:

No secondary indexes on the restricted columns support the provided operators: com.datastax.driver.core.exceptions.InvalidQueryException: No secondary indexes on the restricted columns support the provided operators.

此選擇作品:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and deleted = false 
allow filtering; 

這種選擇也適用:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name' 
allow filtering; 

這種選擇也適用:

select * 
from test 
where type = 'type' 
    and scope='scope' 
    and name='name' 
    and version='version' 
allow filtering; 

任何想法?我不想在低基數列上創建索引,但我不明白爲什麼在某些情況下該查詢有效(當我通過主鍵和附加字段刪除兩個字段進行篩選時)。

卡桑德拉版本:2.1.14

如果我的理解是正確的,有沒有可能在查詢中使用條件與複合分區鍵和其他領域內的共同所有的鍵。但我沒有找到任何解釋......

+1

你的cassandra版本是什麼? –

+0

專業提示:需要允許篩選和/或二級索引的查詢不會擴展。構建您的表以適應您的查詢,並且此問題消失。 – Aaron

+0

Cassandra版本:2.1.14 –

回答

2

無論需要查詢什麼(WHERE子句的一部分)需要作爲主鍵或單獨索引的一部分進行索引。

對於組合鍵,需要包含鍵的最左邊部分才能在鍵的最右邊部分進行搜索。

例如,如果組合鍵是(type, scope, name, deleted)並且想要在deleted上查詢,則需要提供type, scope, name。要查詢name需要供應至少type, scope等。

deleted作爲密鑰的倒數第二部分使其可以進行搜索,而無需額外的額外開銷,因爲刪除的基數較低,所以會產生額外的索引並且效率較高(或沒有)。

CREATE TABLE test (
    type text, 
    scope text, 
    name text, 
    version text, 
    alias text, 
    deleted boolean, 
    PRIMARY KEY (type, scope, name, deleted, version) 
); 
select * from test 
    where type = 'type' 
     and scope='scope' 
     and name='name' 
     and deleted = false; 

select * from test 
    where type = 'type' 
    and scope='scope' 
    and name='name' 
    and version='version' 
    and deleted in (true,false); 

注意去除雙and type='type'的,包含的所有可能的值刪除,以能夠在允許過濾(不能很好地執行)的版本,並去除搜索。

一般情況下,制定一個適合您的查詢的模式。首先想一想'我該怎麼去查詢這個',以幫助你決定把什麼放在主鍵上,以什麼順序。忘記關係數據庫語義,它們不適用。

+0

「(...)不管需要查詢什麼(作爲WHERE子句的一部分),都需要作爲主鍵或單獨索引的一部分進行索引(...)」但是正如你在我的例子看到我沒有索引刪除列和第二個查詢工作... –

+0

它'工作',只要允許過濾啓用,當然。查詢部分在密鑰的索引部分完成,其結果在刪除時被過濾。它自己的查詢並未使用作爲其搜索的一部分被刪除。 – danny

+0

好的,爲什麼第一個查詢不起作用? –