全部产品
Search
文档中心

ApsaraDB for SelectDB:Indeks terbalik

更新时间:Jul 30, 2025

Indeks terbalik umumnya digunakan untuk pengambilan informasi. Anda dapat memisahkan teks menjadi kata kunci untuk membuat indeks terbalik, yang memungkinkan pengambilan dokumen berisi kata kunci tertentu dengan cepat. ApsaraDB for SelectDB mendukung indeks terbalik, yang dapat digunakan untuk pencarian teks penuh pada data tipe TEXT dan kesetaraan atau kueri rentang pada data tipe NUMERIC dan DATE. Dengan cara ini, Anda dapat mengambil data yang memenuhi kondisi tertentu dari sejumlah besar data secara efisien. Topik ini menjelaskan fitur indeks terbalik di ApsaraDB for SelectDB, serta cara membuat dan menggunakannya.

Implementasi

Dalam implementasi indeks terbalik di ApsaraDB for SelectDB, setiap baris dalam tabel sesuai dengan sebuah dokumen, dan setiap kolom sesuai dengan bidang dalam dokumen. Oleh karena itu, indeks terbalik memungkinkan Anda menemukan baris yang berisi kata kunci tertentu dengan cepat, mempercepat kueri yang menggunakan klausa WHERE.

Indeks terbalik berbeda dari indeks lainnya di ApsaraDB for SelectDB. ApsaraDB for SelectDB menggunakan file terpisah untuk menyimpan indeks terbalik. File ini memiliki pemetaan logika dengan file segmen, tetapi keduanya independen satu sama lain. Hal ini menghilangkan kebutuhan untuk menulis ulang file segmen saat memperbarui atau menghapus indeks terbalik, sehingga mengurangi overhead pemrosesan secara signifikan.

Skenario

  • Mempercepat pencarian teks penuh untuk data tipe STRING.

  • Mempercepat pencarian untuk data tipe STRING, NUMERIC, atau DATETIME menggunakan operator: =, !=, >, >=, <, and <=.

Manfaat

  • Mendukung kombinasi logika.

    • Mendukung filter indeks dorong ke bawah untuk operator OR dan NOT.

    • Mendukung kombinasi operator AND, OR, dan NOT.

  • Mendukung manajemen indeks yang fleksibel dan cepat.

    • Memungkinkan pembuatan indeks terbalik saat membuat tabel.

    • Memungkinkan pembuatan indeks terbalik untuk tabel yang sudah ada.

    • Memungkinkan penghapusan indeks terbalik yang sudah ada dari tabel.

Batasan

  • Tipe data FLOAT dan DOUBLE yang tidak memiliki presisi tinggi tidak mendukung indeks terbalik. Tipe data DECIMAL memiliki presisi tinggi dan mendukung indeks terbalik. Anda dapat menggunakan tipe DECIMAL.

  • Beberapa tipe data kompleks tidak mendukung indeks terbalik. Tipe data kompleks termasuk MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE, dan AGG_STATE. Tipe data JSON dapat mendukung indeks terbalik setelah dikonversi menjadi tipe data VARIANT.

  • Bidang tipe NUMERIC mendukung indeks terbalik, tetapi Anda tidak diperbolehkan menentukan parser untuk bidang tersebut. Nilai valid parser: english, chinese, dan unicode.

  • Anda dapat membuat indeks terbalik untuk semua kolom dalam model DUPLICATE dan model UNIQUE yang memiliki Merge on Write (MoW) diaktifkan. Untuk model AGGREGATE dan UNIQUE dengan MoW dinonaktifkan, Anda hanya dapat membuat indeks terbalik untuk kolom Kunci. Model-model tersebut perlu membaca semua data dan menggabungkannya, sehingga indeks tidak dapat digunakan untuk menyaring data terlebih dahulu.

Buat indeks terbalik

Anda dapat membuat indeks terbalik saat membuat tabel atau menambahkannya ke kolom dalam tabel yang sudah ada.

Buat indeks terbalik saat Anda membuat tabel

