キーとして(user_id、timestamp)を持つカラムファミリを使用する必要があります。私のクエリでは、user_idに関係なく、指定された時間範囲内のすべてのレコードを取得します。これは正確なテーブルスキーマです。
CREATE TABLE userlog (
user_id text,
ts timestamp,
action text,
app_type text,
channel_name text,
channel_session_id text,
pid text,
region_id text,
PRIMARY KEY (user_id, ts)
)
走ってみた
SELECT * FROM userlog WHERE ts >= '2013-01-01 00:00:00+0200' AND ts <= '2013-08-13 23:59:00+0200' ALLOW FILTERING;
これは、ローカルのcassandra小さなデータセットを含むインストールで正常に動作しますが、
Request did not complete within rpc_timeout.
すべてのデータを含む本稼動システム上。
与えられた列ファミリでスムーズに実行される、できればcqlクエリがありますか、それとも設計を変更する必要がありますか?
タイムアウトは、Cassandraがデータを返すのにタイムアウト(デフォルトは10秒)より長くかかっているためです。クエリの場合、Cassandraは、返される前にデータセット全体。複数のレコードの場合、これはタイムアウトよりも簡単に長くかかる可能性があります。
大量のデータを生成するクエリの場合、ページングする必要があります。
SELECT * FROM userlog WHERE ts >= '2013-01-01 00:00:00+0200' AND ts <= '2013-08-13 23:59:00+0200' AND token(user_id) > previous_token LIMIT 100 ALLOW FILTERING;
ここで、user_id
は、以前に返されたuser_idです。また、最後に返されたuser_idのすべてのレコードを確実に取得するために、tsをページングする必要があります。
または、Cassandra 2.0.0(リリース直後))では、ページングは透過的に行われるため、タイムアウトや手動ページングなしで元のクエリが機能します。
ALLOW FILTERING
は、Cassandraはすべてのデータを読み取りますが、指定された範囲内のデータのみを返します。これは、範囲がデータのほとんどである場合にのみ効率的です。 5分の時間枠では、これは非常に非効率的です。
hotness は、時間(または任意の範囲)で照会できるため、パーティションキーとして「その他の列」を指定し、次に「クラスタリング列」としてタイムスタンプを指定するように見えます
CREATE TABLE postsbyuser (
userid bigint,
posttime timestamp,
postid uuid,
postcontent text,
PRIMARY KEY ((userid), posttime)
) WITH CLUSTERING ORDER BY (posttime DESC);
偽のデータを挿入する
insert into postsbyuser (userid, posttime) values (77, '2013-04-03 07:04:00');
およびクエリ(重要な部分は、「高速」クエリであり、ALLOW FILTERING
は必須ではありません。これはどのようにすべきかです:
SELECT * FROM postsbyuser where userid=77 and posttime > '2013-04-03 07:03:00' and posttime < '2013-04-03 08:04:00';
また、トリックを使用して 日ごとにグループ化 (したがって、日ごとにクエリを実行できる)またはそうでないこともできます。
「グループ化」スタイルのトリックを使用する場合、セカンダリインデックスもオプションになります(セカンダリインデックスは「EQ」でのみ機能するようです=
演算子?)。
一般に、これは、データクエリに合わせてスキーマをモデル化していないことを示している可能性があります。これは、Cassandra物事の実行方法です( https:// docs。 datastax.com/en/cql/3.3/cql/ddl/dataModelingApproach.html )...
そのため、理想的には、クエリに合わせてスキーマをモデル化します。 Cassandraの時系列モデリングを行う方法に関するリソースがいくつかありますが、 このスライド共有 は、あなたが持っているものと似ているように見えます-しかし、それはあなたがしたい種類のクエリに対する広告のサポートではありません。 「特定の時間範囲のすべてのデータを取得する」クエリをサポートするCassandra=スキーマの例を実際に見つけたとは思わない。
いずれにせよ、この回答の残りの部分では、この反復で得たスキーマに固執していると仮定します。
これは2つのクエリとして実行できます。
SELECT DISTINCT user_id FROM userlog;
そして、各ユーザーに対して、
SELECT * FROM userlog WHERE
user_id='<user>'
AND ts >= '2013-01-01 00:00:00+0200'
AND ts <= '2013-08-13 23:59:00+0200';
ユーザーIDのセットが小規模から中規模の場合、IN
クエリを使用して回避できる場合があります。
SELECT * FROM userlog WHERE
user_id IN ('sampleuser', 'sampleadmin', ...)
AND ts >= '2013-01-01 00:00:00+0200'
AND ts <= '2013-08-13 23:59:00+0200';
これが機能することに注意してくださいwithoutALLOW FILTERING
。