MySql(二)索引的设计与使用
MySql(二)索引的设计与使用
一、索引概述
所有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(二)索引的设计与使用的更多相关文章
- Mysql 学习-索引的设计原则
索引的设计不合理或者缺少索引都会对数据库和应用程序的性能造成障碍.高效的索引对获的良好性能非常重要.设计索引是,应该考虑一下准则: (1)索引并非语讹夺越好,若一个表中有大量索引,不仅占用磁盘空间,而 ...
- MySQL数据库索引的设计原则
为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引. 1.选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录.例如,学生表中学号是具有唯 ...
- MySQL索引的设计和使用
一.索引可以有效地提升SELECT操作的性能,同时会影响UPDATE.CREATE和DELETE操作的性能.每种引擎对于表的索引有数量和长度的限制. 二.索引的设计原则 (A) 搜索的索引列,不一定是 ...
- mysql的索引设计原则以及常见索引的区别
索引定义:是一个单独的,存储在磁盘上的数据库结构,其包含着对数据表里所有记录的引用指针. 数据库索引的设计原则: 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索 ...
- MySQL实战 | 05 如何设计高性能的索引?
原文链接:MySQL | 05 如何设计高性能的索引? 上回我们主要研究了为什么使用索引,以及索引的数据结构.今天带你了解如何设计高性能的索引. 其中,有这么一个点,说的是 InnoDB 引擎中使用的 ...
- MySQL索引的设计、使用和优化
原文:http://bbs.landingbj.com/t-0-243071-1.html MySQL索引概述 所有MySQL列类型可以被索引.对相关列使用索引是提高SELECT操作性能的最佳途径.根 ...
- MySQL之索引(二)
高性能的索引策略 正确地创建和使用索引是实现高性能查询的基础.在MySQL之索引(一)这一章中我们介绍了各种类型的索引及其对应的优缺点.现在我们一起来看看如何真正地发挥这些索引的优势. 独立的列 我们 ...
- SQL语句优化、mysql不走索引的原因、数据库索引的设计原则
SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...
- MySQL on Azure高可用性设计 DRBD - Corosync - Pacemaker - CRM (二)
在上一篇文章中描述了MySQL HA on Azured 设计思路,本篇文章中将描述具体的部署,每个组件的安装和配置. 整体的设计架构如下: 下面将是所有组件的安装配置过程,所有的虚拟机是CentOS ...
随机推荐
- 自动化单元测试(Karma + Mocha)
使用 Karma + Mocha做单元测试 Karma([ˈkɑrmə] 卡玛)是一个测试运行器,它可以呼起浏览器,加载测试脚本,然后运行测试用例 Mocha([ˈmoʊkə] 摩卡)是一个单元测试框 ...
- python之scrapy框架基础搭建
一.创建工程 #在命令行输入scrapy startproject xxx #创建项目 二.写item文件 #写需要爬取的字段名称 name = scrapy.Field() #例 三.进入spide ...
- Linux 时间同步 04 ntp时间同步
Linux 时间同步 04 ntp时间同步 目录 Linux 时间同步 04 ntp时间同步 安装ntp 配置与外部时间服务器进行时间同步的客户端主机 配置其他客户端与以上客户端主机时间同步 验证查看 ...
- 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?
作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...
- Spring中ApplicationContextAware接口的说明
转载 https://www.cnblogs.com/muqingzhi123/p/9805623.html 1.为什么使用AppplicationContextAware? ApplicationC ...
- 风炫安全web安全学习第三十五节课 文件下载和文件读取漏洞
风炫安全web安全学习第三十五节课 文件下载和文件读取漏洞 0x03 任意文件下载漏洞 一些网站由于业务需求,往往需要提供文件下载功能,但若对用户下载的文件不做限制,则恶意用户就能够下载任意敏感文件, ...
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
- Head First 设计模式 —— 07. 适配器模式
思考题 你能想到真实世界中,还有哪些适配器的例子? P236 HDMI 转 VGA 转换器 Type-C 转 3.5mm 线 适配器模式解析 客户使用适配器的过程: P241 客户通过目标接口调用适配 ...
- 【老孟Flutter】为什么 build 方法放在 State 中而不是在 StatefulWidget 中
老孟导读:此篇文章是生命周期相关文章的番外篇,在查看源码的过程中发现了这一有趣的问题,欢迎大家一起探讨. Flutter 中Stateful 组件的生命周期:http://laomengit.com/ ...
- python_元组(tuple)
#tuple(),元组不可以修改,不能对其进行增加或删除操作,元组是有序的 #1.定义 tu_1 = () #定义一个空元组 tu_2 = (1,2,'alex',[3,4],(5,6,7),True ...