Tüm Ürünler
Search
Belge Merkezi

ApsaraDB for SelectDB:Ters dizin

Son Güncelleme:Oct 08, 2026

Ters dizin, bilgi erişim alanında yaygın olarak kullanılan bir dizinleme tekniğidir. Metni terimlere ayırarak bir dizin oluşturur ve bu terimleri içeren belgelerin hızlıca bulunmasını sağlar.ApsaraDB for SelectDB ters dizinleri destekler. Bu özelliği kullanarak metin veri türlerinde tam metin araması yapabilir; sayısal ve tarih veri türlerinde eşitlik ile aralık sorguları çalıştırabilirsiniz. Bu sayede büyük veri kümelerinden istenen verileri hızla filtreleyebilirsiniz. Bu konu, ApsaraDB for SelectDB içindeki ters dizin özelliğini, oluşturma ve kullanım yöntemlerini kapsayacak şekilde açıklar.

Çalışma prensibi

Alibaba Cloud SelectDB ortamında ters dizin, tablo satırını bir belge, sütunu ise bir alan olarak ele alır. Bu yaklaşım, belirli bir anahtar kelimeyi içeren satırların hızla bulunmasını sağlayarak WHERE yan tümcesi kullanan sorguların performansını artırır.

Standart dizinlerden farklı olarak ters dizin, ayrı bir ters dosyada saklanır. Bu dosya mantıksal olarak segment dosyasıyla eşlenir ancak onunla bütünleşik değildir. Bu yöntem, dizin güncellemeleri ve silme işlemleri için segment dosyasının yeniden yazılmasını önleyerek işlem yükünü önemli ölçüde azaltır.

Kullanım senaryoları

  • Dize veri türlerinde tam metin aramasını hızlandırır.

  • Dize, sayısal ve datetime türleri için =, !=, >, >=, <, <= filtreleme işlemlerini hızlandırır.

Avantajlar

  • Mantıksal operatörler için kapsamlı destek sunar.

    • OR ve NOT mantığı için dizin aktarımı (index pushdown) desteği eklenmiştir.

    • Birden çok koşulun herhangi bir AND, OR ve NOT kombinasyonunu destekler.

  • Esnek ve hızlı dizin yönetimi sağlar.

    • Tablo oluştururken ters dizin tanımlayın.

    • Mevcut bir tabloya ters dizin ekleyin.

    • Tablodan ters dizini silin.

Sınırlamalar

  • Hassasiyet sorunları nedeniyle FLOAT ve DOUBLE kayan nokta veri türleri ters dizini desteklemez. Bunun yerine, ters dizini destekleyen DECIMAL sabit nokta veri türünü kullanın.

  • MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE ve AGG_STATE gibi bazı karmaşık veri türleri ters dizini desteklemez. JSON verilerinde ters dizin kullanmak için sütunu VARIANT veri türüne dönüştürün.

  • Sayısal türdeki bir alanda ters dizin oluşturabilirsiniz ancak english, chinese veya unicode gibi bir parser belirtemezsiniz.

  • DUPLICATE modeli ve Write sırasında Birleştirme (Merge on Write) özelliği etkin olan UNIQUE modeli, herhangi bir sütunda ters dizini destekler. Buna karşılık, AGGREGATE modeli ve Write sırasında Birleştirme özelliği devre dışı olan UNIQUE modeli yalnızca Anahtar (Key) sütununda ters dizini destekler. Bu modeller tüm verileri okuyup birleştirmek zorunda olduğundan sistem dizini ön filtreleme için kullanamaz.

Dizin oluşturma

Ters dizini tablo oluşturma sırasında veya mevcut bir tablodaki bir sütun üzerinde oluşturabilirsiniz.

Tablo oluşturma sırasında dizin ekleme

Bu işlem senkron olarak gerçekleşir. Tablo başarıyla oluşturulduğunda dizin oluşturma işlemi de tamamlanır.

Önemli

Ters dizinler farklı veri modellerinde aşağıdaki sınırlamalara sahiptir:

  • Toplama anahtarı modeli için ters dizini yalnızca anahtar sütunlarda oluşturabilirsiniz.

  • Benzersiz anahtar modelinde Write sırasında Birleştirme özelliğinin etkin olması gerekir. Özellik etkinleştirildiğinde ters dizini herhangi bir sütunda oluşturabilirsiniz.

  • Yinelenen anahtar modeli için ters dizini herhangi bir sütunda oluşturabilirsiniz.

Sözdizimi

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

Parametreler

Tablo oluşturma parametreleri

Parametre

Zorunlu

Açıklama

db_name

Hayır

