フリート管理ソリューションのデータヒストリアンとしてCassandraを使用しています。Cassandraにテーブルがあり、車両が行った移動の詳細を保存します。テーブル構造は以下の通りです
CREATE TABLE journeydetails(
bucketid text,
vehicleid text,
starttime timestamp,
stoptime timestamp,
travelduration bigint,
PRIMARY KEY (bucketid,vehicleid,starttime,travelduration)
);
どこ:
次のクエリを実行します-2015-12-1から2015-12-3までの車両のすべての移動量を取得します(移動時間が30分を超える)
このクエリを実行すると:
select * from journeydetails where bucketid in('2015-12') and vehicleid in('1234567')
and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59'
and travelduration > 1800000;
私はこの結果を得ます:
InvalidRequest: code=2200 [Invalid query] message="Clustering column "travelduration"
cannot be restricted (preceding column "starttime" is restricted by a non-EQ relation)
この問題を修正する方法についてのアドバイスはありますか?
select * from journeydetails where bucketid in('2015-12') and vehicleid in('1234567')
and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59'
and travelduration > 1800000;
それはうまくいきません。理由は、Cassandraがデータをディスクに保存する方法に戻ります。Cassandraのアイデアは、正確なキーで単一の行を返す際に非常に効率的であることです、またはディスクから連続した範囲の行を返すとき。
行はbucketid
で分割され、vehicleid
、starttime
、およびtravelduration
でディスク上に並べ替えられます。 starttime
で既に範囲クエリ(非EQリレーション)を実行しているため、後続のキーを制限することはできません。これは、travelduration
制限により、範囲条件の一部の行が不適格になる可能性があるためです。これにより、非効率的な非連続的な読み取りが発生します。 Cassandraは、予測できないパフォーマンスをもたらす可能性のあるクエリ(このような)を記述しないように設計されています。
2つの選択肢があります。
1- travelduration
より前のすべてのキー列を(等しい関係で)制限できる場合は、大なり条件を適用できます。
select * from journeydetails where bucketid='2015-12' and vehicleid='1234567'
and starttime='2015-12-1 00:00:00' and travelduration > 1800000;
もちろん、正確なstarttime
を制限することは、あまり役に立たないかもしれません。
2-もう1つの方法は、travelduration
を完全に省略して、元のクエリが機能するようにすることです。
select * from journeydetails where bucketid='2015-12' and vehicleid='1234567'
and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59';
残念ながら、Cassandraはクエリの柔軟性をあまり提供していません。このレベルのレポートを実現するために Spark (Cassandraと一緒に)などのソリューションを使用して成功を収めた人がたくさんいます。
そして、余談ですが、必要がない限りIN
を使用しないでください。 IN
を使用したクエリは、セカンダリインデックスを使用する場合と同様です。つまり、Cassandraは、クエリを満たすために複数のノードと通信する必要があります。単一のアイテムを使用して呼び出すことも、おそらくそうではありません。しかし、IN
は、Cassandraに深く入り込む前に実際に破るべき、古いRDBMSの習慣の1つです。