`

MySQL学习(索引、引擎、优化)

 
阅读更多
索引对于查询的速度至关重要,理解索引也是数据库调优的起点。

1. 建立索引前,先设计好建立索引列的数据类型。
1)越小的数据类型性能越好:因为越小的数据类型对于硬盘读取、内存、CPU缓存都需要更少的空间,处理起来更快。
2)简单的数据类型更好:整型比字符型更好。
3)尽量避免使用NULL: 建立索引的列最好是Not Null约束的,如果一定要用NULL,可以用0或者某特殊值替代。因为在MySQL中,对于NULL的值很难进行查询优化,因为他们使得索引的计算更加复杂。

2. 索引概述:
对于任何关系型数据库,索引都是进行优化的最主要因素。对于少量的数据,不必使用索引。
如果对于多列进行索引(组合索引),列的顺序非常中意。MySQL仅对索引最左边的前缀进行有效的查找。
例如:存在组合索引(c1, c2), 查询语句select * from t1 where c1=1 and c2=2能够使用该索引。select * from t1 where c1=1也能够使用该索引。但select * from t1 where c2=2不能使用该索引。
理由是,没有组合索引的引导列,即,要想使用c2列进行索引,必须出现c1等于某值。

2.1 索引的类型
索引与引擎的关系:
索引是在存储引擎中实现的,而不是在服务器层中实现的。所以每种存储引擎的索引都不一定相同,并不是所有的存储引擎都支持所有的索引类型。

2.1.1 B-Tree索引
假如有一个表:
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)
);
其索引包含了表中每一行的last_name, first_name, dob列。

索引存储的值按照索引列中的顺序排序(先last_name, 在first_name, 再dob). 可以用B-Tree索引进行全关键字、关键字范围、关键字前缀进行查询。
所以可以对如下情形生效:
1)匹配全值(Match the full value): 对索引中所有列都指定具体的值。例如查找出1960-01-01出生的Cuba Allen.
2)匹配最左前缀(Match a leftmost prefix): 可以利用索引查找last_name为Allen的人。
3)匹配列前缀(Match a column prefix): 可以列用索引查找last_name为J开头的人,仅仅使用索引中的第一列。
4)匹配值的范围查询(Match a range of values): 可以利用索引查找last_name在Allen和Barrymore之间的人,仅仅使用索引中的第一列。
5)匹配部分精确而其他部分进行范围匹配(Match one part exactly and match a range on another part): 可以利用索引查找last_name为Allen, 而first_name为K开头的人。

因为B-Tree中的节点都是顺序存储的,所以可以利用索引进行查找(找到某值),也可以对查询结果order by.

使用B-Tree索引有下面的限制:
1)查询必须从索引的最左边的列开始
2)不能跳过某一列索引:即不能利用索引查询last_name为Allen, 且1980-01-01出生的人。必须先查first_name后再查dob.
3)存储引擎不能使用索引中范围条件右边的列。例如:where last_name='Smith' and first_name like 'J%' and dob='1976-01-02', 则索引只对last_name和first_name有效,因为like是范围查询。

2.1.2 Hash索引
MySQL中,只有Memory存储引擎支持hash索引,是Memory引擎默认的索引类型。尽管Memory表也可以使用B-Tree索引。

3. 高性能的索引策略
3.1 聚簇索引(Clustered Indexes) -- 在MySQL的InnoDB引擎中,主键索引就是聚簇索引。
聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不适合创建索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引。
目前,支持聚簇索引的引擎只有InnoDB和solidDB.

3.1.1 聚簇索引和非聚簇索引的区别:InnoDB引擎支持聚簇索引,而MyISAM不支持聚簇索引。
例如:
create table layout_test (
col1 int NOT NULL,
col2 int NOT NULL,
primary key(col1),
key(col2)
);
假设主键位于1--10000之间,且按随机顺序插入,然后由optimize table进行优化。col2随机赋予1--100之间的值,所以会存在许多重复的值。
1)MyISAM的布局:
MyISAM按照插入的顺序在磁盘上存储数据。
注:MyISAM不支持聚簇索引,索引中每一个叶子节点仅仅包含行号(row number), 且叶子节点按照col1的顺序存储。
2)InnoDB的布局:
InnoDB按聚簇索引的形式存储数据。
注:聚簇索引总每个叶子节点包含primary key的值,事务ID和回滚指针(rollback pointer).

3.2 覆盖索引(Covering Indexes)
如果索引包含满足查询的所有数据,就成为覆盖索引。
覆盖所有有如下好处:
1)索引项通常比记录要小,所以MySQL访问更好的数据。
2)索引都按值的大小顺序存储,相对于随机访问记录,需要更少的IO.
3)大多数数据引擎更好的缓存了索引。比如MySQL只缓存索引。
4)覆盖索引对于InnoDB表尤其有用,因为InnoDB使用聚簇索引组织数据,如果二级索引中包含所需的数据,就不需要在索引中查找了。

3.3 利用索引进行排序
MySQL中,有两种方式生成有序的结果集:一是使用filesort, 二是按索引顺序扫描。
利用索引进行排序非常快,且可以利用同一索引同时进行查找和排序操作。
当索引的顺序与order by的列顺序相同时,且所有的列是同一方向(全部升序或者全部降序)时,可以用索引排序。
如果查询时多表连接,仅当order by中所有的列都是第一个表的列时,索引才会生效。其他情况都会使用filesort.

例如:
create table actor (
actor_id int unsigned not null auto_increment,
name varchar(16) not null default,
password varchar(16) not null default,
primary key(actor_id),
key(name)
) engine=InnoDB
insert into actor(name,password) values('cat01','1234567');
insert into actor(name,password) values('cat02','1234567');
insert into actor(name,password) values('ddddd','1234567');
insert into actor(name,password) values('aaaaa','1234567');

mysql>explain select actor_id from actor order by actor_id;
结果:
id:1
select_type:SIMPLE
table:actor
type:index
possible_keys:NULL
key:PRIMARY
ref:NULL
rows:4
Extra:Using index
1 row in set(0.00 sec)

mysql>explain select actor_id from actor order by password;
结果:
id:1
select_type:SIMPLE
table:actor
type:index
possible_keys:NULL
key:NULL
key_len:NULL
ref:NULL
rows:4
Extra:Unsing filesort
1 row in set(0.00 sec)

mysql>explain select actor_id from actor order by name;
结果:
id:1
select_type:SIMPLE
table:actor
type:index
possible_key:NULL
key:name
key_len:18
ref:NULL
rows:4
Extra:Using index

当MySQL不能使用索引进行排序时,就会利用自己的排序算法(快速排序算法)在内存(sort buffer)中对数据进行排序。如果内存装载不下,它会将磁盘上的数据进行分块,再对各个数据块进行排序,然后将各个数据库合并成有序的结果集。

3.4 索引与加锁
索引对于InnoDB非常重要,因为它可以让查询锁定更少的元组。因为InnoDB直到事务提交时才会解锁。有两个原因:
1. 即使InnoDB行级锁非常高效,内存开销非常小,但还是存在开销。
2. 对不需要的元组加锁,会增加锁的开销,降低并发性能。
InnoDB仅对需要访问的元组加锁,而索引能够减少InnoDB访问的元组数。

===========================
MyISAM和InnoDB的区别:
1. 事务处理:MyISAM不支持,InnoDB支持
2. 性能:MyISAM好于InnoDB
3. fulltext索引:MyISAM支持,InnoDB不支持
4. select count(*) from table1; MyISAM效率好:MyISAM仅读出保存好的行数,而InnoDB要扫描一遍整个表。
5. auto_increment: MyISAM可以用该列与其他列一起建立联合索引,而InnoDB只支持包含只有该字段的索引。
6. delect from table; InnoDB会一行一行删除,不会重新建立表。

综上,MyISAM和InnoDB的主要区别是,InnoDB支持事务处理和行级锁。而MyISAM不支持,所以MyISAM往往被认为只适合在小项目中应用。
MyISAM的好处:
1. 对于读多写少的情形,MyISAM的性能比InnoDB好很多。
2. MyISAM的索引和数据是分开的,并且索引是有压缩的,这样内存使用率就提高了不少。而InnoDB的索引和数据是紧密捆绑的,并没有使用压缩,从而会造成InnoDB的体积更庞大。

一般来说,MyISAM适合:
1. 做很多count计算
2. 插入不频繁,查询非常频繁
3. 没有事务

InnoDB适合于:
1. 可靠性要求比较高,或者要求事务
2. 表更新和查询都非常的频繁,并且表锁定的机会比较大。

============================

MySQL的explain

explain的作用是显示了MySQL如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。
使用方法:在select语句前加上explain就可以了。

例如:explain select surname, first_name from a, b where a.id=b.id

分析结果形式如下:
table | type | possible_keys | key | key_len | ref | rows | extra

分别解释如下:
1. table:显示这一行的数据是关于哪张表的
*2. type:显示连接使用了哪种类型。最好到最差的连接类型为:const, eq_reg, ref, range, index, ALL
3. possible_key: 显示可以应用在这张表上的索引。
*4. key: 实际使用的索引。如果为NULL, 则没有使用索引。
5. key_len: 索引的长度
6. ref: 显示索引的哪一列被使用了。
7. rows: MySQL认为必须检查的用来返回请求数据的行数。
*8. extra: 额外信息:
1)distinct: 一旦找到与行相匹配的行,就不再搜索了。
2)not exist: MySQL优化了左连接,一旦它找到了匹配left join标准的行,就不再搜索了。
3)using filesort: 指Mysql将用外部排序而不是按照index顺序排列结果。数据较少时从内存排序,否则从磁盘排序。Explain不会显示的告诉客户端用哪种排序。
4)using index: 表示Mysql使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据。
分享到:
评论

相关推荐

    MySQL数据库设计、优化.pptx

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

    MySQL学习笔记,包括SQL基本语法、MySQL基础知识,包括存储引擎、索引、视图、锁、优化、存储结构等MySQL主要的内容

    MySQL学习笔记,包括SQL基本语法、MySQL基础知识,包括存储引擎、索引、视图、锁、优化、存储结构等MySQL主要的内容。

    mysql多条件索引

    数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度。 索引优化是数据库优化的最重要手段。 如果查询语句使用索引...

    MySQL 通过索引优化含ORDER BY的语句

    3、尽量在采用MyIsam作为引擎的时候使用索引(因为MySQL以BTree存储索引),而不是InnoDB。但MyISAM不支持Transcation。 4、当你的程序和数据库结构/SQL语句已经优化到无法优化的程度,而程序瓶颈并不能顺利解决,那...

    Mysql性能优化教程

    Mysql 执行优化 2 认识数据索引 2 为什么使用数据索引能提高效率 2 如何理解数据索引的结构 2 优化实战范例 3 认识影响结果集 4 影响结果集的获取 4 影响结果集的解读 4 常见案例及优化思路 5 理解执行状态 7 常见...

    mysql高级视频教程百度云(2019).txt

    48.MySQL高级_为排序使用索引OrderBy优化.avi 47.MySQL高级_in和exists.avi 46.MySQL高级_小表驱动大表.avi 45.MySQL高级_索引优化答疑补充和总结口诀.avi 44.MySQL高级_索引面试题分析.avi 43.MySQL高级...

    MySQL海量数据查询优化策略.

    MySQL海量数据查询优化策略,方法。 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引...

    2021年MySQL高级教程视频.rar

    09.MySQL高级索引索引分类.avi 10.MySQL高级索引索引语法.avi 11.MySQL高级索引索引设计原则.avi 12.MySQL高级视图概述.avi 13.MySQL高级视图创建及修改视图.avi 14.MySQL高级视图查看及删除视图.avi 15.MySQL高级...

    尚硅谷Java视频教程_MySQL高级视频

    尚硅谷_MySQL高级_索引单表优化案例 · 32.尚硅谷_MySQL高级_索引两表优化案例 · 33.尚硅谷_MySQL高级_索引三表优化案例 · 34.尚硅谷_MySQL高级_索引优化1 · 35.尚硅谷_MySQL高级_索引优化2 · 36.尚硅谷_...

    MySQL学习笔记-基础到进阶

    内容概要:MySQL学习笔记,内容包括SQL基本语法、MySQL基础知识,包括存储引擎、索引、视图、锁、优化、存储结构等MySQL主要的内容。 适用人群:适合自学MySQL的同学使用。 能学到什么:MySQL从基础到进阶的全部内容...

    mysql优化.xmind

    MySQL的优化思维导图,主要是从 数据类型的优化 索引 设计优化 选择合适的储存引擎 等四个方面 进行了详细的讲述

    Mysql覆盖索引详解

    使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL查询优化器在执行查询前会决定是否有索引覆盖查询 注意 1、覆盖索引也并不适用于任意的索引类型,索引必须存储列的值 2...

    分享几道关于MySQL索引的重点面试题

    以下回答全部是基于MySQL的InnoDB引擎 例如对于下面这一张表 如果我们按照 name 字段来建立索引的话,采用B+树的结构,大概的索引结构如下 如果我们要进行模糊查找,查找name 以“张”开头的所有

    Java高级编程——MySQL索引实现及优化原理解析

    在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式。MyISAM索引实现MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的...

    深入讲解MySQL Innodb索引的原理

    回想四年前,我在学习mysql的索引这块的时候,老师在讲索引的时候,是像下面这么说的 索引就像一本书的目录。而当用户通过索引查找数据时,就好比用户通过目录查询某章节的某个知识点。这样就帮助用户有效地提高了...

    mysql性能优化

    分别从表结构的优化,SQL语句的优化,存储引擎的选择,索引的优化以及现今MySQL的发展与其他企业级数据库的比较。介绍了从编码选择到数据类型的选择以及从整体的角度设计表结构。在SQL语句的选择和使用的介绍的时候...

    Mysql的性能优化

    Mysql 执行优化 2 认识数据索引 2 为什么使用数据索引能提高效率 2 如何理解数据索引的结构 2 如何理解影响结果集 3 理解执行状态 4 常见分析手段 4 分析流程 6 总结 7 Mysql 运维优化 9 存储引擎类型 9 内存使用...

    MySQL创建全文索引分享

    使用索引时数据库性能优化的必备技能之一。在MySql数据库中,有四种索引:聚焦索引(主键索引)、普通索引、唯一索引以及我们这里将要介绍的全文索引(FUNLLTEXT INDEX)。 全文索引(也称全文检索)是目前搜索引擎...

    浅谈MySQL的B树索引与索引优化

    如何基于索引结构,理解常见的MySQL索引优化思路?索引结构的选择基于这样一个性质:大数据量时,索引无法全部装入内存。为什么索引无法全部装入内存?假设使用树结构组织索引,简单估算一下:假设单个索引节点12B,...

    Mysql面试过关!(详解:索引+常用引擎+常见问题+sql调优)

    一、Mysql索引 1、添加索引sql语句 2、查看MySQL中建立的索引是否生效 3、索引失效场景(补充:以下在实际应用中并不会一定导致索引失效,基于mysql不同版本的优化规则) 3.1 在联合索引的场景下,查询条件不满足最...

Global site tag (gtag.js) - Google Analytics