Operasi ini bersifat sinkron. Jika Anda membuat indeks terbalik saat membuat tabel, tabel dan indeks terbalik dibuat secara sinkron.

Penting

Indeks terbalik memiliki batasan yang berbeda dalam model data berikut:

  • Dalam model Aggregate Key, Anda hanya dapat membuat indeks terbalik pada kolom kunci.

  • Dalam model Unique Key, Anda harus mengaktifkan fitur MoW. Setelah mengaktifkan fitur MoW, Anda dapat membuat indeks terbalik pada kolom apa pun.

  • Dalam model Duplicate Key, Anda dapat membuat indeks terbalik pada kolom apa pun.

Sintaksis

CREATE TABLE  [IF NOT EXISTS] [db_name.]<table_name>
(
  <column_definition_list>,
  [<index_definition_list>] 
)
table_properties;

Parameter

Parameter yang Digunakan untuk Membuat Tabel

Parameter

Wajib

Deskripsi

db_name

Tidak

Nama database tempat Anda ingin membuat tabel.

table_name

Ya

Nama tabel yang ingin Anda buat.

column_definition_list

Ya

Daftar definisi kolom. Untuk informasi lebih lanjut, lihat CREATE-TABLE.

table_properties

Ya

Properti tabel, seperti model data dan pengaturan partisi dan bucketing. Untuk informasi lebih lanjut, lihat Model data.

index_definition_list

Tidak

Daftar definisi indeks.

index_definition_list

Anda dapat mendefinisikan beberapa indeks dalam format berikut saat membuat tabel: index_definition[, index_definition][, index_definition]....

Sintaksis index_definition

INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")] [COMMENT '<comment>']

Parameter index_definition

Parameter wajib

Parameter

Deskripsi

index_name

Nama indeks.

column_name

Nama kolom tempat indeks dibuat.

index_type

Tipe indeks. Atur nilai menjadi USING INVERTED.

Parameter opsional
PROPERTIES

Parameter PROPERTIES menentukan apakah akan memisahkan teks menjadi kata kunci berdasarkan indeks. Nilai parameter PROPERTIES terdiri dari satu atau lebih pasangan kunci-nilai yang dipisahkan oleh koma (,). Setiap pasangan kunci-nilai dalam format "<key>" = "<value>". Untuk melihat hasil tokenisasi teks kontinu, Anda dapat memanggil fungsi TOKENIZE. Untuk informasi lebih lanjut, lihat Fungsi TOKENIZE.

key

value

parser

Pemisah kata. Secara default, kunci dibiarkan kosong, yang menentukan bahwa teks tidak dipisahkan menjadi kata kunci. Anda tidak diperbolehkan menentukan parser untuk bidang tipe NUMERIC. Nilai valid:

  • english: pemisah kata bahasa Inggris, cocok untuk bidang yang berisi istilah bahasa Inggris. Pemisah kata ini memisahkan teks menjadi kata kunci menggunakan spasi dan tanda baca, serta memberikan performa tinggi.

  • chinese: pemisah kata bahasa Cina, cocok untuk bidang yang berisi istilah bahasa Cina. Pemisah kata ini memberikan performa lebih rendah daripada pemisah kata bahasa Inggris.

  • unicode: pemisah kata Unicode campuran, cocok untuk bidang yang berisi istilah bahasa Inggris dan Cina. Pemisah kata ini dapat memisahkan awalan dan akhiran alamat email, alamat IP, dan kombinasi karakter dan digit. Ini juga dapat memisahkan istilah bahasa Cina berdasarkan karakter.

parser_mode

Mode tokenisasi kata. Granularitas tokenisasi kata bervariasi berdasarkan mode tokenisasi kata.

Secara default, mode coarse_grained digunakan untuk semua pemisah kata. Dalam mode coarse_grained, teks dipisahkan menjadi istilah panjang. Sebagai contoh, 武汉市长江大桥 dipisahkan menjadi dua istilah berikut: 武汉市 dan 长江大桥.

