一、索引概述

所有Mysql列类型都可以被索引,对相关列使用索引时提高select操作性能的最佳途径。

根据存储引擎可以定义每个表的最大索引数和最大索引长度,每种存储引擎对每个表至少支持16个索引,总索引长度至少为256字节。

MyISAM和InnoDB存储引擎的表默认创建的都是BTREE索引。

索引在创建表的时候可以同时创建,也可以随时增加新的索引。

创建新索引的语法为:

create [unique|fulltext|spatial] index index_name
[using index_type]
on tb1_name (index_col_name,...) index_col_name:
col_name[(length)][ASC|DESC]

也可使用alter table的语法来增加索引。

例如:为city表创建10个字节的前缀索引:

mysql> create index cityname on city (city(10));

如果以city为条件进行查询,可以发现索引cityname被使用:

mysql> explain select * from city where city = 'yt' \G

索引删除语法为:

drop index index_nama on tb1_name

例如:想要删除city表上的索引cityname,可以:

mysql> drop index cityname on city;

二、设计索引的原则

  • 搜索的索引列,不一定是要选择的列。也就是说,最适合索引的列是出现在where字句中的列,或连接子局中指定的列,而不是出现在select关键字后的选择列表中的列。
  • 使用唯一索引。考虑某列中值的分布。索引的列的基数越大,索引的效果越好。例如:存放出生日期的列具有不同的值,易于区分各行。而用来记录性别的列,只含有“M”和“F”,则对此列进行索引没有多大用处。
  • 使用短索引。如果对字符串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做。例如,一个char(200)列,如果在前10或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。对前10个或20个字符进行索引能够节省大量索引空间,也可能会使查询更快。较小的索引涉及的磁盘IO较少,较短的值比较起来更快。更为重要的是,对于较短的键值,索引高速缓存中的块能容纳更多的键值,因此,MySQL也可以在内存中容纳更多的值。这样就增加了找到行而不用读取索引中较多块的可能性。
  • 利用最左前缀。在创建一个n列的索引时,实际是创建了mysql可利用的n个索引。多列索引可起几个索引的作用,因为可利用索引中最左边的列集来匹配行。
  • 不要过度索引。不要以为索引越多越好。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。创建多余的索引给查询优化带来了更多的工作。
  • 对于InnoDB存储引擎的表,记录默认会按照一定的顺序保存,如果有明确定义的主键,则按照主键顺序保存,如果没有主键,但是有唯一索引,那么就按照唯一索引的顺序保存。如果既没有主键又没有唯一索引,那么表中会自动生成一个内部列,按照这个列的顺序保存。按照主键或内部列进行的访问是最快的,所以InnoDB表尽量自己指定主键,当表中同时有几个列都是唯一的,都可以作为主键的时候,要选择最常作为访问条件的列作为主键,提高查询的效率。此外,InnoDB表的普通索引都会保存主键的键值,所以主键要尽可能选择较短的数据类型,可以有效地减少索引的磁盘占用,提高索引的缓存效果。

三、BTREE索引与HASH索引

对于HASH索引:

  • 只用于使用=或<=>操作符的等式比较。
  • 优化器不能使用HASH索引来加速ORDER BY操作。
  • MySQL不能确定在两个值之间大约有多少行。如果将一个MyISAM表改为HASH索引的Memory表,会影响一些查询的执行效率。
  • 只能使用整个关键字来搜索一行。

对于BTREE索引,当使用>、<、>=、<=、BETWEEN、!=或者<>,或者like ‘pattern’(pattern不以通配符开始)操作符时,都可以使用相关列上的索引。

下列范围查询适用于BTREE索引和HASH索引:

select * from t1 where key_col = 1 or key_col in (15,18,20);

下列范围查询只适用于BTREE索引:

select * from t1 where key_col > 1 and key_col < 10;
select * from t1 where key_col like 'ab%' or key_col between 'lisa' and 'simon';

例如:创建一个和city表完全相同的memory存储引擎的表city_memory:

mysql> create table city_memory(
city_id smallint unsigned not null auto_increment,
city varchar(50) not null,
country_id smallint unsigned not null,
last_update timestamp not null default current_timestamp on update current_timestamp,
primary key (city_id),
key idx_fx_country_id(country_id)
)engine=memory default charset=urf-8; mysql> insert into city_momory select * from city;

当对索引字段进行范围查询的时候,只有BTREE索引可通过索引访问:

mysql> explain select * from city where country_id > 1 and country_id < 10 \G

而HASH索引实际上是全表扫描的:

mysql> explain select * from city_memory where country_id > 1 and country_id < 10 \G

索引用于快速找出在某个列中有一特定值的行。如果不使用索引,Mysql必须从第一条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,Mysql能快速到达一个位置去搜寻数据文件的中间,没有必要看所有数据。

大多数Mysql索引(如PRIMARY KEY、UNIQUE、INDEX和FULLTEXT等)在BTREE中存储。

空间列类型的索引使用RTREE,且MEMORY表还支持HASH索引。