Tabloyu içerecek veritabanının adı.

table_name

Evet

Oluşturulacak tablonun adı.

column_definition_list

Evet

Sütun tanımlarının listesi. Daha fazla bilgi için bkz. CREATE-TABLE.

table_properties

Evet

Veri modeli, bölümleme ve paketleme gibi tablo özellikleri. Daha fazla bilgi için bkz. veri modeli.

index_definition_list

Hayır

Dizin tanımlarının listesi.

index_definition_list

Tablo oluştururken bir veya daha fazla dizin tanımlayabilirsiniz. Aşağıdaki biçimi kullanın: index_definition[, index_definition][, index_definition]....

index_definition

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

Parametreler

Zorunlu parametreler


Parametre


Açıklama


index_name


Dizin adı.


column_name


Dizinlenecek sütunun adı.


index_type


Dizin türü. Değeri USING INVERTED olarak ayarlayın.

İsteğe bağlı parametreler

Özellikler

PROPERTIES yan tümcesi, dizin için belirteç ayrıştırma seçeneklerini belirtir. Virgülle ayrılmış bir veya daha fazla anahtar-değer çiftinden oluşur ve biçimi "<key>" = "<value>" şeklindedir. Belirli bir metnin nasıl belirteçlere ayrılacağından emin değilseniz çıktıyı görüntülemek için TOKENIZE işlevini kullanın. Daha fazla bilgi için bkz. Belirteç ayrıştırma işlevleri.

Anahtar

Değer

parser

Belirteç ayrıştırıcıyı belirtir. Bu özellik atlanırsa belirteç ayrıştırma işlemi gerçekleşmez. parser özelliği sayısal veri türleri için desteklenmez.

  • english: İngilizce belirteç ayrıştırıcı. İngilizce metinler için idealdir; yüksek performanslı bu ayrıştırıcı kelimeleri boşluklara ve noktalama işaretlerine göre ayırır.

  • chinese: Çince belirteç ayrıştırıcı. Çince karakterler içeren metinler için uygundur. Performansı İngilizce ayrıştırıcıya göre daha düşüktür.

  • unicode: Unicode belirteç ayrıştırıcı. Çince ve İngilizce gibi karışık dilli metinler için uygundur. E-posta ön eklerini ve son eklerini, IP adreslerini ve alfasayısal dizeleri belirteçlere ayırabilir. Ayrıca Çince metni karakter karakter ayırır.

parser_mode

Belirteçlerin ayrıştırılma modunu, yani ayrıştırma granülerliğini belirtir.

Tüm belirteç ayrıştırıcılar varsayılan olarak coarse_grained modunu kullanır. Bu mod metni daha uzun kelimelere bölmeye eğilimlidir. Örneğin, 'Wuhan City Yangtze River Bridge' ifadesi 'Wuhan City' ve 'Yangtze River Bridge' olmak üzere iki kelimeye ayrılır.

Çince ayrıştırıcı için parser=chinese belirtildiğinde fine_grained modu da desteklenir. Bu mod metni daha kısa kelimelere ayırmaya eğilimlidir. Örneğin, 'Wuhan City Yangtze River Bridge' ifadesi 'Wuhan', 'Wuhan City', 'mayor', 'Yangtze River', 'Yangtze River Bridge' ve 'Bridge' olmak üzere altı belirtece ayrılır.

Belirteç ayrıştırmanın nasıl çalıştığı hakkında daha fazla bilgi edinmek için bkz. Belirteç ayrıştırma işlevleri.

support_phrase

Dizinin hızlandırılmış MATCH_PHRASE ifade sorgularını destekleyip desteklemediğini belirtir. Varsayılan değer false olur.

  • true: Destek etkinleştirilir; bu durum daha fazla depolama alanı gerektirir.

  • false: Depolama alanından tasarruf etmek için destek devre dışı bırakılır. Birden çok terimi sorgulamak için MATCH_ALL kullanabilirsiniz.

char_filter

Belirteçlere ayırmadan önce dizeleri ön işleme tabi tutar. Şu anda char_filter_type yalnızca char_replace değerini destekler.

char_replace, char_filter_pattern içindeki her karakteri char_filter_replacement değerindeki karşılık gelen karakterle değiştirir.

  • char_filter_pattern: Değiştirilecek karakterlerin dizisi.

  • Bu özellik isteğe bağlıdır; atlandığında varsayılan olarak tek bir boşluk karakteri kullanılır.

ignore_above

