索引

 什么是索引?

索引是帮助Mysql提高获取数据的数据结构,换一句话讲就是“排好序的快速查找的数据结构”。

一.索引的分类

MySQL主要的几种索引类型:1.普通索引、2.唯一索引、3.主键索引、4.组合索引、5.全文索引。

1.普通索引
         是最基本的索引,它没有任何限制。

 2.唯一索引
        与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一

3.主键索引
        是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。

主键索引和唯一索引的区别:
        主键必唯一,但是唯一索引不一定是主键;
 一张表上只能有一个主键,但是可以有一个或多个唯一索引。 

4.组合索引
        一个索引包含多个列,实际开发中推荐使用复合索引。

复合索引主要特点
       如果我们创建了(name, age,xb)的复合索引,那么其实相当于创建了(name, age,xb)、(name, age)、(name)三个索引,这被称为最佳左前缀
特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

MySQL INNodb建立复合索引 a,b,c;那么 查询条件 where a =xxx and c= xxx 能用到索引嘛?
回答:可以。

注意事项:
    1、对于复合索引,在查询使用时,最好将条件顺序按找索引的顺序,这样效率最高;
          select * from table1 where col1=A AND col2=B AND col3=D
    2、如果使用 where col2=B AND col1=A 或者 where col2=B 将不会使用索引

 5.全文索引
   全文搜索的索引。
    FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。

综合小案例理解:

比如你在为某商场做一个会员卡的系统。
这个系统有一个会员表
有下列字段:

会员编号 INT
会员姓名 VARCHAR(10)
会员身份证号码 VARCHAR(18)
会员电话 VARCHAR(10)
会员住址 VARCHAR(50)
会员备注信息 TEXT

那么这个 会员编号,作为主键,使用 PRIMARY
会员姓名 如果要建索引的话,那么就是普通的 INDEX
会员身份证号码 如果要建索引的话,那么可以选择 UNIQUE (唯一的,不允许重复)
会员备注信息 , 如果需要建索引的话,可以选择 FULLTEXT,全文搜索。
不过 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。
用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。

二.索引的优点缺点

优点:

(1)提高数据检索的效率,降低数据库IO成本。

(2)通过索引对数据进行排序,降低数据的排序成本,降低CPU的消耗。

缺点:

(1)当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
(2)索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大

三、是否需要创建索引

1:什么时候需要创建索引

