Mysql 索引 转载

转自 :http://blog.csdn.net/wud_jiyanhui/article/details/7403375

什么是索引

索引时一种特殊的文件,他们包涵着对数据表里所有记录的引用指针。

当对数据表记录进行更新后,都会对索引进行刷新。

索引会占用相当大的空间,应该只为经常查询和最经常排序的数据列建立索引。

索引类型

 

①普通索引:这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:

 I.创建索引

例如:CREATE INDEX <索引的名字> ON tablename (列的列表);

 II.修改表

例如:ALTER TABLE tablename ADDINDEX [索引的名字] (列的列表);

 III.创建表的时候指定索引

例如:CREATE TABLE tablename ( [...],INDEX [索引的名字] (列的列表) );

②唯一性索引

这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。

创建方式:和普通索引创建方式一样,将“INDEX”替换成“UNIQUE”就可以了

③主键索引

主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。每个表只能有一个主键

④全文索引

文本字段上的普通索引只能加快对出现在字段内容最前面的字符串进行的检索操作。如果字段里存放的是由学多个单词构成的大段文字,普通索引就没什么作用“%word%”费时,效率低,响应时间长。

生成全文索引时,mysql将把文中出现的所有单词创建一份清单,查询操作根据这份清单去检索相关数据记录。

但目前全文索引对中文支持很差,需要相关分词插件。(如:http://code.google.com/p/mysqlcft/)

多重索引

 

索引可以是单列索引,也可以是多列索引。

创建多列索引:ALTERTABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。MySQL只需一次检索就能够找出正确的结果!在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

多重索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。

假若现在我们有一个firstname、lastname、age列上的多重索引,我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引:

firstname,lastname,age

firstname,lastname

firstname

选择索引列

 

在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:

在WHERE子句中出现的列

在join子句中出现的列

例子:

SELECT people.age, ##不使用索引

town.name ##不使用索引

FROM people LEFT JOIN town ON

people.townid=town.townid ##考虑使用索引

WHERE firstname=‘Mike‘##考虑使用索引

AND lastname=‘Sullivan‘##考虑使用索引

那么,我们是否可以简单地认为应该索引WHERE子句和join子句中出现的每一个列呢?

差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。

分析索引效率

EXPLAIN<SQL命令

例子: EXPLAIN SELECT peopleid FROMpeople WHERE firstname=‘Mike‘AND lastname=‘Sullivan‘ AND age=‘17‘;

这个命令将返回下面这种分析结果:

------------------------

Table  type  possible_keys    key              key_len  ref                rows  Extra

people ref   fname_lname_age  fname_lname_age  102      const,const,const  1     Where used

------------------------

table:这是表的名字。

type:连接操作的类型。下面是MySQL文档关于ref连接类型的说明:

对于每一种与另一个表中记录的组合,MySQL将从当前的表读取所有带有匹配索引值的记录。如果连接操作只使用键的最左前缀,或者如果键不是UNIQUE或PRIMARY KEY类型(换句话说,如果连接操作不能根据键值选择出唯一行),则MySQL使用ref连接类型。如果连接操作所用的键只匹配少量的记录,则ref是一种好的连接类型。”

在本例中,由于索引不是UNIQUE类型,ref是我们能够得到的最好连接类型。

如果EXPLAIN显示连接类型是“ALL”,而且你并不想从表里面选择出大多数记录,那么MySQL的操作效率将非常低,因为它要扫描整个表。你可以加入更多的索引来解决这个问题。预知更多信息,请参见MySQL的手册说明。

possible_keys:可能可以利用的索引的名字。这里的索引名字是创建索引时指定的索引昵称;如果索引没有昵称,则默认显示的是索引中第一个列的名字(在本例中,它是“firstname”)。默认索引名字的含义往往不是很明显。

Key: 它显示了MySQL实际使用的索引的名字。如果它为空(或NULL),则MySQL不使用索引。

key_len: 索引中被使用部分的长度,以字节计。在本例中,key_len是102,其中firstname占50字节,lastname占50字节,age占2字节。如果MySQL只使用索引中的firstname部分,则key_len将是50。

ref: 它显示的是列的名字(或单词“const”),MySQL将根据这些列来选择行。在本例中,MySQL根据三个常量选择行。

rows: MySQL所认为的它在找到正确的结果之前必须扫描的记录数。显然,这里最理想的数字就是1。

Extra: 这里可能出现许多不同的选项,其中大多数将对查询产生负面影响。在本例中,MySQL只是提醒我们它将用WHERE子句限制搜索结果集。

索引设计

一般针对数据分散的关键字进行建立索引,比如ID、login_id,user_id,等建立索引没有意义

尽量使用短索引,一般对int、char/varchar、date/time 等类型的字段建立索引

需要的时候建立联合索引,但是要注意查询SQL语句的编写谨慎建立 unique 类型的索引(唯一索引)

一般建议每条记录最好有一个能快速定位的独一无二定位的唯一标示(索引)

不要过度索引,单表建立的索引不要超过5个,否则更新索引将很耗时

能够快速缩小结果集的 WHERE 条件写在前面,如果有恒量条件,也尽量放在前面

尽量避免使用 GROUP BY、DISTINCT、OR、IN等语句的使用,避免使用联表查询和子查询,因为将使执行效率大大下降能够使用索引的字段尽量进行有效的合理排列,如果使用了联合索引,请注意提取字段的前后顺序

如果where子句的查询条件里有不等号(wherecolumns !=…),mysql将无法使用索引

类似地,在SQL里使用了MySQL部分自带函数,索引将失效,同时将无法使用 MySQL的 QueryCache,比如 LEFT(),SUBSTR(), TO_DAYS()DATE_FORMAT(), 等,如果使用了 OR 或 IN,索引也将失效

在join操作中,mysql只有在主键和外键的数据类型相同时才能使用索引

针对索引字段使用 >, >=, =, <, <=, IF NULL和BETWEEN 将会使用索引,  如果对某个索引字段进行 LIKE 查询和REGEXP,mysql只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,使用 LIKE  ‘%abc%’不能使用索引,使用 LIKE ‘abc%’ 将能够使用索引

在orderby操作中,mysql只有在排序条件不是一个查询条件表达式的情况下才使用索引

时间: 2024-11-08 15:40:39

Mysql 索引 转载的相关文章

[转载]MySQL索引原理与慢查询优化

好文,以防丢失,故转之,另对排版做简单优化.原文地址:http://ourmysql.com/archives/1401 索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查"mysql"这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者w开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成? 索引原理 除了词典,生活中随处可见索引的例子,如火车站的

MySQL索引原理及慢查询优化 转载

原文地址: http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”.“SQL语句优化”.“了解数据库原理”等要求.我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,

【转载】MySQL索引原理及慢查询优化

原文链接:美团点评技术团队:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”.“SQL语句优化”.“了解数据库原理”等要求.我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是

浅谈MySQL索引背后的数据结构及算法(转载)

转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为三个部分. 第一部分主要从数据结

【转载】MySQL索引优化

MySQL索引优化 原文链接 MySQL官方对索引的定义:索引是帮助MySQL高效获取数据的数据结构.索引是在存储引擎中实现的,所以每种存储引擎中的索引都不一样.如MYISAM和InnoDB存储引擎只支持BTree索引:MEMORY和HEAP储存引擎可以支持HASH和BTREE索引. 这里仅针对常用的InnoDB存储引擎所支持的BTree索引进行介绍: 一.索引类型 先创建一个新表,用于演示索引类型 CREATE TABLE index_table ( id BIGINT NOT NULL au

MySQL索引背后的数据结构及最左原则

MySQL索引原理 ##索引目的索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者ze开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成? ##索引原理除了词典,生活中随处可见索引的例子,如火车站的车次表.图书的目录等.它们的原理都是一样的,通过不断的缩小想要获得数据的范围来筛选出最终想要的结果,同时把

MySql索引原理与使用大全

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.索引介绍 索引是对数据库表中一列或多列的值进行排序的一种结构.在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的SQL语句执行得更快.索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容.当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并

mysql索引类型说明

btree和hash Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引. 可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很

MySQL索引及查询优化总结

作者 | 谢庆玲 文章<MySQL查询分析>讲述了使用MySQL慢查询和explain命令来定位mysql性能瓶颈的方法,定位出性能瓶颈的sql语句后,则需要对低效的sql语句进行优化.本文主要讨论MySQL索引原理及常用的sql查询优化. 一个简单的对比测试 前面的案例中,c2c_zwdb.t_file_count表只有一个自增id,FFileName字段未加索引的sql执行情况如下: 在上图中,type=all,key=null,rows=33777.该sql未使用索引,是一个效率非常低的