Belirteçlere ayrılmayan dize değerleri için (parser belirtilmediğinde) bir uzunluk sınırı belirtir.

  • Sistem, ignore_above değerinden uzun dizeleri dizine almaz. Dize dizileri için bu sınır her bir öğe için geçerlidir.

  • Varsayılan: 256 (bayt).

lower_case

Büyük/küçük harfe duyarlı olmayan eşleştirme için belirteçlere ayrılmış terimleri küçük harfe dönüştürüp dönüştürmeyeceğini belirtir.

  • true: Küçük harfe dönüştürür.

  • false: Orijinal büyük/küçük harf yapısını korur.

stopwords

Belirteç ayrıştırıcının davranışını etkileyen durdurma sözcüklerinin listesini belirtir.

  • Yerleşik liste; sistemin dizinleme ve sorgulama sırasında yoksaydığı yaygın, düşük değerli sözcükleri (is, the ve a gibi) içerir.

  • none: Boş bir durdurma sözcükleri listesi kullanır.

dict_compression

Ters dizinin sözlüğü için Zstandard (ZSTD) sözlük sıkıştırmasının etkinleştirilip etkinleştirilmeyeceğini belirtir.

  • true: Sözlük sıkıştırmasını etkinleştirir.

  • false: (Varsayılan) Sözlük sıkıştırmasını devre dışı bırakır.

  • Öneri: Büyük metin veya günlük iş yüklerinde ya da depolama maliyetlerini düşürmek için bu özelliği etkinleştirin. En iyi performansı inverted_index_storage_format = "V3" ile birlikte verir ve büyük ölçekli metin ve günlük verileri için depolama alanını yaklaşık %20 oranında azaltabilir.

Not

Bu parametre yalnızca 4.1.0 ve sonraki sürümlerde desteklenir.

Açıklama


Parametre


Açıklama


comment


Dizin açıklaması.

Örnek: Dizin içeren tablo oluşturma

-- Create a table and an inverted index named idx_comment on the comment column.
-- USING INVERTED sets the index type to inverted index.
-- PROPERTIES("parser" = "english") sets the tokenizer to "english". Other supported tokenizers include "chinese" for Chinese text and "unicode" for mixed-language text. If the "parser" property is omitted, no tokenization occurs.
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;

Dizin ekleme

Bu işlem asenkron olarak gerçekleşir. Dizin oluşturma ilerlemesini SHOW ALTER TABLE COLUMN; komutunu kullanarak kontrol edebilirsiniz.

Sözdizimi

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

Parametreler

Parametreler, tablo oluşturma parametreleriyle aynıdır.

Örnekler

Belirteç ayrıştırma olmadan dizin ekleyin.

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

Belirteç ayrıştırma için english kullanan bir dizin ekleyin.

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

Ters dizinleri görüntüleme

Dizin değişikliği ilerlemesini görüntüleme

ALTER ve DROP komutlarını kullanarak ters dizini değiştirmek asenkron bir süreçtir. İlerlemeyi görüntülemek için aşağıdaki deyimi kullanın.

SHOW ALTER TABLE COLUMN;

Tüm tablo ters dizinlerini görüntüleme

Sözdizimi

SHOW INDEXES FROM <table_name>;

Örnek

SHOW INDEXES FROM user_tb;

Dizin silme

Dizin silme asenkron bir süreçtir. İlerlemeyi kontrol etmek için bkz. Ters dizinler hakkında bilgi sorgulama.

Önemli

Dizin silmek sorgu performansını düşürebilir. Dikkatli olun.

Sözdizimi

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

Örnek

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

Ters dizin

Tam metin araması

Sözdizimi

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

Parametreler

Parametre

Zorunlu

Açıklama

table_name

Evet

Tablo adı.

column_name

Evet

Sütun adı.

conditional_logic

Evet

Arama operatörleri ve mantıksal operatörlerin kombinasyonu.

Mantıksal operatörler: AND, OR ve NOT.

Arama operatörleri:

  • MATCH_ALL: Belirtilen tüm anahtar kelimeleri içeren satırları döndürür.

  • MATCH_ANY: Belirtilen anahtar kelimelerden herhangi birini içeren satırları döndürür.

  • MATCH_PHRASE: Tam ifadeyi içeren satırları döndürür.

keywords

Evet

Arama anahtar kelimeleri.

Birden çok anahtar kelimeyi boşlukla ayırın.

Örnek: keyword1 keyword2 keyword3.

Örnekler

-- Retrieve rows where logmsg contains keyword1.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';

-- Retrieve rows where logmsg contains keyword1 or keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';

-- Retrieve rows where logmsg contains both keyword1 and keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';

-- Retrieve rows where logmsg contains the exact phrase "keyword1 keyword2".
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';