(1.主键自动创建唯一索引

(2. 较频繁的作为查询条件的字段。

(3.查询中排序的字段,查询中统计或者分组的字段。

2:什么时候不需要创建索引

       (1.表记录太少的字段

(2.经常增删改的字段

(3.唯一性太差的字段,不适合单独创建所以。即使频繁作为查询条件 比如性别,民族,政治面貌(可能总共就是那么几个或几十个值重复使用的字段)

四、索引的注意事项(优化)

1.尽量少使用模糊查询,如果要使用那么,通配符%可以出现在结尾,不能在开头。
    如:name like ‘张%’ ,索引有效
    而:name like ‘%张’ ,索引无效,全表查询

2:or 会引起全表扫描

3:不要使用NOT、!=、NOT IN、NOT LIKE等

4.尽量少使用select*,而是根据需求来选择需要显示的字段

5.索引不会包含有null值的列
只要列中包含有null值都将不会被包含在索引中,复合索引中只要有一列含有null值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为null。

6.不要在列上进行运算,这将导致索引失效而进行全表扫描

7.使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作.

8、union并不绝对比or的执行效率高

我们前面已经谈到了在where子句中使用or会引起全表扫描,一般的,我所见过的资料都是推荐这里用union来代替or。事实证明,这种说法对于大部分都是适用的。
有一点不适用:如果or两边的查询列是一样的话,那么用union则反倒和用or的执行速度差很多,虽然这里union扫描的是索引,而or扫描的是全表。
1.select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16'' or fariqi=''2004-2-5''
用时:6423毫秒。扫描计数 2,逻辑读 14726 次,物理读 1 次,预读 7176 次。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
union
select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-2-5''
用时:11640毫秒。扫描计数 8,逻辑读 14806 次,物理读 108 次,预读 1144 次。

五、索引方式(结构)

mysql有两种所以方式:HashBTree

Hash索引
所谓Hash索引,当我们要给某张表某列增加索引时,将这张表的这一列进行哈希算法计算,得到哈希值,排序在哈希数组上。所以Hash索引可以一次定位,其效率很高,而Btree索引需要经过多次的磁盘IO。
因为Hash索引比较的是经过Hash计算的值,所以在= in <=>(安全等于的时候)塔的效率是非常,但我们开发一般会选择Btree,Hash会存在如下一些缺点。

(1)Hash索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。
由于 Hash 索引比较的是进行 Hash 运算之后的 Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。

(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash值,而且Hash值的大小关系并不一定和 Hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

(3)Hash索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。

(4)Hash索引在任何时候都不能避免表扫描。
前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。

(5)Hash索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。

BTREE
B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型。简单理解,塔就像一棵树,B-Tree索引需要从根节点到枝节点,就能才能访问到页节点的具体数据。
btree索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,取而代之的是从索引的根节点开始进行搜索,根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找,通过比较节点页的值和要查找的值可以找到合适的指针进入下一层子节点,这些指针实际上定义了子节点页中值的上限和下限,最终存储引擎要么是找到对应的值,要么是该记录不存在。

B-tree 索引可以用于使用 =, >, >=, <, <= 或者 BETWEEN 运算符的列比较。如果 LIKE 的参数是一个没有以通配符起始的常量字符串的话也可以使用这种索引。

另外有关聚集索引和非聚集索引,这里收藏两篇文章:

1、快速理解聚集索引和非聚集索引

2、主键就是聚集索引吗?

    想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。上尉【14】

MySQL(1)---索引的更多相关文章

  1. 【夯实Mysql基础】MySQL性能优化的21个最佳实践 和 mysql使用索引

    本文地址 分享提纲: 1.为查询缓存优化你的查询 2. EXPLAIN 你的 SELECT 查询 3. 当只要一行数据时使用 LIMIT 1 4. 为搜索字段建索引 5. 在Join表的时候使用相当类 ...

  2. MySQL中索引和优化的用法总结

    1.什么是数据库中的索引?索引有什么作用? 引入索引的目的是为了加快查询速度.如果数据量很大,大的查询要从硬盘加载数据到内存当中. 2.InnoDB中的索引原理是怎么样的? InnoDB是Mysql的 ...

  3. MySQL 联合索引详解

    MySQL 联合索引详解   联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...

  4. Mysql复合索引

    当Mysql使用索引字段作为条件时,如果该索引是复合索引,必须使用该索引中的第一个字段作为条件才能保证系统使用该索引,否则该索引不会被使用,并且应尽可能地让索引顺序和字段顺序一致

  5. 如何正确建立MYSQL数据库索引

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytabl ...

  6. mysql高性能索引策略

    转载说明:http://www.nyankosama.com/2014/12/19/high-performance-index/ 1. 引言 随着互联网时代地到来,各种各样的基于互联网的应用和服务进 ...

  7. MySQL创建索引语法

    1.介绍: 所有mysql索引列类型都可以被索引,对来相关类使用索引可以提高select查询性能,根据mysql索引数,可以是最大索引与最小索引,每种存储引擎对每个表的至少支持16的索引.总索引长度为 ...

  8. mysql使用索引优化查询效率

    索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没 ...

  9. Mysql中索引的 创建,查看,删除,修改

    创建索引 MySQL创建索引的语法如下: ? 1 2 3 CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON ...

  10. mysql 联合索引(转)

    http://blog.csdn.net/lmh12506/article/details/8879916 mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中 ...

随机推荐

  1. 如何选择合适的PHP版本

    PHP版本很多,包括32位64位以及线程安全与非线程安全在内的php版本多达几百个,应该如何选择PHP版本呢 PHP32和64的选择和区别 32bit的php的整型数据最大最小正负2GB左右(0x7F ...

  2. Java程序简介

    ---恢复内容开始--- java程序的基本构成: HelloDate.java package 语句 import 语句 类定义 -class 一个文件只能有一个public 类 (与文件同名) 类 ...

  3. k8s 安装步骤

    1 安装Docker 1.1 增加中国区镜像 https://registry.docker-cn.com 2 下载安装k8s的镜像的脚本 https://github.com/AliyunConta ...

  4. mysql中gbk_chinese_ci与gbk_bin区别

    如果在query browser中选create new table在字符集的选择中collation栏有两个选择gbk_chinese_ci与gbk_bin gbk_bin是二进制存储.区分大小写的 ...

  5. 别人的Linux私房菜(13)学习Shell脚本

    CentOS6.x以前版本的系统服务启动接口在/etc/init.d/目录下,存放了脚本. Shell脚本因调用外部命令和bash 的一些默认工具,速度较慢,不适合处理大量运算. 执行方式有:直接命令 ...

  6. 4yue 22

    1 # 1 . 进程 线程 协程 之间的相同点和不同点 #相同点:都能帮助我们实现并发操作,规避IO时间,提高执行效率 #进程:内存隔离 操作系统级别 可以利用多核(高计算) 计算机中资源分配的最小单 ...

  7. centos7 启动tomcat卡盾

    vim $JAVA_HOME/jre/lib/security/java.security securerandom.source=file:/dev/random 改为 securerandom.s ...

  8. Linux---一级/二级目录以及位置目录名/指令

    home目录:普通用户登录进来以后的初始位置(会在home目录下创建一个登录名相同的目录例如  / home / 用户名),如果是超级用户则就是 在根目录 /下的 root目录(也就是 /root) ...

  9. For语句的衍生对象

    for in语句: for...in 语句用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作). for...in 语句用于对数组或者对象的属性进行循环操作. for ... in 循环中的 ...

  10. Day07 (黑客成长日记) 函数的参数及作用

    定义函数: 1.定义函数注意: (1)位置参数:直接定义函数. def func(a,b): print(a,b) func(1,2) (2)默认参数:关键字参数:参数名= ‘默认的值‘ def fu ...