All Products
Search
Document Center

ApsaraDB for SelectDB:Indeks terbalik

Last Updated:May 14, 2026

Indeks terbalik adalah teknik pengindeksan umum dalam information retrieval yang bekerja dengan melakukan tokenisasi teks menjadi kata kunci untuk membangun indeks, sehingga memungkinkan pengambilan dokumen yang berisi kata kunci tersebut secara cepat. ApsaraDB for SelectDB mendukung indeks terbalik. Anda dapat menggunakan fitur ini untuk melakukan pencarian teks penuh pada tipe data teks serta menjalankan kueri kesetaraan dan kueri rentang pada tipe data numerik dan tanggal, sehingga memungkinkan penyaringan set data besar secara cepat guna menemukan data tertentu. Topik ini menjelaskan fitur indeks terbalik di ApsaraDB for SelectDB, termasuk cara membuat dan menggunakannya.

Cara kerja

Di Alibaba Cloud SelectDB, indeks terbalik memperlakukan baris tabel sebagai dokumen dan kolom sebagai bidang. Pendekatan ini memungkinkan indeks terbalik menemukan baris yang berisi kata kunci tertentu dengan cepat, sehingga meningkatkan performa kueri yang menggunakan klausa WHERE.

Berbeda dengan indeks biasa, indeks terbalik disimpan dalam file terbalik terpisah. File ini dipetakan secara logis ke file segmen tetapi tidak diintegrasikan dengannya. Pendekatan ini menghindari penulisan ulang file segmen saat pembaruan atau penghapusan indeks, sehingga secara signifikan mengurangi overhead pemrosesan.

Skenario penggunaan

  • Mempercepat pencarian teks penuh pada tipe data string.

  • Mempercepat penyaringan =, !=, >, >=, <, <= untuk tipe data string, numerik, dan datetime.

Keuntungan

  • Dukungan komprehensif untuk operator logika.

    • Ditambahkan dukungan untuk index pushdown logika OR dan NOT.

    • Mendukung kombinasi kondisi ganda apa pun menggunakan AND, OR, dan NOT.

  • Manajemen indeks yang fleksibel dan cepat.

    • Buat indeks terbalik saat membuat tabel.

    • Tambahkan indeks terbalik ke tabel yang sudah ada.

    • Hapus indeks terbalik dari tabel.

Keterbatasan

  • Tipe data floating-point FLOAT dan DOUBLE tidak mendukung indeks terbalik karena masalah presisi. Sebagai gantinya, gunakan tipe data fixed-point DECIMAL yang mendukung indeks terbalik.

  • Beberapa tipe data kompleks tidak mendukung indeks terbalik, termasuk MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE, dan AGG_STATE. Untuk menggunakan indeks terbalik dengan data JSON, ubah kolom tersebut ke tipe data VARIANT.

  • Anda dapat membuat indeks terbalik pada bidang bertipe numerik, tetapi tidak dapat menentukan parser, seperti english, chinese, atau unicode.

  • Model DUPLICATE dan model UNIQUE dengan fitur Merge on Write yang diaktifkan mendukung indeks terbalik pada kolom apa pun. Sebaliknya, model AGGREGATE dan model UNIQUE dengan Merge on Write dinonaktifkan hanya mendukung indeks terbalik pada kolom Key. Karena model-model ini harus membaca dan menggabungkan semua data, sistem tidak dapat menggunakan indeks untuk pre-filtering.

Membuat indeks

Anda dapat membuat indeks terbalik saat pembuatan tabel atau pada kolom di tabel yang sudah ada.

Buat indeks saat pembuatan tabel

Ini adalah operasi sinkron. Pembuatan indeks selesai ketika tabel berhasil dibuat.

Penting

Indeks terbalik memiliki keterbatasan berikut pada model data yang berbeda:

  • Untuk model aggregate key, Anda hanya dapat membuat indeks terbalik pada kolom key.

  • Untuk model unique key, fitur Merge on Write harus diaktifkan. Setelah diaktifkan, Anda dapat membuat indeks terbalik pada kolom apa pun.

  • Untuk model duplicate key, Anda dapat membuat indeks terbalik pada kolom apa pun.

Sintaks

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

Parameter

Parameter pembuatan tabel