MySql(二)索引的设计与使用的更多相关文章

  1. Mysql 学习-索引的设计原则

    索引的设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍.高效的索引对获的良好性能非常重要.设计索引是,应该考虑一下准则: (1)索引并非语讹夺越好,若一个表中有大量索引,不仅占用磁盘空间,而 ...

  2. MySQL数据库索引的设计原则

    为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引. 1.选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录.例如,学生表中学号是具有唯 ...

  3. MySQL索引的设计和使用

    一.索引可以有效地提升SELECT操作的性能,同时会影响UPDATE.CREATE和DELETE操作的性能.每种引擎对于表的索引有数量和长度的限制. 二.索引的设计原则 (A) 搜索的索引列,不一定是 ...

  4. mysql的索引设计原则以及常见索引的区别

    索引定义:是一个单独的,存储在磁盘上的数据库结构,其包含着对数据表里所有记录的引用指针. 数据库索引的设计原则: 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索 ...

  5. MySQL实战 | 05 如何设计高性能的索引?

    原文链接:MySQL | 05 如何设计高性能的索引? 上回我们主要研究了为什么使用索引,以及索引的数据结构.今天带你了解如何设计高性能的索引. 其中,有这么一个点,说的是 InnoDB 引擎中使用的 ...

  6. MySQL索引的设计、使用和优化

    原文:http://bbs.landingbj.com/t-0-243071-1.html MySQL索引概述 所有MySQL列类型可以被索引.对相关列使用索引是提高SELECT操作性能的最佳途径.根 ...

  7. MySQL之索引(二)

    高性能的索引策略 正确地创建和使用索引是实现高性能查询的基础.在MySQL之索引(一)这一章中我们介绍了各种类型的索引及其对应的优缺点.现在我们一起来看看如何真正地发挥这些索引的优势. 独立的列 我们 ...

  8. SQL语句优化、mysql不走索引的原因、数据库索引的设计原则

    SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...

  9. MySQL on Azure高可用性设计 DRBD - Corosync - Pacemaker - CRM (二)

    在上一篇文章中描述了MySQL HA on Azured 设计思路,本篇文章中将描述具体的部署,每个组件的安装和配置. 整体的设计架构如下: 下面将是所有组件的安装配置过程,所有的虚拟机是CentOS ...

随机推荐

  1. eclipse中把spring源码关联至当前工程

    1.下载并导入spring的相关jar包下载对应版本的spring 2.在当前工程中,选择Referenced Libraries,展开后,选择相应的jar包,右击并选择Properties 3. 在 ...

  2. 腾讯消息队列CMQ部署与验证

    环境 IP 备注 192.168.1.66 node1 前置机 192.168.1.110 node2 192.168.1.202 node3 架构图 组件介绍 组件 监听端口 access 1200 ...

  3. 【小菜学网络】MAC地址详解

    上一小节介绍了以太网帧的结构,以及帧中各个字段的作用.参与以太网通讯的实体,由以太网地址唯一标识.以太网地址也叫做 MAC 地址,我们对它仍知之甚少. 以太网地址在不同场景,称谓也不一样,常用叫法包括 ...

  4. JMeter如何设置语言为中文

    一.现象 JMeter安装后,默认语言为英文,如下图所示: 对于英文水平一般的人来说,刚开始使用起来比较费劲(比如我),影响我工作效率.那么,怎么将英文改为中文呢? 二.解决方法 1.修改设置 点击菜 ...

  5. fastjson反序列化漏洞原理及利用

    重要漏洞利用poc及版本 我是从github上的参考中直接copy的exp,这个类就是要注入的类 import java.lang.Runtime; import java.lang.Process; ...

  6. Python requirements.txt 语法

    前言 之前一直苦于一个问题,比如一些包在Win上安装不了,比如 uvloop 但是为了提高效率,代码中必须有这个模块 在运行中可以通过 os 模块判断是否使用, 那依赖文件呢? requirement ...

  7. 【Problems】Could not set property 'id' of 'xxx' with value '' Cause argument type mismatch

    一个问题:向comment表添加记录时,报错, 无法设置值. reflection.ReflectionException: Could not set property 'id' of 'class ...

  8. Py-上下文管理方法,描述符的应用,错误与异常

    上下文管理方法: 可以在exit里面弄一些内存清理的功能 class Open: def __init__(self,name): self.name=name def __enter__(self) ...

  9. 命名秘籍周获近五千星——GitHub 热点速览 v.21.04

    作者:HelloGitHub-小鱼干 命名一直是编程界的难点,这次 naming-cheatsheet 就能帮上你的忙.按照它的 SID(Short..Intuitive.Descriptive)原则 ...

  10. 代码托管从业者 Git 指南

    本文作者:李博文 - CODING 后端开发工程师 前言 六七年前,我机缘巧合进入了代码托管行业,做过基于 Git 支持 SVN 客户端接入.Git 代码托管平台分布式.Git 代码托管读写分离.Gi ...