Jika pengaturan parser=chinese dikonfigurasi, pemisah kata Cina digunakan dan mode fine_grained didukung. Dalam mode fine_grained, teks dipisahkan menjadi istilah pendek. Sebagai contoh, 武汉市长江大桥 dipisahkan menjadi enam istilah berikut: 武汉, 武汉市, 市长, 长江, 长江大桥, dan 大桥.

Untuk informasi lebih lanjut tentang cara menggunakan tokenisasi kata, lihat Fungsi TOKENIZE.

support_phrase

Menentukan apakah akan mempercepat kueri MATCH_PHRASE menggunakan indeks. Nilai default: false.

  • Jika Anda mengatur parameter ini ke true, kueri MATCH_PHRASE dipercepat tetapi indeks memerlukan lebih banyak kapasitas penyimpanan.

  • Jika Anda mengatur parameter ini ke false, kueri MATCH_PHRASE tidak dipercepat dan indeks memerlukan lebih sedikit ruang penyimpanan. Anda dapat melakukan kueri MATCH_ALL untuk mencocokkan beberapa istilah sekaligus.

char_filter

Parameter yang digunakan untuk memproses string sebelum teks dipisahkan menjadi kata kunci. Parameter char_filter_type dapat diatur ke char_replace saja.

Jika Anda mengatur parameter char_filter_type ke char_replace, karakter dalam nilai parameter char_filter_pattern diganti dengan karakter dalam nilai parameter char_filter_replacement.

  • char_filter_pattern: array karakter yang akan diganti.

  • char_filter_replacement: array karakter yang digunakan untuk menggantikan karakter yang akan diganti. Anda dapat meninggalkan parameter ini kosong. Nilai default adalah karakter spasi.

COMMENT

Parameter

Deskripsi

comment

Deskripsi indeks.

Contoh

-- Buat tabel dan indeks terbalik bernama idx_comment pada kolom comment.
-- USING INVERTED menentukan bahwa tipe indeks adalah indeks terbalik.
-- PROPERTIES("parser" = "english") menentukan bahwa pemisah kata bahasa Inggris digunakan untuk memisahkan teks menjadi kata kunci. Anda juga dapat mengatur parameter parser ke chinese atau unicode. Jika Anda membiarkan parameter parser kosong, teks tidak dipisahkan menjadi kata kunci.
CREATE TABLE hackernews_1m
(
    `id` BIGINT,
    `deleted` TINYINT,
    `type` String,
    `author` String,
    `timestamp` DateTimeV2,
    `comment` String,
    `dead` TINYINT,
    `parent` BIGINT,
    `poll` BIGINT,
    `children` Array<BIGINT>,
    `url` String,
    `score` INT,
    `title` String,
    `parts` Array<INT>,
    `descendants` INT,
    INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'indeks terbalik untuk comment'
)
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10;

Buat indeks terbalik untuk tabel yang sudah ada

Operasi ini bersifat asinkron. Anda dapat mengeksekusi pernyataan SHOW ALTER TABLE COLUMN; untuk menanyakan kemajuan pembuatan indeks.

Sintaksis

ALTER TABLE <table_name> ADD INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")];

Parameter

Parameter-parameter tersebut sama dengan yang digunakan untuk membuat indeks terbalik saat membuat tabel.

Contoh

Buat indeks terbalik yang tidak digunakan untuk memisahkan teks menjadi kata kunci.

ALTER TABLE user_tb ADD INDEX index_userId(user_id) USING INVERTED ;

Buat indeks terbalik yang digunakan untuk memisahkan teks menjadi kata kunci menggunakan pemisah kata Inggris.

ALTER TABLE user_tb ADD INDEX index_city(city) USING INVERTED PROPERTIES("parser" = "english");

Kueri informasi tentang indeks terbalik

Kueri kemajuan perubahan indeks

Anda dapat mengeksekusi pernyataan ALTER atau DROP untuk mengubah indeks terbalik. Operasi ini bersifat asinkron. Anda dapat mengeksekusi pernyataan berikut untuk menanyakan kemajuannya:

SHOW ALTER TABLE COLUMN;

Kueri semua indeks yang dibuat untuk tabel

Sintaksis

SHOW INDEXES FROM <table_name>;

Contoh

SHOW INDEXES FROM user_tb;

