Indeks pada Tabel Apache Cassandra

M. Ramadhan
Telematika
Published in
5 min readApr 6, 2020

Tulisan kali ini akan membahas tentang indeks, kapan sebaiknya menggunakan indeks dan kapan sebaiknya tidak menggunakan indeks. Akan dibahas pula bagaimana:
• membuat indeks menggunakan pernyataan CREATE INDEX
• menghapus indeks menggunakan pernyataan DROP INDEX

Pendahuluan

Indeks menyediakan sarana untuk mengakses data di Cassandra menggunakan atribut selain kolom primary key. Keuntungannya adalah, pada kondisi yang tepat, pemrosesan query dapat dilakukan dengan cepat dan efisien. Indeks disimpan dalam tabel terpisah dan tersembunyi dari tabel yang berisi nilai yang diindeks. Indeks dapat digunakan untuk semua kolom, termasuk kolom koleksi, yaitu LIST, MAP, SET, kecuali kolom COUNTER dan kolom STATIC.

Indeks sangat baik dilakukan pada kolom yang memiliki banyak data ganda pada suatu tabel yang memiliki banyak baris. Misalnya, tabel penduduk berisi dua ratusan juta baris, akan dicacah jumlah penduduk per provinsi. Data penduduk akan terbagi ke 30-an provinsi. Kolom provinsi — memiliki sangat banyak data ganda — sangat layak untuk diindeks.

Jangan gunakan indeks pada situasi berikut:

  • kolom yang memiliki banyak nilai berbeda, query pada baris data yang sangat besar untuk sedikit hasil.
  • tabel yang menggunakan kolom COUNTER.
  • kolom yang nilainya sering diubah dan atau dihapus.

Membuat Indeks

Indeks dibuat dengan menggunakan pernyataan CREATE INDEX. Berikut adalah diagram sintaksnya.

  • Jika indeks dengan nama yang sama sudah ada, muncul pesan kesalahan dan operasi gagal. Gunakan klausa IF NOT EXIST untuk meniadakan pesan kesalahan.
  • nama_indeks boleh diabaikan.
  • nama_keyspace adalah keyspace yang berisi tabel yang akan diindeks kolomnya. Tidak diperlukan jika keyspace telah ditentukan dengan perintah USE.
  • nama_tabel adalah tabel yang akan diindeks kolomnya.
  • nama_kolom adalah kolom yang akan diindeks.
  • Klausa KEYS, VALUES, ENTRIES, danFULL digunakan untuk kolom berjenis MAP.

Contoh Penggunaan Indeks
Terlebih dahulu dibuat keyspace pustaka, diaktifkan, lalu diikuti dengan mendefinisikan tabel buku dan menambahkan datanya.

CREATE KEYSPACE IF NOT EXISTS pustaka
WITH REPLICATION = {
'class' : 'SimpleStrategy',
'replication_factor' : 1
};
USE pustaka; // Mengaktifkan keyspace pustaka// Mendefinisikan tabel buku
CREATE TABLE IF NOT EXISTS buku (
isbn ascii PRIMARY KEY,
judul text,
penerbit varchar,
thterbit smallint,
pengarang set<text>
);
// Menambahkan data buku
INSERT INTO buku (isbn,judul,penerbit,thterbit,pengarang)
VALUES ('978178398X','NoSQL vs SQL','Digital',2019,{'Dirun','Ayu'}) IF NOT EXISTS;
INSERT INTO buku (isbn,judul,penerbit,thterbit,pengarang)
VALUES ('9781484201','Belajar CQL','Iqra',2018,{'Ayu','Anta'})
IF NOT EXISTS;
INSERT INTO buku (isbn,judul,penerbit,thterbit)
VALUES ('12345X9876','CQL 3.0','ePress',2018) IF NOT EXISTS;
INSERT INTO buku (isbn,judul,penerbit,thterbit,pengarang)
VALUES ('9781239875','Tutorial SQL','Iqra',2019,{'Yana','Dirun'})
IF NOT EXISTS;
INSERT INTO buku (isbn,judul,penerbit,thterbit,pengarang)
VALUES ('223344557Z','Cassandra','ePress',2020,{'Anta'})
IF NOT EXISTS;

Struktur tabel buku di atas hanya memungkinkan pemrosesan query berdasarkan kriteria nilai primary key isbn.

cqlsh:pustaka> SELECT * FROM buku; isbn       | judul        | penerbit | pengarang         | thterbit
------------+--------------+----------+-------------------+---------
9781239875 | Tutorial SQL | Iqra | {'Dirun', 'Yana'} | 2019
12345X9876 | CQL 3.0 | ePress | null | 2018
9781484201 | Belajar CQL | Iqra | {'Anta', 'Ayu'} | 2018
978178398X | NoSQL vs SQL | Digital | {'Ayu', 'Dirun'} | 2019
223344557Z | Cassandra | ePress | {'Anta'} | 2020
(5 rows)
cqlsh:pustaka> // Query berdasarkan kriteria primary key isbn
cqlsh:pustaka> SELECT * FROM buku
... WHERE isbn = '9781239875';
isbn | judul | penerbit | pengarang | thterbit
------------+--------------+----------+-------------------+---------
9781239875 | Tutorial SQL | Iqra | {'Dirun', 'Yana'} | 2019
(1 rows)

