cassandra查詢效率探討

chenatu發表於2016-07-03

cassandra查詢效率探討

cassandra目前提倡的建表與查詢方式為CQL方式,傳統的cassandra-cli相關的api由於效能問題將逐步淘汰,而cassandra-cli也將在2.2版本之後被淘汰。

在CQL中,可以利用類似SQL的方式建立資料表,例如:

CREATE TABLE monitor (
    id bigint,
    value text,
    num int,
    timestamp timestamp,
    PRIMARY KEY (id, timestamp ));

其中id與timestamp共同構成了primary key。primary key可以不止一個欄位,大於一個欄位的可以構成clustering key。其中在primary key中第一個欄位為partition key,用來決定row在整個ring中的分佈。後面的欄位為clustering key,對於同一個partition key所代表的行,是根據clustering key以一定順序在物理上相鄰儲存的。所以根據partition key以及clustering key進行聯合查詢速度會比較快。cassandra對於如下查詢效率比較高

select * from monitor WHERE id = 1;
select * from monitor WHERE id = 2 AND timestamp = '2015-12-01 12:00:00+0800';
select * from monitor WHERE id = 2 AND timestamp > '2015-12-01 12:00:00+0800' AND timestamp < '2015-12-01 23:00:00+0800';

但是對於下面的查詢,cassandra會返回InvalidRequest: code=2200 [Invalid query] message="Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING"

select * from monitor WHERE timestamp = '2015-12-01 12:00:00+0800';

其原因為是cassandra認為這查詢效率比較低下,需要使用者顯式地增加ALLOW FILTERING修飾。這種查詢過程是先獲取所有行,然後在根據timestamp = '2015-12-01 12:00:00+0800'進行過濾,效率自然比較低。

解決的辦法通常有在timestamp欄位上建立所以。但不能簡單地將cassandra建立索引的機制與普通的關係型資料庫如mysql劃等號。通過primary key查詢,可以通過ring的資訊很快的定位到具體的節點。但是通過index查詢欄位的話,cassandra會每個節點進行查詢。雖然節點內部也會對本地資料進行索引,但是效率還是遠不如直接查詢primary key快。此外cassandra並不能夠對於timestamp >'2015-12-01 12:00:00+0800'這種範圍條件進行查詢。所以更好的方式是另外建立一個表,將需要查詢的欄位作為主鍵,並儲存對應關係。

參考資料

  1. ALLOW FILTERING explained

  2. A deep look at the CQL WHERE clause

  3. When to use an index

相關文章