CQL3のCassandra 2.0のSELECT ... WHEREクエリ

Cassandra(以降、 C * )は、その内部構造によりWHEREリクエストを制限します。 C *の仕組みを説明したサイクルの最初の記事を読んでいないと、この記事は複雑で混乱しているように見えます。 これを進める前にそれを読んでください。

この記事の目的は、C *初心者向けのリファレンスとして機能することです。

CQLとSQLのいくつかの違い


Cassandraクエリ言語( CQL )のSELECTクエリには、通常のSQL JOINGROUP BY操作がありません。 また、 WHERE操作は大幅に切り捨てられます。 SQLでは、任意の列でフィルタリングできますが、CQLでは、 パーティションキークラスタリング 列、およびセカンダリインデックスでのみフィルタリングできます
注:C * 2.0では、SQLインデックスなどの任意の列に対してセカンダリINDEXを作成できます。 実際、セカンダリKassandraインデックスは、ユーザーから隠された追加のテーブルです。したがって、それらに対するWHEREクエリのパフォーマンスは、キー列に対するクエリよりも劣ります。


免責事項


 CREATE TABLE ad_click ( reseller_id text, day text, -- day in the format of 'YYYY-MM-DD' time timestamp, ad_id text, amount float, PRIMARY KEY ((reseller_id, day), time, ad_id) --   (reseller_id,day)    (time,ad_id) ) WITH CLUSTERING ORDER BY (time DESC); 


WHEREを使用したデータのフィルタリング


大まかに言って、「ろ過」という言葉はここでは不適切です。 検索と言う方が正確です。 C *はほとんどフィルタリングを許可しません。

WHEREリクエストは、文字列が保存されているノードを見つけてそこにリクエストを渡すようにCassandraに指示します。

列を互いに比較する

JOINがないため、列を互いに比較することはできません。
 SELECT * from ad_click WHERE maxTimeuuid(day) = maxTimeuuid(3141592653589); -- ; 


および、または

WHEREクエリの複数の条件はOR演算子と組み合わせることはできず、 ANDのみが機能します。 また、動作する比較演算子はごくわずかであり、常にそうとは限りません。

平等=

等号演算子(=)の使用はほぼ無制限です。 キー列とインデックス列に制限されています。 また、次のキー列を比較する前に、前のすべてのキー列を比較する必要があります。

正しく:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND -- OK day = '2013-11-29' AND -- OK time = 3141592653589 AND -- OK ad_id = '890_567_234'; -- OK 

間違った:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND amount = 0; -- !    . SELECT * FROM ad_click WHERE day = '2013-11-29' AND -- !    reseller_id. time = 3141592653589 AND ad_id = '890_567_234'; SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND ad_id = '890_567_234'; -- !    time. 


インクルージョンIN

包含演算子(IN)の使用は、分散キーの最後の列とクラスターキーの最後の列に制限されています。

正しく:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day IN ('2013-11-28', '2013-11-29') AND -- OK time = 3141592653589 AND ad_id IN ('890_567_234', '890_567_010'); -- OK 

間違った:
 SELECT * FROM ad_click WHERE reseller_id IN ('supaboobs') AND -- !      . day = '2013-11-28' AND time = 3141592653589 AND ad_id = '890_567_234'; SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-28' AND time IN (3141592653589) AND -- !      . ad_id = ('890_567_234'); 


比較演算子= >> = << =


比較構文

列名は比較演算子の左側に、値は右側になければなりません。
正しく:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND -- OK day = '2013-11-29'; -- OK 

間違った:
 SELECT * FROM ad_click WHERE 'supaboobs' = reseller_id AND -- !    . '2013-11-29' = day AND -- !    . 3141592653589 < time; -- !    . 


比較機能

CQLクエリの最後の列で使用でき、列は排他的にクラスタ化する必要があります。

正しく:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time >= 3141592653589; -- OK SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time = 3141592653589 AND ad_id > '890_567_234'; -- OK 

間違った:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time >= 3141592653589 AND -- !     . ad_id = '890_567_234'; SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time >= 3141592653589 AND ad_id < '890_567_234'; -- !     . SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND ad_id < '890_567_234'; -- !     time. SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day < '2013-11-29'; -- !    . 


回避策-フィルタリングを許可する

配布キーを指定することはできませんが、クラスターのキーのみを残して、リクエストの最後にALLOW FILTERINGします。 他のすべての制限が適用されます。
重要! この場合のタイムアウトは、すべてのノードをすべての線に沿って通過するため、非常に可能性が高くなります。


正しく:
 SELECT * FROM ad_click WHERE time = 3141592653589 AND -- OK ad_id > '890_567_234' -- OK ALLOW FILTERING; SELECT * FROM ad_click WHERE time >= 3141592653589 AND -- OK time <= 3141592653589 -- OK ALLOW FILTERING; 

間違った:
 SELECT * FROM ad_click WHERE time >= 3141592653589 AND ad_id > '890_567_234' -- !    . ALLOW FILTERING; SELECT * FROM ad_click WHERE time >= 3141592653589 AND time <= 3241592653589 AND ad_id = '890_567_234' -- !     . ALLOW FILTERING; 


二次インデックス

セカンダリインデックスは等価演算子のみをサポートします。それだけです。 セカンダリインデックスの要求は、他のキーの有無にかかわらず実行できます。

セカンダリインデックスを作成するには、次のコマンドを実行する必要があります。
 CREATE INDEX on ad_click (amount); 


正しく:
 SELECT * FROM ad_click WHERE amount = 0.0075; -- OK SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time = 3141592653589 AND ad_id = '890_567_234' AND amount = 0.0075; -- OK 

間違った:
 SELECT * FROM ad_click WHERE reseller_id = 'supaboobs' AND day = '2013-11-29' AND time = 3141592653589 AND ad_id = '890_567_234' AND amount > 0.0; -- !       . 


おわりに


「なぜSELECTが機能しないのか」という質問がなくなることを願っています。

ソース




サイクルの前の記事

Source: https://habr.com/ru/post/J205176/


All Articles