Sayısal ve tarih türleri için eşitlik ve aralık sorguları

Sorgu sözdizimi standart SQL sözdizimidir.

Örnek

-- Equality, range, IN, and NOT IN queries
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');

Sorgu performansı karşılaştırması

Bu konuda, ters dizin kullanımıyla ve kullanılmadan sorgu performansını karşılaştırmak amacıyla 1 milyon satırlık bir hackernews veri kümesi kullanılmaktadır.

Ön koşullar

Adım 1: Tablo oluşturun.

  1. Veritabanı oluşturun.

    CREATE DATABASE test_inverted_index;
  2. Oluşturulan veritabanına geçin.

    USE test_inverted_index;
  3. Hedef tabloyu oluşturun.

    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;
    -- Creates a table and an inverted index named idx_comment on the comment column.
    -- USING INVERTED specifies that the index type is an inverted index.
    -- PROPERTIES("parser" = "english") specifies that the English tokenizer is used. You can also specify "chinese" for Chinese text or "unicode" for mixed-language text. If you do not specify the "parser" parameter, no tokenization is performed.

Adım 2: Verileri içe aktarın

  1. Veri dosyasını indirin.

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Verileri Stream Load kullanarak içe aktarın.

    ApsaraDB for SelectDB örnek ayrıntıları sayfasında ApsaraDB for SelectDB örneğinin uç nokta ana bilgisayarını ve bağlantı noktası numarasını görüntüleyebilirsiniz. Stream Load hakkında daha fazla bilgi için bkz. 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. Veri içe aktarmayı doğrulamak için bir count() sorgusu çalıştırın.

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

Performans karşılaştırması

Not
  • Belirteç ayrıştırıcı kullanan ters dizinli sorgular ile belirteç ayrıştırıcı kullanmayan sorgular arasında sayım sonuçları farklılık gösterebilir. Bunun nedeni, ters dizinin sütun verilerini belirteçlere ayırması ve terimleri normalleştirmesidir (örneğin küçük harfe dönüştürmesi); bu durum dizin kullanan sorguların daha fazla satırla eşleşmesine neden olabilir.

  • Bazı örneklerdeki performans farkı veri kümesi küçük olduğu için önemli olmayabilir. Veri kümesi büyüdükçe performans iyileşmesi daha belirgin hale gelir.

Tam metin araması

  • comment sütununun OLAP içerdiği satırları sayın.

    • comment sütununda OLAP içeren satır sayısını LIKE operatörü kullanarak saymak 0,18 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • Ters dizine dayalı MATCH_ANY tam metin araması, comment sütununda OLAP içeren satır sayısını 0,02 saniyede hesaplar. Bu süre, LIKE operatörünü kullanmaya göre 9 kat daha hızlıdır.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 row in set (0.02 sec)
  • comment sütununun OLTP içerdiği satırları sayın.

    • Bu işlem, comment sütununda OLTP içeren satır sayısını LIKE operatörü kullanarak sayar ve 0,07 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • Ters dizine dayalı MATCH_ANY tam metin araması, comment sütununda OLTP içeren satır sayısını 0,01 saniyede hesaplar. Bu süre, LIKE operatörünü kullanmaya göre 7 kat daha hızlıdır.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • comment sütununun hem OLAP hem de OLTP içerdiği satırları sayın.

    • LIKE kullanıldığında sorgu 0,13 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • MATCH_ALL ile tam metin araması kullanıldığında sorgu 0,01 saniye sürer; bu da LIKE kullanımına göre 13 kat daha hızlıdır.

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • comment sütununun OLAP veya OLTP içerdiği satırları sayın.

    • LIKE kullanıldığında sorgu 0,12 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • MATCH_ANY ile tam metin araması kullanıldığında sorgu 0,01 saniye sürer; bu da LIKE kullanımına göre 12 kat daha hızlıdır.

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