Parameter

Wajib

Deskripsi

db_name

Tidak

Nama database yang akan berisi tabel tersebut.

table_name

Ya

Nama tabel yang akan dibuat.

column_definition_list

Ya

Daftar definisi kolom. Untuk informasi selengkapnya, lihat CREATE-TABLE.

table_properties

Ya

Properti tabel, seperti model data, partisi, dan bucketing. Untuk informasi selengkapnya, lihat model data.

index_definition_list

Tidak

Daftar definisi indeks.

index_definition_list

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

index_definition

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

Parameter

Parameter wajib

Parameter

Deskripsi

index_name

Nama indeks.

column_name

Nama kolom yang akan diindeks.

index_type

Jenis indeks. Tetapkan nilai ini ke USING INVERTED.

Parameter opsional
Properti

Klausa PROPERTIES menentukan opsi tokenisasi untuk indeks. Klausa ini terdiri dari satu atau beberapa pasangan kunci-nilai yang dipisahkan koma dalam format "<key>" = "<value>". Jika Anda tidak yakin bagaimana teks tertentu akan ditokenisasi, gunakan fungsi TOKENIZE untuk melihat output-nya. Untuk informasi selengkapnya, lihat Fungsi tokenisasi.

Kunci

Nilai

parser

Menentukan pemisah kata. Jika properti ini dihilangkan, tidak ada tokenisasi yang dilakukan. Properti parser tidak didukung untuk tipe data numerik.

  • english: Pemisah kata bahasa Inggris. Ideal untuk teks berbahasa Inggris, pemisah kata berkinerja tinggi ini memisahkan kata berdasarkan spasi dan tanda baca.

  • chinese: Pemisah kata bahasa Tiongkok. Cocok untuk teks yang berisi karakter Tiongkok. Performanya lebih rendah dibandingkan pemisah kata bahasa Inggris.

  • unicode: Pemisah kata Unicode. Cocok untuk teks campuran, seperti Tiongkok dan Inggris. Dapat melakukan tokenisasi awalan dan akhiran email, alamat IP, serta string alfanumerik. Juga melakukan tokenisasi teks Tiongkok per karakter.

parser_mode

Menentukan mode tokenisasi kata, yang mengatur granularitas tokenisasi.

Semua pemisah kata menggunakan mode coarse_grained secara default. Mode ini cenderung membagi teks menjadi kata yang lebih panjang. Misalnya, 'Wuhan City Yangtze River Bridge' dibagi menjadi dua kata: 'Wuhan City' dan 'Yangtze River Bridge'.

Ketika parser=chinese ditentukan untuk pemisah kata Tiongkok, mode fine_grained juga didukung. Mode ini cenderung melakukan tokenisasi teks menjadi kata yang lebih pendek. Misalnya, 'Wuhan City Yangtze River Bridge' ditokenisasi menjadi enam token: 'Wuhan', 'Wuhan City', 'mayor', 'Yangtze River', 'Yangtze River Bridge', dan 'Bridge'.

Untuk mempelajari lebih lanjut cara kerja tokenisasi, lihat Fungsi tokenisasi.

support_phrase

Menentukan apakah indeks mendukung percepatan kueri frasa MATCH_PHRASE. Nilai default-nya adalah false.

  • true: Mengaktifkan dukungan, yang memerlukan lebih banyak storage space.

  • false: Menonaktifkan dukungan untuk menghemat storage space. Anda dapat menggunakan MATCH_ALL untuk mengkueri beberapa kata kunci.

char_filter

Memproses string sebelum tokenisasi. Saat ini, char_filter_type hanya mendukung char_replace.

char_replace mengganti setiap karakter dalam char_filter_pattern dengan karakter yang sesuai dari char_filter_replacement.

  • char_filter_pattern: Array karakter yang akan diganti.

  • Properti ini opsional dan default-nya adalah satu karakter spasi jika dihilangkan.

ignore_above

Menentukan batas panjang untuk nilai string non-tokenisasi (ketika tidak ada parser yang ditentukan).

  • Sistem tidak mengindeks string yang lebih panjang dari nilai ignore_above. Untuk array string, batas ini berlaku untuk setiap elemen.

  • Default: 256 (byte).

