`

Mysql数据库优化学习之二 索引优化(一)

阅读更多
转载请标明出处: http://fuliang.iteye.com/blog/1063352

索引基础知识
索引是帮助MySQL有效检索数据的一种数据结构,它是获得高性能的关键,但是人们常常忘记或者错误的理解了它,所以索引通常是现实中最常出现的性能问题。
当你的数据变得很大时,索引变得非常重要,即使很轻负载的数据库没有恰当的索引,随着数据的增加,性能也会很快的下降。
MySQL使用索引都是一种类似的方式,他首先对给定的值搜索索引结构,如果在索引中找到,再去找包含匹配的行。
当你对多于一行的数据建索引的时候,索引的次序很重要,因为MySQL只能使用索引的最左前缀来有效进行搜索。对两列进行建索引和分别对单个列检索是不同的。

索引类型
有很多类型的索引,每种索引的设计在不同的目的下达到高效,索引是在存储引擎下实现的,并不是在服务层,因此他并没有被标准化:索引在不同的存储引擎不同,不是所有的引擎都支持所有的索引类型。即使多个索引支持同一种索引类型,也可能有不同的实现。

B-Tree索引
当人们谈论索引但没有提及类型时,他们通常指的是B-Tree索引,使用B-Tree的数据结构来存储索引。大多数的存储引擎支持这种索引类型。Archive引擎是个例外,直到5.1还没有支持索引,刚开始支持单索引的AUTO_INCREMENT列。
我们使用"B-Tree"来描述索引,因为CREATE TABLE和其他的语句都使用这个术语,但是不同的存储引擎结构。比如NDB聚类存储引擎使用T-Tree,但是标记BTREE。
不同的存储引擎存储B-Tree索引的方式不同,这会影响性能。比如MyISAM使用前缀压缩技术来让索引变得更小,然后InnoDB并没有压缩索引,因为他不能使用压缩的索引来优化。MyISAM索引直接指向行存储的物理地址,但是InnoDB通过主键的值来引用行,每一种方式都有优缺点。
B-Tree的一般观点是所有的值都有序的存储,每一个节点到根节点都有相同的距离。MyISAM使用不同的结构,但是基本上都是相似的。
由于B-Tree的索引列是有序的,他们对于搜索区间非常有用,比如查找“所有名字以I到K开头的”人,这是很有效的。
可以使用B-Tree索引的类型:B-Tree索引对于查找全部key的值,键的区间或者键的前缀。对
比如有以下表:
CREATE TABLE People (
last_name varchar(50) not null,
first_name varchar(50) not null,
dob date not null,
gender enum('m', 'f') not null,
key(last_name, first_name, dob)
);

于一下集中查询非常有用:
1、匹配全部key的值 匹配所有在索引中的列 where last_name='Allen' and first_name='Cuba' and dob='1960-01-01'
2、最左前缀匹配 where last_name='Cuba' and first_name='Allen'
3.匹配一列的前缀 比如 where last_name like 'J%'
4.匹配一个区间 where last_name between 'Allen' and 'Barrymore'
5.匹配条件中前面的一个条件和区间部分 比如last_name='A' and first_na me like 'J%'
6.仅涉及到index的查询 这种查询只会访问索引,不会访问存储的行。这就是使用覆盖索引优化。select last_name, first_name, dob from People where last_name='Allen'
B-Tree索引的缺陷:
1.如果index的列不是从最左开始,那么索引没有用。
2.不能跳过索引中的一列。比如where last_name='Allen' and dob='1960-01-01'
3.存储引擎不能够优化区间右边的索引,比如:
where last_name='Smith' and first_name like 'J%' and dob='1976-12-23'
索引只能够用到last_name和first_name,因为like是一个区间条件。

所以索引的顺序非常重要,所有这些限制都是和索引的顺序相关。

Hash索引:
hash索引是基于hash表构建的,仅仅对精确查找索引中的列有用。对于每一行,存储引擎
对索引列计算hash code,它在索引中存储hash code和指向行的指针。

在MySQL中,只有Memory存储引擎支持显式的hash索引,是其默认的索引类型,但是Memory表可以使用B-Tree索引。
比如下面的表:
CREATE TABLE testhash (
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
KEY USING HASH(fname)
) ENGINE=MEMORY;

hash索引查询非常的快,然而hash索引有如下缺点:
1.因为索引中只有hash code和指向行的指针,所以MySQL不能直接使用索引的值来避免对行的访问,然而访问内存的行是很快的,所以并不会降低多少性能。
2.MySQL不能使用Hash索引来进行排序,因为他们并不是有序存储的。
3.Hash索引不支持部分key的匹配。因为计算hash code需要整个索引的值。
4.Hash索引仅仅支持等号操作=,in <=> ,所以并不能加快区间查询比如where price > 100
5.使用Hash索引访问数据很快,但是如果有很多冲突也是问题。
6.如果有很多hash冲突,那么维护索引会很慢。比如你一个区分度不是很够的列建立hash索引,那么删除一行,查找对应的一行会很耗时。
这些限制导致hash索引只在一部分特殊情况下比较有用。然而如果符合应用的需求,能够很大的增强访问的速度。
NDB聚类引擎支持唯一hash索引。。
InnoDB具有一个特别的特性被称为适应性hash索引。InnoDB发现比较频繁访问的索引值,会为其在B-Tree索引之上建立Hash索引,这使得B-Tree索引具有一定的hash特性,这个特性是自动的,你无法控制和配置。

构建自己的hash索引:
如果存储引擎不支持hash索引,你可以想InnoDB那样模拟一个。这样你可以获得hash索引很好的特性,比如很长的key具有很小的索引大小。

这个办法很简单:创建一个假的hash索引在标准的B树索引之上。这个和使用真的hash索引不是完全相同的事,它仍能够使用B-Tree索引来查询,但是使用的hash值而不是可以的本身来查找。你只需要在where条件中指定hash函数。
比如对于查找url的例子,url通常导致B-Tree索引变得很大,因为他们很长,我们可以使用
select id from url where url='http://www.mysql.com';

我们可以删除掉对url的索引,添加url_crc列,然后建立索引:
select id from url where url='http://www.mysql.com' and url_crc=CRC32('http://www.mysql.com');

一个缺点是需要维护hash这一列,在MySQL5.0以上版本已经支持触发器,我们可以使用它来维护:
CREATE TABLE pseudohash (
id int unsigned NOT NULL auto_increment,
url varchar(255) NOT NULL,
url_crc int unsigned NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);

我们临时改变一下分隔符,这样分号可以在触发器中使用:
DELIMITER |
CREATE TRIGGER pseudohash_crc_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN
SET NEW.url_crc=crc32(NEW.url);
END;
|
CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN
SET NEW.url_crc=crc32(NEW.url);
END;
|
DELIMITER ;


如果你使用这种方式,最要不需要选择SHA1和MD5这样的hash函数,他们返回很长的字符产,浪费了很大的空间,导致慢的比较操作。简单的函数能够提供可接受的冲突率,是个比较好的选择。如果有很多的行,CRC32可能导致很多的冲突,实现自己的CRC64函数,确保其返回一个整数,而不是字符串。比如可以简单的这么实现:
SELECT CONV(RIGHT(MD5('http://www.mysql.com/'), 16), 16, 10) AS HASH64;


空间(R-Tree)索引
MyISAM支持空间索引,你可以使用地理空间类型比如geometry。不想B-Tree索引,空间索引不需要是最左前缀的。它同时索引所有维度的数据。这样,查询可以有效使用任何维度组合。
但是你需要使用GIS的函数,比如mbrcontains()。

全文索引
全文索引是MyISAM的一种特殊的索引类型。他可以在文本中查找关键字,而不是直接比较在
索引中的值。全文索引和其他类型的匹配完全不同。他有很多微妙之处,比如停顿词、词根化、和复数归一化,以及bool类型的搜索。和搜索引擎类似。
在一个列建全文索引并不会影响在这列建立B-tree索引。全文索引只对MATCH AGAINST操作有效,对普通的WHERE是无效的。

参考《高性能MySQL》
3
1
分享到:
评论

相关推荐

    MySQL数据库优化

    MySQL数据库优化(一) 1 MySQL数据库优化(二) 5 MySQL数据库优化(三) 13 MySQL数据库优化(五):锁 25 MySQL数据库优化(六):优化数据库结构 29 MySQL数据库优化(七):MySQL如何使用索引 31 MySQL数据库...

    MySQL数据库设计、优化.pptx

    提纲 规范 基础规范 命名规范 库表规范 字段规范 索引规范 开发环境 优化 MySQL数据库设计、优化全文共24页,当前为第2页。 规范 基础规范 全部使用InnoDB引擎,MyISAM适用场景非常少 字符集:latin1 =&gt; utf8 =&gt; ...

    mysql数据库索引优化.doc

    mysql数据库索引优化.docmysql数据库索引优化.docmysql数据库索引优化.doc

    MySQL查询优化技术_索引.pdf

    MySQL查询优化技术_索引

    MYSQL数据库优化秘籍

    MYSQL数据库优化秘籍,大牛出的,值得你反复研读 MySQL在Linux环境下的安装 文件引擎MyISAM与InnoDB比较 LOAD DATA INFILE/mysqldump DBA的分析命令 MySQL的系统配置参数、诊断操作系统的状态 MySQL的分库分表,分区...

    MySQL数据库查询优化

    课程大纲: 第1课 数据库与关系代数 综述数据库、关系代数、查询优化技术 综述数据库调优技术 预计时间1小时 第2课 数据库查询优化技术总揽 ...真正认识、掌握MySQL的查询优化技术,大步流星步入查询优化的高手之列。

    MySQL索引优化课件

    MySQl索引优化课件,详细得介绍了MySQl索引优化数据库

    MySQL架构执行与SQL性能优化 MySQL高并发详解 MySQL数据库优化训练营四期课程

    MySQL架构执行与SQL性能优化-MySQL高并发详解课程,课程的目标简单...课程安排的学习的教程与对应的学习课件,详细的学习笔以及课程对应的SQL语句,具有由数据库或者MySQL的同学们快来参加这堂MySQL的性能优化课堂吧。

    MySQL进阶学习需要掌握的具体内容解析,MySQL数据库如何使用和优化索引.docx

    因此,在设计和使用MySQL数据库时,了解如何使用和优化索引非常重要。 一个索引是一种数据结构,可以快速定位和访问表中的数据。MySQL支持多种类型的索引,包括B树索引、哈希索引和全文索引等。正确选择索引类型...

    MySql数据库优化之SQL和索引的优化

    索引的优化是面试中数据库部分可以说是必问的问题,这个和平时的积累有关。本文详细介绍了SQL和索引的优化。     目录 1 索引的执行分析 1.1 单表的查询索引的执行过程及优化-普通查询 1.2 单表查询索引的执行过程...

    MySQL数据库的优化

    MySQL介绍、架构、什么优化、查询优化、索引使用、存储优化、数据库结构优化、硬件优化、MySQL缓存、MySQL服务器参数

    MySQL数据库索引优化

    介绍BTree索引和Hash索引,详细介绍索引的优化策略等等 1.Btree索引和Hash索引 2.安装演示数据库 3.索引优化策略上 4.索引优化策略中 5.索引优化策略下

    MySQL数据库性能优化之索引优化

     这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化  索引为什么能提高数据访问性能?  很多人只知道索引能够提高数据库的性能,但并不是特别了解其原理,其实我们可以用一个...

    书籍:Oracle与MySQL数据库索引设计与优化

    Oracle与MySQL数据库索引设计与优化 一书,书本有详细介绍

    完整版 MySQL8.0从入门到精通 MySQL数据库教程 全套PPT课件资源集合 共26个章节 含全部源代码.rar

    完整版 MySQL8.0从入门到精通 MySQL数据库教程 第09章 索引(共13页).ppt 完整版 MySQL8.0从入门到精通 MySQL数据库教程 第10章 存储过程和函数(共20页).ppt 完整版 MySQL8.0从入门到精通 MySQL数据库教程 第11章...

    MySQL数据库优化技术之索引使用技巧总结

    这里紧接上一篇《MySQL数据库优化技术之配置技巧总结》,进一步分析索引优化的技巧: (七)表的优化 1. 选择合适的数据引擎 MyISAM:适用于大量的读操作的表 InnoDB:适用于大量的写读作的表 2.选择合适的列类型 使用 ...

    全面深入Mysql数据库优化视频完整资料

    全面深入Mysql数据库优化视频【完整资料】包括索引 存储过程等

    【整理】数据库面试题索引sql优化+数据库SQL优化总结之百万级数据库优化

    数据库面试题索引sql优化.pdf+数据库SQL优化总结之百万级数据库优化.pdf 附赠Oracle高性能sql优化

    mysql数据库sql优化

    1. SQL优化 1 1.1. 优化实战 1 1.1.1. 策略1.尽量全值匹配 1 1.1.2. 策略2.最佳左前缀法则 2 1.1.3. 策略3.不在索引列上做任何操作 2 1.1.4. 策略4.范围条件放最后 3 1.1.5. 策略5.覆盖索引尽量用 3 1.1.6. 策略6.不...

    运用解析器优化MySQL数据库查询性能.pdf

    摘要: 本文首先阐述了索引在数据库查询优化中的重要作用,然后详细介绍了在MySQL中...作为数据库管理员,合理优化和使用索引是提升MySQL数据库查询性能的重要手段。 关键词:MySQL,数据库,查询优化,索引,执行计划,解析器

Global site tag (gtag.js) - Google Analytics