`

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高级:索引、优化

    一、MySQL索引 1. 索引类型:MySQL支持多种索引类型,包括B-Tree(默认索引类型)、Hash、Full-text(全文索引)以及R-tree(空间数据索引)。B-Tree索引适用于范围查询,而Hash索引适用于等值查询,Full-text索引...

    MySQL数据库索引优化

    MySQL数据库索引优化是数据库管理员和开发人员在提升数据库性能方面的一个关键点,涉及BTree索引和Hash索引以及索引优化的策略。索引是数据库中一种非常重要的数据结构,它能够大幅提升查询的效率,但也需要恰当的...

    mysql存储与索引技术

    本文将深入探讨 MySQL 中的存储引擎和索引技术,帮助优化数据库性能。 首先,MySQL 提供了多种存储引擎,每种引擎都有其特定的功能和适用场景。MyISAM 是 MySQL 的默认引擎,它不支持事务处理,但速度快,适合于...

    mysql查询优化之索引优化

    - **InnoDB存储引擎的索引优化**:InnoDB支持行级锁定,其主键索引是聚簇索引,其他非主键索引是非聚簇索引。理解这些特性有助于更好地设计索引。 - **分区与分片**:对于超大型表,可以考虑使用分区或分片技术,将...

    MySQL Innodb 索引原理详解

    本文详细介绍了MySQL InnoDB存储引擎中的索引原理及其实现方式,特别是B+树的应用。通过对比不同的树形结构,我们了解到B+树为何成为数据库索引的理想选择。此外,还讨论了InnoDB与MyISAM的主要差异,以及索引的插入...

    书籍:Oracle与MySQL数据库索引设计与优化

    《Oracle与MySQL数据库索引设计与优化》这本书深入探讨了两个主流关系型数据库管理系统——Oracle和MySQL中的索引设计和优化策略。索引是数据库性能的关键因素,它们能够加速数据检索,提高系统效率,尤其在大数据量...

    MySQL索引分析和优化.pdf

    ### MySQL索引分析与优化详解 #### 一、引言 在现代数据库管理系统中,索引扮演着极其重要的角色。合理的索引设计不仅能显著提升查询性能,还能优化数据的存储结构,进而提高整个系统的响应速度。本文将深入探讨...

    mysql性能优化之索引优化

    MySQL性能优化中的索引优化是提升数据库查询效率的关键技术。索引是一种特殊的数据结构,它允许数据库快速定位和访问表中的特定数据行,类似于书籍的目录,帮助读者迅速找到所需内容。MySQL中,默认的索引类型是B+树...

    mysql之Linux安装,重点是索引的优化笔记

    ### MySQL之Linux安装与索引优化笔记 #### 一、MySQL简介及Linux版安装 **1. MySQL概述** MySQL是一种关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,目前属于Oracle公司。它是一种开源软件,因其性能...

    MySQL 索引最佳实践

    本文将深入探讨MySQL索引的最佳实践,旨在为开发者和数据库管理员提供实用指南。 ### 理解索引的重要性 索引的存在主要是为了加速数据库中的数据访问速度。在没有索引的情况下,数据库必须遍历整个表来查找特定的...

    深入浅出MySQL数据库开发、优化与管理维护.doc

    在本篇中,我们将学习 MySQL 数据库优化的知识点,包括查询优化、索引优化、存储优化和服务器优化等。 管理维护篇 在本篇中,我们将学习 MySQL 数据库管理维护的知识点,包括数据库备份、数据库恢复、服务器监控和...

    MySQL索引最佳实践

    ### MySQL索引最佳实践 ...通过以上内容的学习,我们可以了解到MySQL索引的重要性和不同类型的索引在实际应用中的优势与局限性。正确地理解和运用这些知识可以帮助我们更高效地管理和优化数据库性能。

    Mysql索引优化解决方案.doc

    "Mysql索引优化解决方案" MySQL索引是帮助MySQL高效获取数据的数据结构。MySQL在存储数据之外,还维护着满足特定查找算法的数据结构,这些数据结构以某种引用(指向)表中的数据,这样我们就可以通过数据结构上实现...

    MySQL 索引及优化实战1

    MySQL 索引是数据库性能优化的关键因素,它通过预排序数据来加快查询速度。索引分为聚集索引和非聚集索引。 聚集索引(Clustered Index)是数据库表中数据实际存储的方式,决定了数据在磁盘上的物理顺序。由于数据...

    mysql数据库以及索引详解.pptx

    ### MySQL数据库及索引详解 #### 一、MySQL简介与数据库发展 MySQL是一款非常流行的开源关系型数据库管理...通过理解MySQL及其索引的基本概念,开发者可以更好地管理和优化数据库性能,确保高效地完成数据检索任务。

    MySQL创建索引,查看以及删除

    MySQL是世界上最受欢迎的关系型数据库管理系统之一,其性能优化的一个关键因素是索引的使用。索引可以帮助快速查找和访问数据库中的数据,极大地提高了查询效率。本文将深入探讨MySQL中创建、查看和删除索引的相关...

    mysql 索引与执行计划

    InnoDB引擎中,聚簇索引将数据和索引存储在同一结构中,因此查询速度非常快。 5. **非聚簇索引**:与聚簇索引相对应,它们将索引和数据分开存储。 ##### 1.1.3 基础语法 MySQL提供了多种方法来创建、查看和删除...

Global site tag (gtag.js) - Google Analytics