cqlsh:pustaka> SELECT * FROM buku
... WHERE isbn IN ('223344557Z','12345678','9781484201');
isbn | judul | penerbit | pengarang | thterbit
------------+-------------+----------+-----------------+----------
223344557Z | Cassandra | ePress | {'Anta'} | 2020
9781484201 | Belajar CQL | Iqra | {'Anta', 'Ayu'} | 2018
(2 rows)

cqlsh:pustaka> SELECT COUNT(*) AS "Jumlah buku" // Fungsi agregasi
... FROM buku
... WHERE isbn IN ('223344557Z','12345678','9781484201');
Jumlah buku
-------------
2

Pemrosesan query berdasarkan kriteria nilai selain primary key, kolom thterbit misalnya, akan memberikan pesan kesalahan.

cqlsh:pustaka> // Query berdasarkan kriteria bukan primary key \\

cqlsh:pustaka> SELECT * FROM buku
... WHERE thterbit = 2019;
InvalidRequest: Error from server: 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"

cqlsh:pustaka> SELECT * FROM buku
... WHERE thterbit IN (2020,2018);
InvalidRequest: Error from server: code=2200 [Invalid query] message="IN predicates on non-primary-key columns (thterbit) is not yet supported"

cqlsh:pustaka> SELECT thterbit,
... COUNT(*) AS "Jumlah buku" // Fungsi agregasi
... FROM buku
... WHERE thterbit = 2019;
InvalidRequest: Error from server: 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"

Pemrosesan query buku berdasarkan tahun terbit dapat dilakukan dengan terlebih dahulu membuat indeksnya.

cqlsh:pustaka> CREATE INDEX idx_thterbit ON buku(thterbit);

Cassandra membuat tabel berisi nilai yang diindeks, terpisah dan tersembunyi dari tabel yang diindeks.

CREATE TABLE idx_thterbit (
thterbit smallint,
isbn ascii
PRIMARY KEY ((thterbit),isbn)
);

Pemrosesan query buku berdasarkan tahun terbit kini dapat dilakukan., namun hanya berlaku untuk kriteria menggunakan operator =.

cqlsh:pustaka> // Query berdasarkan kriteria nilai thterbit
cqlsh:pustaka> // --bukan primary key-- tapi sudah diindeks.

cqlsh:pustaka> SELECT *
... FROM buku
... WHERE thterbit = 2019;
isbn | judul | penerbit | pengarang | thterbit
------------+--------------+----------+-------------------+---------
9781239875 | Tutorial SQL | Iqra | {'Dirun', 'Yana'} | 2019
978178398X | NoSQL vs SQL | Digital | {'Ayu', 'Dirun'} | 2019
(2 rows)

cqlsh:pustaka> SELECT *
... FROM buku
... WHERE thterbit IN (2020,2018); // ERROR
InvalidRequest: Error from server: code=2200 [Invalid query] message="IN predicates on non-primary-key columns (thterbit) is not yet supported"

cqlsh:pustaka> SELECT thterbit,
... COUNT(*) AS "Jumlah buku" // Fungsi agregasi
... FROM buku
... WHERE thterbit = 2019;
thterbit | Jumlah buku
----------+-------------
2019 | 2
(1 rows)

Indeks Kolom Koleksi
Indeks dapat digunakan untuk kolom koleksi, yaitu LIST, MAP, dan SET. Berikut adalah contoh penggunaan indeks kolom bertipe SET.

cqlsh:pustaka> CREATE INDEX idx_pengarang ON buku(pengarang);cqlsh:pustaka> SELECT * FROM buku               // Daftar buku yang
... WHERE pengarang CONTAINS 'Anta'; // pengarangnya Anta
isbn | judul | penerbit | pengarang | thterbit
------------+-------------+----------+-----------------+----------
9781484201 | Belajar CQL | Iqra | {'Anta', 'Ayu'} | 2018
223344557Z | Cassandra | ePress | {'Anta'} | 2020
(2 rows)

Menghapus Indeks

Indeks dihapus dengan menggunakan pernyataan DROP INDEX. Berikut adalah diagram sintaksnya.

  • Jika indeks yang dihapus tidak ada, tampil pesan kesalahan, operasi penghapusan diabaikan.
  • Gunakan klausa IF EXIST untuk meniadakan pesan kesalahan.
  • Sebagai contoh, pernyataan berikut menghapus indeks idx_pengarang.
cqlsh:pustaka> DROP INDEX idx_pengarang;

Referensi

--

--

M. Ramadhan
Telematika

I’m a database designer and developer, childhood in Menggala, living in Palembang.