Hapus indeks terbalik

Anda dapat menghapus indeks dalam mode asinkron. Untuk informasi lebih lanjut tentang cara menanyakan kemajuan penghapusan indeks, lihat Kueri Informasi tentang Indeks Terbalik.

Penting

Jika Anda menghapus indeks terbalik dari tabel, performa kueri pada tabel tersebut menurun. Lanjutkan dengan hati-hati.

Sintaksis

-- Sintaksis 1
DROP INDEX <index_name> ON <table_name>;
-- Sintaksis 2
ALTER TABLE <table_name> DROP INDEX <index_name>;

Contoh

DROP INDEX index_userId ON user_tb;
ALTER TABLE user_tb DROP INDEX index_city;

Gunakan indeks terbalik

Pencarian teks penuh

Sintaksis

SELECT * FROM <table_name> WHERE <column_name> <conditional_logic> '<keywords>';

Parameter

Parameter

Wajib

Deskripsi

table_name

Ya

Nama tabel yang ingin Anda kueri.

column_name

Ya

Nama kolom yang ingin Anda kueri.

conditional_logic

Ya

Logika kondisional, yaitu kombinasi kata kunci pencarian teks penuh dan operator logika.

Operator logika: AND, OR, dan NOT.

Kata kunci pencarian teks penuh:

  • MATCH_ALL: mencocokkan beberapa istilah sekaligus.

  • MATCH_ANY: mencocokkan satu istilah.

  • MATCH_PHRASE: mencocokkan frasa.

keywords

Ya

Istilah yang digunakan untuk menanyakan data.

Pisahkan beberapa istilah dengan spasi.

Contoh: keyword1 keyword2 keyword3.

Contoh

-- Kueri semua baris yang berisi keyword1 dalam kolom logmsg dari tabel log_tb. 
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';

-- Kueri semua baris yang berisi keyword1 atau keyword2 dalam kolom logmsg dari tabel log_tb. 
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';

-- Kueri semua baris yang berisi keyword1 dan keyword2 dalam kolom logmsg dari tabel log_tb. 
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';

-- Kueri semua baris yang berisi keyword1 dan keyword2 dalam kolom logmsg dari tabel log_tb dan di mana keyword2 mengikuti keyword1. 
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';

Kesetaraan atau kueri rentang pada data tipe NUMERIC dan DATE

Dalam skenario ini, sintaksis kueri sama dengan sintaksis SQL standar.

Contoh

-- Lakukan kueri kesetaraan, kueri rentang, dan kueri yang berisi kondisi IN atau NOT IN.
SELECT * FROM user_tb WHERE id = 123;
SELECT * FROM user_tb WHERE ts > '2023-01-01 00:00:00';
SELECT * FROM user_tb WHERE op_type IN ('add', 'delete');

Bandingkan performa kueri

Dalam contoh ini, tabel hackernews yang berisi 1 juta entri data digunakan untuk membandingkan performa kueri sebelum dan sesudah menggunakan indeks terbalik.

Persiapan Lingkungan

Langkah 1: Buat Tabel

  1. Buat database.

    CREATE DATABASE test_inverted_index;
  2. Beralih ke database yang telah dibuat.

    USE test_inverted_index;
  3. Buat tabel.

    CREATE TABLE hackernews_1m
    (
        `id` BIGINT,
        `deleted` TINYINT,
        `type` String,
        `author` String,
        `timestamp` DateTimeV2,
        `comment` String,
        `dead` TINYINT,
        `parent` BIGINT,
        `poll` BIGINT,
        `children` Array<BIGINT>,
        `url` String,
        `score` INT,
        `title` String,
        `parts` Array<INT>,
        `descendants` INT,
        INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'indeks terbalik untuk comment'
    )
    DUPLICATE KEY(`id`)
    DISTRIBUTED BY HASH(`id`) BUCKETS 10;
    -- Buat tabel dan indeks terbalik bernama idx_comment pada kolom comment.
    -- USING INVERTED menentukan bahwa tipe indeks adalah indeks terbalik.
    -- PROPERTIES("parser" = "english") menentukan bahwa pemisah kata bahasa Inggris digunakan untuk memisahkan teks menjadi istilah. Anda juga dapat mengatur parameter parser ke chinese atau unicode. Jika Anda membiarkan parameter parser kosong, teks tidak dipisahkan menjadi istilah.

