【原创】MariaDB 实现函数索引
2014-04-05 00:00
387 查看
我们知道MySQL 暂时不支持函数索引。 目前大部分数据库包括PostgreSQL,Oracle等都支持。 什么是函数索引呢?
函数索引就是说用某固定的函数来对列生成一个基于此函数结果集的索引树。 好处是开发人员写SQL变得随意而且简单了,但是不好的一点也是如此,必须写按照固定条件进行的读取过滤。
在之前呢,如果要实现这样的功能,MySQL 得创建一个新的列,然后用前置触发器来修改此列的值。 现在呢,MariaDB有一个虚拟列的特性可以很方便的来实现这个目的。
先来看下在PostgreSQL中的表结构
这张表的EMAIL列属性上有一个函数索引,目的是来查找次EMAIL属性是属于哪家提供商,比如163,GMAIL等等。
我们给张表产生了20W行记录。
现在来进行对应的查询。 如果不严格按照这个函数的创建规范,查询就不走索引,所以一定要严格来写SQL。
从查询分析计划中看到,走这个函数索引,扫描了大概2K行记录,生成结果集1960行。
接下来,我们看看在MariaDB中如何来实现对应的功能。
表结构如下:
这里我们用到了MariaDB的虚拟列,并且对虚拟列指定persistent属性,这样就能当成真实的属性来看待了。
行,下来我们利用这个虚拟列来进行查询,不过这样反而简单点,查询语句不需要那么严格了,直接跟普通的语句一样。
查询速度当然也就非常快了。
本文出自 “上帝,咱们不见不散!” 博客,请务必保留此出处http://yueliangdao0608.blog.51cto.com/397025/1389861
函数索引就是说用某固定的函数来对列生成一个基于此函数结果集的索引树。 好处是开发人员写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列属性上有一个函数索引,目的是来查找次EMAIL属性是属于哪家提供商,比如163,GMAIL等等。
我们给张表产生了20W行记录。
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
从查询分析计划中看到,走这个函数索引,扫描了大概2K行记录,生成结果集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
相关文章推荐
- 【原创】MariaDB 实现函数索引
- MariaDB 实现函数索引
- 【原创】oracle函数INSTR的MySQL实现
- 经典的js问题 实现点击li能够弹出当前li索引与innerHTML的函数
- 【原创】用C实现Trim()函数
- [原创]18行代码实现无限级填充TreeView的例子与函数
- [原创] 编写函数,实现对链表元素的排序与分类
- 【原创】ORACLE的几个函数在MYSQL里面的简单实现
- 模版函数指针,C++委托的实现-原创
- phpcms 实现自动加载所有函数文件【原创】
- 【原创】MySQL 以及 Python 实现排名窗口函数
- oracle 实现基于函数的索引
- [原创] 实现函数y=x2的图形与圆的图形叠加显示
- 自己实现mysql “函数索引”
- SQLServer中间接实现函数索引或者Hash索引
- STL sort 函数实现详解 作者:fengcc 原创作品 转载请注明出处 前几天阿里电话一面,被问到STL中sort函数的实现。以前没有仔细探究过,听人说是快速排序,于是回答说用快速排序实现的
- 探索c++的函数pow()的实现方法·数学与程序设计的结合(绝对原创)
- 模版函数指针,C++委托的实现-原创
- (原创)PHP利用iconv()函数实现任何编码之间的转换
- 模版函数指针,C++委托的实现-原创