想法非常简单,在标准的B-Tree索引上创建一个伪哈希索引。它和真正的哈希索引不是一回事,因为它还是使用B-Tree索引进行查找。然而,它将会使用键的哈希值进行查找,而不是键自身。你所要做的事情就是在where子句中手动地定义哈希函数。

例子:URL查找。

URL通常会导致B-Tree索引变大,因为它们非常长。通常会按照下面的方式来查找URL表。

mysql>select id from url where url='http://www.mysql.com';

但是,如果移除掉url列上的索引并且给表添加一个被索引的url_src列,就可以按照下面的方式进行查询:

mysql>select id from url where url='http://www.mysql.com' and url_src=CRC32('http://www.mysql.com');

mysql查询优化器注意到url_src列上有很小的,选择性很高的索引,并且它会使用里面的值进行索引查找。即使有几列相同的url_src值,也很容易进行精确的对比来确定需要的行。替代方案是把完整的URL索引为字符串,它要慢很多。

这个办法的一个缺点就是要维护哈希值。你可以手工进行维护,在mysql5.0 以上版本中,可以使用触发器来进行维护。

1.创建一个表:

create table pseudohash(

  1. id int unsigned NOT NULL auto_increment,
  2. url varchar(255) NOT NULL,
  3. url_src int unsigned NOIT NULL DEFAULT 0,
  4. PRIMARY KEY(id)
  5. );

接下来创建触发器。我们先暂时更新一下命令分隔符,这样就可以在触发器中使用分号:

DELIMITER |

  1. CREATE TRIGGER pseudohash_src_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN SET NEW.url_src = crc32(NEW.url);
  2. END;
  3. |
  4. CREATE TRIGGER pseudohash_src_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN SET NEW.url_src = crc32(NEW.url);
  5. END;
  6. |
  7. DELIMITER;

剩下的工作就是验证触发器自动维护了哈希值。

如果使用这种方式,就不应该使用SHA1()和MD5()这此哈希函数。它们返回很长的字符串,会浪费大量的存储空间并且减慢比较速度。它们是强加密函数,被设计为不产生任务冲突。这并不是我们的目标。简单的哈希函数能在有较好性能的同时保证可接受的冲突率。当然,如果表有很多行并且CRC32()产生了很多冲突,就要实现自己的64位哈希函数,要确保自己的函数返回整数,而不是字符串。

mysql>select conv(right(md5('http://www.mysql.com/'),16),16,10) as hash64;

mysql优化之伪哈希索引的更多相关文章

  1. MySQL技巧--伪哈希索引

    哈希索引 哈希索引就是通过一个哈希函数计算出某个key的hash值,并以这个hash值去找到目标数据.例如:对于数据库的一行数据,对其主键进行hash运算,得到一个地址,这个地址指向这行记录的存储地址 ...

  2. mysql在B-Tree上创建伪哈希索引

    构建哈希的过程 select过程 长字符串下,构建索引可通过自定义哈希作为索引,本人通过实验,在3百多个数据记录的下,性能效果很明显,完全不是一个等级.以下为索引前后几种情况对比 无索引的url:直接 ...

  3. MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描

    满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引 ...

  4. MySQL中的自适应哈希索引

    众所周知,InnoDB使用的索引结构是B+树,但其实它还支持另一种索引:自适应哈希索引. 哈希表是数组+链表的形式.通过哈希函数计算每个节点数据中键所对应的哈希桶位置,如果出现哈希冲突,就使用拉链法来 ...

  5. MySql优化-你的SQL命中索引了吗

    在项目开发中SQL是必不可少的,表索也一样.这些SQL的运行性能不知道吗?有多少是命中了索引的?命中哪个索引?索引中有哪个是无效索引?这些无效索引是否会影响系统的性能?带着这些问题我们一起来学习一下. ...

  6. 《Mysql - 优化器是如何选择索引的?》

    一:概念 - 在 索引建立之后,一条语句可能会命中多个索引,这时,索引的选择,就会交由 优化器 来选择合适的索引. - 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句. 二: ...

  7. mysql优化-------Myisam与innodb引擎,索引文件的区别

    Myisam与innodb引擎,索引文件的区别: innodb的次索引指向对主键的引用. myisam的次索引和主索引都指向物理行. myisam一行一行的插入,会产生一行一行的文件,磁盘上有数据文件 ...

  8. Mysql优化-为表字段添加索引

    1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) : ALTE ...

  9. mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)

    没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...

随机推荐

  1. linux下nginx安裝

    1.yum安裝 yum安裝  http://nginx.org/packages/centos/7/noarch/RPMS/ 第一步: 安裝命令: yum localinstall http://ng ...

  2. Mac terminal Javac

    Mac  terminal Javac Open the Terminal's vim , then write them: public class test{ public static void ...

  3. scala分析数据作图

    参考网址:https://stackoverflow.com/questions/36984780/spark-shell-how-to-use-breeze-viz 刚开始按照网上的教程只导入了 两 ...

  4. Objective-C语法之NSPredicate的使用

    正则表达式判断手机号码和电话号码的方法: #import <Foundation/Foundation.h> /** 正则判断手机号码地址格式 */ BOOL isMobileNumber ...

  5. 【python】泰语分词器安装

    1.安装icu http://blog.csdn.net/liyuwenjing/article/details/6105388 2.安装pyicu https://anaconda.org/kale ...

  6. VBscript实现开机自动启动,自动复制原件后启动

    set fso = createobject("scripting.filesystemobject") set ws = createobject("wscript.s ...

  7. 2015-10-07:几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右

    最近发现(2015-10-07)几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右

  8. perforce 学习资源

    这两天,要将depot切换到stream 使用,收集了很多perforce的学习资源,在这里记录一下: perforce 官网:  www.perforce.com perforce参考手册:  ht ...

  9. MathType如何设置标尺的单位

    MathType在编辑公式的时候,经常会需要将公式对齐.在将公式对齐的这个过程中,有时候会用到标尺,这样可以更精确的定位公式的位置.我们在使用标尺的时候,有时候会发现标尺上显示的是英寸,而我们平常已经 ...

  10. Android开发学习笔记-splash画面的显示

    贴代码: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=&qu ...