Langkah 2: Impor Data

Impor data ke tabel yang telah dibuat.

  1. Unduh file data.

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Impor data ke tabel menggunakan Stream Load.

    Di halaman Detail Instans dari sebuah instans ApsaraDB for SelectDB, Anda dapat melihat titik akhir dan nomor port dari instans ApsaraDB for SelectDB. Untuk informasi lebih lanjut tentang Stream Load, lihat Gunakan Stream Load untuk Mengimpor Data.

    curl --location-trusted -u root: -H "compress_type:gz" -T hacknernews_1m.csv.gz  http://<host>:<port>/api/test_inverted_index/hackernews_1m/_stream_load
    {
        "TxnId": 2,
        "Label": "a8a3e802-2329-49e8-912b-04c800a461a6",
        "TwoPhaseCommit": "false",
        "Status": "Success",
        "Message": "OK",
        "NumberTotalRows": 1000000,
        "NumberLoadedRows": 1000000,
        "NumberFilteredRows": 0,
        "NumberUnselectedRows": 0,
        "LoadBytes": 130618406,
        "LoadTimeMs": 8988,
        "BeginTxnTimeMs": 23,
        "StreamLoadPutTimeMs": 113,
        "ReadDataTimeMs": 4788,
        "WriteDataTimeMs": 8811,
        "CommitAndPublishTimeMs": 38
    }
  3. Panggil fungsi count() untuk memeriksa apakah data telah diimpor.

    SELECT count() FROM hackernews_1m;
    +---------+
    | count() |
    +---------+
    | 1000000 |
    +---------+
    1 row in set (0.02 sec)

Perbandingan Performa

Catatan
  • Hasil yang diperoleh dengan menggunakan indeks terbalik yang digunakan untuk memisahkan teks menjadi istilah berbeda dari hasil yang diperoleh tanpa menggunakan indeks terbalik. Indeks terbalik memisahkan nilai dalam kolom menjadi istilah dan menormalkan istilah tersebut dengan mengonversinya ke huruf kecil. Oleh karena itu, hasil yang diperoleh dengan menggunakan indeks terbalik lebih banyak daripada hasil yang diperoleh tanpa menggunakan indeks terbalik.

  • Performa kueri dalam beberapa contoh tidak berbeda secara signifikan karena ukuran dataset kecil. Semakin besar dataset, semakin besar perbedaan performa.

Pencarian Teks Penuh
  • Hitung jumlah baris yang berisi OLAP dalam kolom comment.

    • Hitung jumlah baris yang berisi OLAP dalam kolom comment berdasarkan kondisi LIKE. Kueri membutuhkan waktu 0,18 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • Hitung jumlah baris yang berisi OLAP dalam kolom comment berdasarkan kata kunci pencarian teks penuh MATCH_ANY. Kueri membutuhkan waktu 0,02 detik. Performa kueri berdasarkan kata kunci pencarian teks penuh delapan kali lebih tinggi daripada berdasarkan kondisi LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 row in set (0.02 sec)
  • Hitung jumlah baris yang berisi OLTP dalam kolom comment.

    • Hitung jumlah baris yang berisi OLTP dalam kolom comment berdasarkan kondisi LIKE. Kueri membutuhkan waktu 0,07 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • Hitung jumlah baris yang berisi OLTP dalam kolom comment berdasarkan kata kunci pencarian teks penuh MATCH_ANY. Kueri membutuhkan waktu 0,01 detik. Performa kueri berdasarkan kata kunci pencarian teks penuh enam kali lebih tinggi daripada berdasarkan kondisi LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • Hitung jumlah baris yang berisi OLAP dan OLTP dalam kolom comment.

    • Hitung jumlah baris yang berisi OLAP dan OLTP dalam kolom comment berdasarkan kondisi LIKE. Kueri membutuhkan waktu 0,13 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • Hitung jumlah baris yang berisi OLAP dan OLTP dalam kolom comment berdasarkan kata kunci pencarian teks penuh MATCH_ALL. Kueri membutuhkan waktu 0,01 detik. Performa kueri berdasarkan kata kunci pencarian teks penuh dua belas kali lebih tinggi daripada berdasarkan kondisi LIKE.

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • Hitung jumlah baris yang berisi OLAP atau OLTP dalam kolom comment.

    • Hitung jumlah baris yang berisi OLAP atau OLTP dalam kolom comment berdasarkan kondisi LIKE. Kueri membutuhkan waktu 0,12 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • Hitung jumlah baris yang berisi OLAP atau OLTP dalam kolom comment berdasarkan kata kunci pencarian teks ppenuh. Kueri membutuhkan waktu 0,01 detik. Performa kueri berdasarkan kata kunci pencarian teks penuh sebelas kali lebih tinggi daripada berdasarkan kondisi LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      71 |
      +---------+
      1 row in set (0.01 sec)