Eşitlik ve aralık sorguları

  • DateTimeV2 sütununda bir aralık sorgusunun performansını karşılaştırın.

    1. Ters dizin olmadan, timestamp değeri 2007-08-23 04:17:00 değerinden büyük olan satırları sayan bir sorgu 0,03 saniye sürer.

       SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.03 sec)
    2. timestamp sütununa ters dizin ekleyin.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Dizin oluşturma ilerlemesini kontrol edin. FinishTime ile CreateTime arasındaki fark, timestamp sütunundaki 1 milyon satır için ters dizin oluşturmanın yalnızca 1 saniye sürdüğünü gösterir.

      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. Ters dizin oluşturulduktan sonra, timestamp sütunu 2007-08-23 04:17:00 değerinden büyük olan verileri sayan aynı sorguyu çalıştırmak 0,01 saniye sürer. Bu, ters dizin olmadan yapılan sorguya kıyasla 2 saniyelik bir iyileşmedir.

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.01 sec)
  • Sayısal bir sütunda eşitlik sorgusunun performansını karşılaştırın.

    1. Ters dizin olmadan, parent sütunu 11189 değerine eşit olan satırları sayan bir sorgu 0,01 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Belirteç ayrıştırıcı olmadan sayısal parent sütununda ters dizin oluşturun.

      -- For numeric types, you do not need to specify a tokenizer when using INVERTED.
      -- ALTER TABLE ... ADD INDEX is an alternative syntax for creating an index.
      ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Dizin oluşturma ilerlemesini kontrol edin.

      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. Aynı sorguyu tekrar çalıştırın. Bu veri kümesi için sorgu süresi 0,01 saniye olarak kalır ve önemli bir değişiklik göstermez.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • Dize sütununda eşitlik sorgusunun performansını karşılaştırın.

    1. Ters dizin olmadan, author sütunu 'faster' değerine eşit olan satırları sayan bir sorgu 0,03 saniye sürer.

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. Belirteç ayrıştırıcı olmadan author sütununda ters dizin oluşturun.

      -- In this example, only USING INVERTED is specified. The values in the author column are not tokenized, and each value is treated as a single term.
      ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Dizin oluşturma ilerlemesini kontrol edin.

      -- It takes only 1.5s to incrementally create an index on the author column with 1 million rows of 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. Dizin oluşturulduktan sonra sorgu yalnızca 0,01 saniye sürer; bu da 3 kat daha hızlı olduğunu gösterir.

      -- After the index is created, string equality matching is also significantly accelerated.
      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.01 sec)

Belirteç ayrıştırma işlevi

TOKENIZE işlevi, bir metin dizisini terim dizisine ayırır. Belirteçlere ayırma, ters dizin oluşturmanın ve kullanmanın temel bileşenidir. Belirteçlere ayırma kalitesi dizin performansını doğrudan etkiler.

Bir metin dizisinin nasıl belirteçlere ayrıldığını görmek için sonucu görüntülemek amacıyla TOKENIZE işlevini kullanın. TOKENIZE işlevinin iki ana parametresi vardır: parser ve parser_mode. Aşağıdaki tabloda bu parametreler açıklanmaktadır.

Parametre

Açıklama

parser

Kullanılacak belirteç ayrıştırıcıyı belirtir. Bu parametre atlanırsa işlev belirteçlere ayırma işlemi gerçekleştirmez.

  • english: İngilizce belirteç ayrıştırıcı. İngilizce metin içeren alanlar için uygundur. Metni boşluklara ve noktalama işaretlerine göre ayırır ve yüksek performans sunar.

  • chinese: Çince belirteç ayrıştırıcı. Çince metin içeren alanlar için uygundur. İngilizce ayrıştırıcıya göre daha yavaş çalışır.

  • unicode: Karışık dil belirteç ayrıştırıcı. Çince ve İngilizce gibi karışık dilli metinler için uygundur. E-posta ön eklerini ve son eklerini, IP adreslerini ve alfasayısal dizeleri belirteçlere ayırır. Ayrıca Çince metni karakter karakter ayırır.

parser_mode

Belirteçlere ayırma modunu, yani ayrıştırma granülerliğini belirtir.

Tüm belirteç ayrıştırıcılar varsayılan olarak coarse_grained modunu kullanır. Bu mod metni daha uzun kelimelere bölmeye eğilimlidir. Örneğin, '武汉市长江大桥' dizisi '武汉市' ve '长江大桥' olmak üzere iki kelimeye ayrılır.

Çince ayrıştırıcı için parser=chinese belirtildiğinde fine_grained modu da desteklenir. Fine_grained modu metni daha kısa kelimelere ayırmaya eğilimlidir. Örneğin, '武汉市长江大桥' ifadesi '武汉', '武汉市', '市长', '长江', '长江大桥' ve '大桥' olmak üzere altı kelimeye ayrılır.

Örnekler:

-- English tokenization result.
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"]                         |
+------------------------------------------------+
1 row in set (0.02 sec)

-- Fine-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-----------------------------------------------------------------------------------+
| tokenize('武汉长江大桥', '"parser"="chinese","parser_mode"="fine_grained"')       |
+-----------------------------------------------------------------------------------+
| ["武汉", "武汉长江大桥", "长江", "长江大桥", "大桥"]                              |
+-----------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- Coarse-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"')        |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"]                                                                 |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

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