【オリジナル】MariaDB実装関数インデックス


MySQLは関数インデックスを一時的にサポートしていないことを知っています.現在、ほとんどのデータベースにはPostgreSQL、Oracleなどがサポートされています.関数インデックスとは?
関数インデックスとは、ある固定関数を使用してカラムにこの関数結果セットに基づくインデックスツリーを生成することです.利点は開発者がSQLを書くのが勝手で簡単になったことですが、悪い点もそうで、固定条件による読み取りフィルタリングを書かなければなりません.
以前は、このような機能を実装するには、MySQLが新しいカラムを作成し、プリトリガでカラムの値を変更する必要がありました.今、MariaDBには仮想カラムの特性があり、この目的を実現するのに便利です.
まず、PostgreSQLのテーブル構造を見てみましょう.
t_girl=# \d email_list;
             Table "public.email_list"
  Column  |            Type             | Modifiers
----------+-----------------------------+-----------
 id       | integer                     |
 email    | character varying(200)      |
 log_time | timestamp without time zone |
Indexes:
    "idx_email_suffix" btree (substr(email::text, "position"(email::text, '@'::text) + 1))

このテーブルのEMAIL列のプロパティには、163、GMAILなど、次のEMAILプロパティがどのプロバイダに属しているかを調べるための関数インデックスがあります.
私たちは表に20 W行の記録を作った.
t_girl=# select count(*) from email_list;
 count 
--------
 200000
(1 row)
Time: 39.851 ms

対応するクエリーを行います.この関数の作成仕様に厳格に従わないと、クエリはインデックス化されないので、SQLを厳格に書かなければなりません.
 
QUERY PLAN                                                             
--------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=1607.19..1607.20 rows=1 width=12) (actual time=5.514..5.514 rows=1 loops=1)
   ->  Bitmap Heap Scan on email_list  (cost=48.29..1602.08 rows=2047 width=12) (actual time=1.126..4.806 rows=1960 loops=1)
         Recheck Cond: (substr((email)::text, ("position"((email)::text, '@'::text) + 1)) = '56.com'::text)
         ->  Bitmap Index Scan on idx_email_suffix  (cost=0.00..47.78 rows=2047 width=0) (actual time=0.802..0.802 rows=1960 loops=1)
               Index Cond: (substr((email)::text, ("position"((email)::text, '@'::text) + 1)) = '56.com'::text)
 Total runtime: 5.603 ms
(6 rows)
Time: 6.601 ms

クエリー分析計画から,この関数インデックスを用いて約2 K行のレコードをスキャンし,結果セット1960行を生成した.
t_girl=# select count(email) as num from email_list where substr(email,position('@' in email)+1)='56.com';
 num 
------
 1960
(1 row)
Time: 5.251 ms
t_girl=#

次に、MariaDBで対応する機能をどのように実現するかを見てみましょう.
表の構造は次のとおりです.
MariaDB [t_girl]> show create table email_list;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| email_list | CREATE TABLE `email_list` (
  `id` int(11) DEFAULT NULL,
  `email` varchar(200) DEFAULT NULL,
  `log_time` datetime(6) DEFAULT NULL,
  `email_suffix` varchar(100) AS (substr(email,position('@' in email)+1)) PERSISTENT,
  KEY `idx_email_suffix` (`email_suffix`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

ここではMariaDBの仮想カラムを用い,仮想カラムにpersistent属性を指定することで,真の属性として扱うことができる.
行、次はこの仮想列を利用してクエリーを行いますが、逆に簡単で、クエリー文はそんなに厳しくなく、普通の文と同じです.
MariaDB [t_girl]> explain select count(email) from email_list where email_suffix = '56.com';
+------+-------------+------------+------+------------------+------------------+---------+-------+------+-----------------------+
| id   | select_type | table      | type | possible_keys    | key              | key_len | ref   | rows | Extra                 |
+------+-------------+------------+------+------------------+------------------+---------+-------+------+-----------------------+
|    1 | SIMPLE      | email_list | ref  | idx_email_suffix | idx_email_suffix | 103     | const | 1959 | Using index condition |
+------+-------------+------------+------+------------------+------------------+---------+-------+------+-----------------------+
1 row in set (0.02 sec)

検索速度ももちろん速いです.
MariaDB [t_girl]> select count(email) from email_list where email_suffix = '56.com';        
+--------------+
| count(email) |
+--------------+
|         1960 |
+--------------+
1 row in set (0.02 sec)

本文は「神様、私たちは会わないと散らない!」から出た.ブログは、必ずこの出典を残してくださいhttp://yueliangdao0608.blog.51cto.com/397025/1389861