Kesetaraan atau kueri rentang

  • Bandingkan performa kueri rentang kolom pada data tipe DATETIME.

    1. Kueri data yang nilainya lebih besar dari 2007-08-23 04:17:00 dalam kolom timestamp sebelum indeks terbalik dibuat. Kueri membutuhkan waktu 0,03 detik.

       SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.03 sec)
    2. Buat indeks terbalik pada kolom timestamp.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Kueri kemajuan pembuatan indeks. Berdasarkan perbedaan antara nilai-nilai parameter FinishTime dan CreateTime, Anda dapat melihat bahwa hanya butuh 1 detik untuk membuat indeks terbalik pada kolom timestamp yang berisi 1 juta entri data.

      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      1 row in set (0.00 sec)
    4. Setelah indeks terbalik dibuat, eksekusi pernyataan kueri yang sama untuk menanyakan data yang nilainya lebih besar dari 2007-08-23 04:17:00 dalam kolom timestamp. Kueri membutuhkan waktu 0,01 detik. Performa kueri 0,02 detik lebih cepat daripada sebelum indeks terbalik dibuat.

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.01 sec)
  • Bandingkan performa kueri kesetaraan pada data tipe NUMERIC.

    1. Kueri data yang nilainya 11189 dalam kolom parent sebelum indeks terbalik dibuat.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Buat indeks terbalik yang tidak digunakan untuk memisahkan teks menjadi istilah pada kolom parent.

      -- Anda tidak perlu menentukan pemisah kata untuk kolom tipe NUMERIC saat membuat indeks terbalik pada kolom tersebut.
      -- ALTER TABLE t ADD INDEX adalah sintaksis kedua untuk membuat indeks terbalik.
      ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Kueri kemajuan pembuatan indeks.

      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054   | 10008         | 1:378856428   | 4             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
    4. Setelah indeks terbalik dibuat, eksekusi pernyataan kueri yang sama untuk menanyakan data yang nilainya 11189 dalam kolom parent.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • Bandingkan performa kueri kesetaraan pada data tipe STRING.

    1. Kueri data yang nilainya faster dalam kolom author sebelum indeks terbalik dibuat. Kueri membutuhkan waktu 0,03 detik.

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. Buat indeks terbalik yang tidak digunakan untuk memisahkan teks menjadi istilah pada kolom author.

      -- Dalam contoh ini, indeks terbalik dibuat pada kolom author. Setiap nilai kolom author tidak dipisah menjadi istilah dan dianggap sebagai satu istilah.
      ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Kueri kemajuan pembuatan indeks.

      -- Hanya butuh 1,5 detik untuk membuat indeks terbalik dalam mode inkremental pada kolom author yang berisi 1 juta entri data.
      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054   | 10008         | 1:378856428   | 4             | FINISHED |      | NULL     | 2592000 |
      | 10076 | hackernews_1m | 2023-02-10 19:54:20.046 | 2023-02-10 19:54:21.521 | hackernews_1m | 10077   | 10008         | 1:1335127701  | 5             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      
    4. Setelah indeks terbalik dibuat, eksekusi pernyataan kueri yang sama untuk menanyakan data yang nilainya faster dalam kolom author. Kueri membutuhkan waktu 0,01 detik. Performa kueri 0,02 detik lebih cepat daripada sebelum indeks terbalik dibuat.

      -- Setelah indeks terbalik dibuat, kueri kesetaraan pada string juga dipercepat secara signifikan.
      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.01 sec)