lower_case

Menentukan apakah istilah yang ditokenisasi dikonversi ke huruf kecil untuk pencocokan case-insensitive.

  • true: Mengonversi ke huruf kecil.

  • false: Mempertahankan kapitalisasi aslinya.

stopwords

Menentukan daftar stopwords, yang memengaruhi perilaku pemisah kata.

  • Daftar bawaan mencakup kata umum bernilai rendah (seperti is, the, dan a) yang diabaikan sistem selama pengindeksan dan pengkuerian.

  • none: Menggunakan daftar stopwords kosong.

dict_compression

Menentukan apakah kompresi kamus Zstandard (ZSTD) diaktifkan untuk kamus indeks terbalik.

  • true: Mengaktifkan kompresi kamus.

  • false: (Default) Menonaktifkan kompresi kamus.

  • Rekomendasi: Aktifkan ini untuk beban kerja teks atau log skala besar, atau untuk mengurangi biaya penyimpanan. Fitur ini bekerja paling baik dengan inverted_index_storage_format = "V3" dan dapat mengurangi penyimpanan hingga sekitar 20% untuk data teks dan log skala besar.

Catatan

Parameter ini hanya didukung pada versi 4.1.0 dan yang lebih baru.

Komentar

Parameter

Deskripsi

comment

Deskripsi indeks.

Contoh: Buat tabel dengan indeks

-- Buat tabel dan indeks terbalik bernama idx_comment pada kolom comment.
-- USING INVERTED menetapkan jenis indeks menjadi indeks terbalik.
-- PROPERTIES("parser" = "english") menetapkan pemisah kata menjadi "english". Pemisah kata lain yang didukung termasuk "chinese" untuk teks Tiongkok dan "unicode" untuk teks campuran. Jika properti "parser" dihilangkan, tidak ada tokenisasi yang dilakukan.
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 'inverted index for comment'
)
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10;

Tambahkan indeks

Operasi ini merupakan operasi asinkron. Anda dapat memeriksa progres pembuatan indeks dengan menggunakan SHOW ALTER TABLE COLUMN;.

Sintaks

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

Parameter

Parameter-parameter ini sama dengan parameter saat membuat tabel.

Contoh

Tambahkan indeks tanpa tokenisasi.

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

Tambahkan indeks yang menggunakan english untuk tokenisasi.

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

Lihat indeks terbalik

Lihat progres perubahan indeks

Memodifikasi indeks terbalik menggunakan perintah ALTER dan DROP adalah proses asinkron. Untuk melihat progresnya, gunakan pernyataan berikut.

SHOW ALTER TABLE COLUMN;

Lihat semua indeks tabel terbalik

Sintaks

SHOW INDEXES FROM <table_name>;

Contoh

SHOW INDEXES FROM user_tb;

Hapus indeks

Menghapus indeks adalah proses asinkron. Untuk memeriksa progresnya, lihat Kueri informasi tentang indeks terbalik.

Penting

Menghapus indeks dapat menurunkan performa kueri. Lakukan dengan hati-hati.

Sintaks

-- Sintaks 1
DROP INDEX <index_name> ON <table_name>;
-- Sintaks 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;

Indeks terbalik

Pencarian teks penuh

Sintaks

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

Parameter

Parameter

Wajib

Deskripsi

table_name

Ya

Nama tabel.

column_name

Ya

Nama kolom.

conditional_logic

Ya

Kombinasi operator pencarian dan operator logika.

Operator logika: AND, OR, dan NOT.

Operator pencarian:

  • MATCH_ALL: Mengembalikan baris yang berisi semua kata kunci yang ditentukan.

  • MATCH_ANY: Mengembalikan baris yang berisi salah satu kata kunci yang ditentukan.

  • MATCH_PHRASE: Mengembalikan baris yang berisi frasa persis.

keywords

Ya

Kata kunci pencarian.

Pisahkan beberapa kata kunci dengan spasi.

Contoh: keyword1 keyword2 keyword3.

Contoh

-- Ambil baris di mana logmsg berisi keyword1.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';

-- Ambil baris di mana logmsg berisi keyword1 atau keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';

-- Ambil baris di mana logmsg berisi keyword1 dan keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';

-- Ambil baris di mana logmsg berisi frasa persis "keyword1 keyword2".
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';

Kueri kesetaraan dan rentang untuk numerik dan tanggal

Sintaks kueri menggunakan sintaks SQL standar.

Contoh

-- Kueri kesetaraan, rentang, IN, dan 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');

Perbandingan performa kueri

Topik ini menggunakan set data hackernews dengan 1 juta baris untuk membandingkan performa kueri dengan dan tanpa indeks terbalik.

Prasyarat

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 target.

    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 'inverted index for comment'
    )
    DUPLICATE KEY(`id`)
    DISTRIBUTED BY HASH(`id`) BUCKETS 10;
    -- Membuat tabel dan indeks terbalik bernama idx_comment pada kolom comment.
    -- USING INVERTED menentukan bahwa jenis indeks adalah indeks terbalik.
    -- PROPERTIES("parser" = "english") menentukan bahwa pemisah kata bahasa Inggris digunakan. Anda juga dapat menentukan "chinese" untuk teks Tiongkok atau "unicode" untuk teks campuran. Jika Anda tidak menentukan parameter "parser", tidak ada tokenisasi yang dilakukan.

Langkah 2: Impor data

  1. Unduh file data.

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

    Di halaman detail instans ApsaraDB for SelectDB, Anda dapat melihat host titik akhir dan nomor port instans ApsaraDB for SelectDB. Untuk informasi selengkapnya tentang Stream Load, lihat Stream Load.

    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. Jalankan kueri count() untuk memverifikasi impor data.

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

Perbandingan performa

Catatan
  • Hasil hitungan dapat berbeda antara kueri yang menggunakan indeks terbalik dengan pemisah kata dan yang tidak. Hal ini karena indeks terbalik melakukan tokenisasi data kolom dan menormalisasi istilah (misalnya, dengan mengonversinya ke huruf kecil), yang dapat menyebabkan kueri yang menggunakan indeks mencocokkan lebih banyak baris.

  • Perbedaan performa pada beberapa contoh mungkin tidak signifikan karena ukuran set data kecil. Semakin besar set data, semakin besar peningkatan performa.

Pencarian teks penuh
  • Hitung baris di mana kolom comment berisi OLAP.

    • Menghitung jumlah baris di kolom comment yang berisi OLAP menggunakan operator LIKE memerlukan waktu 0,18 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • Pencarian teks penuh MATCH_ANY berbasis indeks terbalik menghitung jumlah baris di kolom comment yang berisi OLAP dalam 0,02 detik. Ini 9 kali lebih cepat dibandingkan menggunakan operator LIKE.

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

    • Operasi ini menghitung jumlah baris di kolom comment yang berisi OLTP menggunakan operator LIKE dan memerlukan waktu 0,07 detik.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • Pencarian teks penuh MATCH_ANY berbasis indeks terbalik menghitung jumlah baris di kolom comment yang berisi OLTP dalam 0,01 detik. Ini 7 kali lebih cepat dibandingkan menggunakan operator LIKE.

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

    • Menggunakan LIKE, kueri memerlukan 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)
    • Menggunakan pencarian teks penuh dengan MATCH_ALL, kueri memerlukan waktu 0,01 detik, sehingga 13 kali lebih cepat dibandingkan menggunakan LIKE.

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

    • Menggunakan LIKE, kueri memerlukan 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)
    • Menggunakan pencarian teks penuh dengan MATCH_ANY, kueri memerlukan waktu 0,01 detik, sehingga 12 kali lebih cepat dibandingkan menggunakan LIKE.

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