Fungsi TOKENIZE

Fungsi TOKENIZE dapat memisahkan teks kontinu menjadi istilah atau frasa terpisah. Fungsi ini penting untuk membuat dan menggunakan indeks terbalik serta erat kaitannya dengan indeks terbalik. Kualitas dan metode tokenisasi langsung memengaruhi kualitas dan performa indeks terbalik.

Anda juga dapat memanggil fungsi TOKENIZE untuk menanyakan hasil tokenisasi teks kontinu. Fungsi TOKENIZE berisi parameter parser dan parser_mode. Tabel berikut menjelaskan parameter-parameter tersebut.

Parameter

Deskripsi

parser

Pemisah kata. Secara default, parameter ini dibiarkan kosong, yang menentukan bahwa teks tidak dipisahkan. Nilai valid:

  • english: pemisah kata bahasa Inggris, cocok untuk bidang yang berisi istilah bahasa Inggris. Pemisah kata ini memisahkan teks menjadi istilah menggunakan spasi dan tanda baca, serta memberikan performa tinggi.

  • chinese: pemisah kata bahasa Cina, cocok untuk bidang yang berisi istilah bahasa Cina. Pemisah kata ini memberikan performa lebih rendah daripada pemisah kata bahasa Inggris.

  • unicode: pemisah kata Unicode campuran, cocok untuk bidang yang berisi istilah bahasa Inggris dan Cina. Pemisah kata ini dapat memisahkan awalan dan akhiran alamat email, alamat IP, dan kombinasi karakter dan digit. Ini juga dapat memisahkan istilah bahasa Cina berdasarkan karakter.

parser_mode

Mode tokenisasi kata. Granularitas tokenisasi kata bervariasi berdasarkan mode tokenisasi kata.

Secara default, mode coarse_grained digunakan untuk semua pemisah kata. Dalam mode coarse_grained, teks dipisahkan menjadi istilah panjang. Sebagai contoh, 武汉市长江大桥 dipisahkan menjadi dua istilah berikut: 武汉市 dan 长江大桥.

Jika pengaturan parser=chinese dikonfigurasi, pemisah kata Cina digunakan dan mode fine_grained didukung. Dalam mode fine_grained, teks dipisahkan menjadi istilah pendek. Sebagai contoh, 武汉市长江大桥 dipisahkan menjadi enam istilah berikut: 武汉, 武汉市, 市长, 长江, 长江大桥, dan 大桥.

Contoh

-- Hasil tokenisasi kata bahasa Inggris 
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"]                         |
+------------------------------------------------+
1 row in set (0.02 sec)

-- Hasil tokenisasi kata halus yang diimplementasikan menggunakan pemisah kata Cina. 
SELECT TOKENIZE('武汉长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-----------------------------------------------------------------------------------+
| tokenize('武汉长江大桥', '"parser"="chinese","parser_mode"="fine_grained"')       |
+-----------------------------------------------------------------------------------+
| ["武汉", "武汉长江大桥", "长江", "长江大桥", "大桥"]                              |
+-----------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- Hasil tokenisasi kata kasar yang diimplementasikan menggunakan pemisah kata Cina. 
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"')        |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"]                                                                 |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- Hasil tokenisasi kata teks multi-bahasa 
SELECT TOKENIZE('I love CHINA 我爱我的祖国','"parser"="unicode"');
+-------------------------------------------------------------------+
| tokenize('I love CHINA 我爱我的祖国', '"parser"="unicode"')       |
+-------------------------------------------------------------------+
| ["i", "love", "china", "我", "爱", "我", "的", "祖", "国"]        |
+-------------------------------------------------------------------+
1 row in set (0.02 sec)