Kueri kesetaraan dan rentang

  • Bandingkan performa kueri rentang pada kolom DateTimeV2.

    1. Tanpa indeks terbalik, kueri untuk menghitung baris di mana timestamp lebih besar dari 2007-08-23 04:17:00 memerlukan 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. Tambahkan indeks terbalik ke kolom timestamp.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Periksa progres pembuatan indeks. Selisih antara FinishTime dan CreateTime menunjukkan bahwa pembuatan indeks terbalik untuk 1 juta baris pada kolom timestamp hanya memerlukan waktu 1 detik.

      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, menjalankan kueri yang sama untuk menghitung data dengan kolom timestamp lebih besar dari 2007-08-23 04:17:00 hanya memerlukan waktu 0,01 detik—peningkatan 2 detik dibandingkan kecepatan kueri tanpa indeks terbalik.

      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 kolom numerik.

    1. Tanpa indeks terbalik, kueri untuk menghitung baris di mana kolom parent sama dengan 11189 memerlukan waktu 0,01 detik.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Buat indeks terbalik pada kolom numerik parent tanpa pemisah kata.

      -- Untuk tipe numerik, Anda tidak perlu menentukan pemisah kata saat menggunakan INVERTED.
      -- ALTER TABLE ... ADD INDEX adalah sintaks alternatif untuk membuat indeks.
      ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Periksa progres 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. Jalankan kueri yang sama lagi. Waktu kueri tetap 0,01 detik, menunjukkan tidak ada perubahan signifikan untuk set data ini.

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

    1. Tanpa indeks terbalik, kueri untuk menghitung baris di mana kolom author sama dengan 'faster' memerlukan 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 pada kolom author tanpa pemisah kata.

      -- Pada contoh ini, hanya USING INVERTED yang ditentukan. Nilai di kolom author tidak ditokenisasi, dan setiap nilai diperlakukan sebagai satu istilah.
      ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Periksa progres pembuatan indeks.

      -- Hanya memerlukan waktu 1,5 detik untuk membuat indeks secara inkremental pada kolom author dengan 1 juta baris 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 membuat indeks, kueri hanya memerlukan waktu 0,01 detik, sehingga 3 kali lebih cepat.

      -- Setelah indeks dibuat, pencocokan kesetaraan 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 memecah string teks menjadi urutan istilah. Tokenisasi merupakan komponen inti dalam membangun dan menggunakan indeks terbalik. Kualitas tokenisasi secara langsung memengaruhi performa indeks.

Untuk melihat bagaimana string teks ditokenisasi, gunakan fungsi TOKENIZE untuk melihat hasilnya. Fungsi TOKENIZE memiliki dua parameter utama: parser dan parser_mode. Tabel berikut menjelaskan parameter-parameter tersebut.

Parameter

Deskripsi

parser

Menentukan pemisah kata yang digunakan. Jika parameter ini dihilangkan, fungsi tidak melakukan tokenisasi.

  • english: Pemisah kata bahasa Inggris. Cocok untuk bidang yang berisi teks bahasa Inggris. Melakukan tokenisasi teks berdasarkan spasi dan tanda baca serta menawarkan performa tinggi.

  • chinese: Pemisah kata bahasa Tiongkok. Cocok untuk bidang yang berisi teks Tiongkok. Performanya lebih lambat dibandingkan pemisah kata bahasa Inggris.

  • unicode: Pemisah kata bahasa campuran. Cocok untuk teks campuran, seperti Tiongkok dan Inggris. Melakukan tokenisasi awalan dan akhiran email, alamat IP, serta string alfanumerik. Juga melakukan tokenisasi teks Tiongkok per karakter.

parser_mode

Menentukan mode tokenisasi, yang mengatur granularitas tokenisasi.

Semua pemisah kata menggunakan mode coarse_grained secara default. Mode ini cenderung membagi teks menjadi kata yang lebih panjang. Misalnya, string '武汉市长江大桥' dibagi menjadi dua kata: '武汉市' dan '长江大桥'.

Ketika parser=chinese ditentukan untuk pemisah kata Tiongkok, mode fine_grained juga didukung. Mode fine_grained cenderung membagi teks menjadi kata yang lebih pendek. Misalnya, '武汉市长江大桥' ditokenisasi menjadi enam kata: '武汉', '武汉市', '市长', '长江', '长江大桥', dan '大桥'.

Contoh:

-- Hasil tokenisasi 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 fine-grained dari pemisah kata Tiongkok.
SELECT TOKENIZE('武汉长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-----------------------------------------------------------------------------------+
| tokenize('武汉长江大桥', '"parser"="chinese","parser_mode"="fine_grained"')       |
+-----------------------------------------------------------------------------------+
| ["武汉", "武汉长江大桥", "长江", "长江大桥", "大桥"]                              |
+-----------------------------------------------------------------------------------+
1 row in set (0.02 sec)

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

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