MySQL索引、事务与存储引擎

1、MySQL 索引介绍

索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址。在数据十分庞大的时候,索引可以大大加快查询的速度。这是因为使用索引后可以 不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问 相应的数据。索引的作用类似于图书的目录,可以根据目录中的页码快速找到所需的内容。 

1.1、索引概述 

当数据保存在磁盘类存储介质上时,它是作为数据块存放。这些数据块是被当作一个整体来访问的,这样可以保证操作的原子性。硬盘数据块存储结构类似于链表,都包含数据部 分,以及一个指向下一个节点(或数据块)的指针,不需要连续存储。

记录集只能在某个关键字段上进行排序,所以如果需要在一个无序字段上进行搜索,就 要执行一个线性搜索(Linear Search)的过程,平均需要访问 N/2 的数据块,N 是表示所 占据的数据块数目。如果这个字段是一个非主键字段(也就是说,不包含唯一的访问入口), 那么需要在 N 个数据块上搜索整个表格空间。

但是对于一个有序字段,可以运用二分查找(Binary Search),这样只需要访问 log2 (N) 的数据块。这就是为什么数据表使用索引后性能可以得到本质上提高的原因。

索引是对记录集的多个字段进行排序的方法。在一张表中为一个字段创建一个索引,将 创建另外一个数据结构,包含字段数值以及指向相关记录的指针,然后对这个索引结构进行 排序,允许在该数据上进行二分法排序。

使用索引的副作用是需要额外的磁盘空间。对于 MyISAM 引擎而言,这些索引是被统 一保存在一张表中的。如果很多字段都建立了索引,那么会占用大量的磁盘空间,这个文件 将很快到达底层文件系统所能够支持的大小限制。

1.2、索引作用 

在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率。特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询 速度加快成千上万倍。 

例如,有 3 个未索引的表 t1、t2、t3,分别只包含列 c1、c2、c3,每个表分别含有 1000 行数据组成,均为 1~1000 的数值,查找对应值相等行的查询如下所示。

mysql> select c1,c2,c3 from t1,t2,t3 where c1=c2 and c1=c3;

此查询结果应该为 1000 行,每行包含 3 个相等的值。在无索引的情况下处理此查询, 必须寻找 3 个表所有的组合,以便得出与 WHERE 子句相配的那些行。而可能的组合数目为 1000×1000×1000(十亿),显然查询将会非常慢。 

如果对每个表进行索引,就能极大地加速查询进程,利用索引的查询处理如下。

  • 从表 t1 中选择第一行,查看此行所包含的数据。
  • 使用表 t2 上的索引,直接定位 t2 中与 t1 的值匹配的行。同理,利用表 t3 上的索引, 直接定位 t3 中与 t1 的值匹配的行。
  • 扫描表 t1 的下一行并重复前面的过程,直到遍历 t1 中所有的行。

在此情形下,仍然对表 t1 执行了一个完全扫描,但能够在表 t2 和 t3 上进行索引查找直 接取出这些表中的行,比未用索引时要快一百万倍。

利用索引,MySQL 加速了 WHERE 子句满足条件行的搜索,而在多表连接查询时、在执行连接时加快了与其他表中的行匹配的速度。

1.3、索引的分类

在数据库表中,对字段建立索引可以大大提高查询速度。通过善用这些索引,可以令 MySQL 的查询和运行更加高效。索引是快速搜索的关键。MySQL 索引的建立对于 MySQL 的高效运行是非常重要的。下面介绍几种常见的 MySQL 索引类型。

从物理存储的角度来划分,索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据 存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而 非聚簇索引对于单行的检索更快。

从逻辑的角度来划分,索引分为普通索引、唯一索引、主键索引、组合索引和全文索引。 这些索引分类的具体解释如下所示。 

1)普通索引 

普通索引是最基本的索引,它没有任何限制,也是大多数情况下用到的索引。它有以下 几种创建方式。

直接创建索引:

mysql> create index index_id ON info (现金余额);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 

现金余额是指定要创建索引的列名。通常可以考虑将查询语句中在 JOIN 子句和 WHERE 子句里经常出现的列作为索引列。 

修改表结构的方式添加索引: 

mysql> alter table info add index index_id1 (现金余额);
Query OK, 0 rows affected, 1 warning (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 1

mysql> 

创建表结构时,同时创建索引: 

mysql> CREATE TABLE info(id int, 姓名 CHAR(16) NOT NULL, 年龄 TINYINT NOT NULL, 现金余额 INT DEFAULT'3000', PRIMARY KEY(id), index indexx_id1 (现金余额));
Query OK, 0 rows affected (0.01 sec)

mysql>

2)唯一索引 

唯一索引与普通索引类似,不同的就是:唯一索引的索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一。唯一索引创建方法和普通索引类似。 

创建唯一索引:

mysql> create unique index index_id2 ON info (id);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>

修改表结构的时候添加唯一索引: 

mysql> alter table info add unique index_id3 (id);
Query OK, 0 rows affected, 1 warning (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 1

mysql>

创建表的时候同时创建唯一索引:

mysql> CREATE TABLE info1(id int, 姓名 CHAR(16) NOT NULL, 年龄 TINYINT NOT NULL, 现金余额 INT DEFAULT'3000', PRIMARY KEY(id), unique index4(id));
Query OK, 0 rows affected (0.01 sec)

mysql> 

3)主键索引 

主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。 

mysql> CREATE TABLE info2(id int, 姓名 CHAR(16) NOT NULL, 年龄 TINYINT NOT NULL, 现金余额 INT DEFAULT'3000', PRIMARY KEY(id));
Query OK, 0 rows affected (0.01 sec)

mysql>

4)组合索引(最左前缀) 

平时用的 SQL 查询语句一般都有比较多的限制条件,所以为了进一步榨取 MySQL 的 效率,就要考虑建立组合索引。在组合索引的创建中,有两种场景,即为单列索引和多列索 引。下面通过一个场景来具体说明单列索引和多列索引。

在一个 user 用户表中,有 name,age,sex 三个字段,分别分三次建立了 INDEX 普 通索引。那么在 select * from user where name = '' AND age = '' AND sex = '';数据查询语 句中就会分别检索三条索引,虽然扫描效率有所提升,但却还未达到最优。这个时候就需要 使用到组合索引(即多列索引),如下所示。 

mysql> create table user(name varchar(9), age int(3), sex tinyint(1), index user(name,age,sex));
Query OK, 0 rows affected (0.02 sec)

mysql>

在 MySQL 中,有一个知识点叫最左原则。下面的 select 语句的 where 条件是依次从左往右执行的。 

mysql> select * from user where name='' and age='' and sex='';

若使用的是组合索引 index user(name, age, sex)。在查询中,name、age、sex 的顺序必须如组合索引中一致排序,否则索引将不会生效,例如: 

mysql> select * from user where age='' and name='' and sex='';

如果采用“select * from user where age = '' AND name = '' AND sex = '';”查询方式,这 条组合索引将无效化,所以一般在建立索引时,要先想好相应的查询业务,尽量避免虽然有索引,但是使用不上的问题。 

5)全文索引(FULLTEXT)

MySQL 从 3.23.23 版 开 始 支 持 全 文 索 引 和 全 文 检 索 。 在 MySQL5.6 版 本 以 前 FULLTEXT 索引仅可用于 MyISAM 表,在 5.6 之后 innodb 引擎也支持 FULLTEXT 索引; 他们可以从 CHAR、VARCHAR 或 TEXT 列中作为 CREATE TABLE 语句的一部分被创建, 或是随后使用 ALTER TABLE 或 CREATEINDEX 被添加。 

 对于较大的数据集,将资料输入一个没有 FULLTEXT 索引的表中,然后创建索引,其速度比把资料输入现有 FULLTEXT 索引的速度更快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间、非常消耗硬盘空间的做法。

创建表的全文索引:

mysql> CREATE TABLE info3(id int, 姓名 CHAR(16) NOT NULL, 年龄 TINYINT NOT NULL, 现金余额 INT DEFAULT'3000', content text character setA utf8 collate utf8_general_ci null,PRIMARY KEY(id), fulltext(content));
Query OK, 0 rows affected (0.04 sec)

mysql> 

修改表结构添加全文索引: 

mysql> alter table info3 add fulltext index_id3(content);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>

直接创建索引:

mysql> create fulltext index index_id4 ON info3(content);
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 

1.4、创建索引的原则依据 

数据库建立索引的原则: 

  • 确定针对该表的操作是大量的查询操作还是大量的增删改操作; 
  • 尝试建立索引来帮助特定的查询。检查自己的 sql 语句,为那些频繁在 where 子句中出现的字段建立索引;
  • 尝试建立复合索引来进一步提高系统性能。修改复合索引将消耗更长时间,同时复合索引也占磁盘空间;
  • 对于小型的表,建立索引可能会影响性能;
  • 应该避免对具有较少值的字段进行索引;
  • 避免选择大型数据类型的列作为索引。

索引建立的原则:

索引查询是数据库中重要的记录查询方法,要不要建立索引以及在那些字段上建立索引都要和实际数据库系统的查询要求结合来考虑,下面给出实际生产环境中的一些通用的原则:

  • 在经常用作过滤器的字段上建立索引;
  • 在 SQL 语句中经常进行 GROUP BY、ORDER BY 的字段上建立索引;
  • 在不同值较少的字段上不必要建立索引,如性别字段;
  • 对于经常存取的列避免建立索引;
  • 用于联接的列(主健/外健)上建立索引;
  • 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定; 
  • 缺省情况下建立的是非簇集索引,但在以下情况下最好考虑簇集索引,如:含有限数目 (不是很少)唯一的列;进行大范围的查询;充分的利用索引可以减少表扫描 I/0 的次 数,有效的避免对整表的搜索。当然合理的索引要建立在对各种查询的分析和预测中, 也取决于 DBA 所设计的数据库结构。

1.5、查看索引 

MySQL 数据表索引已经创建好了,那么如何才能查看刚刚创建的索引?或者怎么去查看表内已经存在的索引?有以下两种查看当前索引的方式。 

mysql> show index from info;
mysql> show keys from info;

以 info 表为例,查看 info 表的索引内容。

mysql> show index from info;
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name  | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| info  |          0 | PRIMARY   |            1 | id           | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| info  |          0 | index_id2 |            1 | id           | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| info  |          0 | index_id3 |            1 | id           | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| info  |          1 | index_id1 |            1 | 现金余额     | A         |           0 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)

mysql>

以上结果中各字段的含义如下:

  • Table:表的名称。
  • Non_unique:如果索引不能包括重复词,则为 0;如果可以,则为 1。
  • Key_name:索引的名称。
  • Seq_in_index:索引中的列序号,从 1 开始。
  • Column_name:列名称。
  • Collation:列以什么方式存储在索引中。在 MySQL 中,有值‘A’(升序)或 NULL(无 分类)。
  • Cardinality:索引中唯一值数目的估计值。通过运行 ANALYZE TABLE 或 myisamchk -a 可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没 有必要是精确的。基数越大,当进行联合时,MySQL 使用该索引的机会就越大。 
  • Sub_part:如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列 被编入索引,则为 NULL。
  • Packed:指示关键字如何被压缩。如果没有被压缩,则为 NULL。
  • Null:如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO。
  • Index_type:用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
  • Comment:备注。

1.6、删除索引 

索引在创建之后,是会占用一定的磁盘空间的,因此表内如果有不再使用的索引,从数据库性能方面考虑,最好是删除无用索引。索引的删除有如下两种方法。 

DROP INDEX 索引名 ON 表名;

ALTER TABLE 表名 DROP INDEX 索引名;

以 info 表为例,删除 info 表的索引。

mysql> drop index index_id1 on info;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 
mysql> alter table info drop index index_id2;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>

2、MySQL事务 

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中, 要删除一个人员,即需要删除人员的基本资料,又需要删除和该人员相关的信息,如信箱, 文章等等。这样,这些数据库操作语句就构成一个事务! 

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
  • 事务用来管理 insert,update,delete 语句。 

一般来说,事务是必须满足 4 个条件(ACID):原子性(Atomicity,或称不可分割性)、 一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。 

  • 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不 会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开 始前的状态,就像这个事务从来没有执行过一样;
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的 资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以 自发性地完成预定的工作;
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防 止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包 括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable);
  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马 上执行 COMMIT 操作。因此要显式地开启一个事务必须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

事务控制语句包含:

  • BEGIN 或 START TRANSACTION:显式地开启一个事务;
  • COMMIT:也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务, 并使已对数据库进行的所有修改变为永久性的;
  • ROLLBACK:又可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户 的事务,并撤销正在进行的所有未提交的修改;
  • SAVEPOINT identifier:SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT; 
  • RELEASE SAVEPOINT identifier:删除一个事务的保存点,当没有指定的保存点时, 执行该语句会抛出一个异常;
  • ROLLBACK TO identifier:把事务回滚到标记点;
  • SET TRANSACTION:用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级 别 有 READ UNCOMMITTED 、 READ COMMITTED 、 REPEATABLE READ 和SERIALIZABLE。

MYSQL 事务处理主要有两种方法:

(1)用 BEGIN, ROLLBACK, COMMIT 来实现

  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认

(2)直接用 SET 来改变 MySQL 的自动提交模式

  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交 

以下是事务的示例:

mysql> use demo;
Database changed
mysql> create table kgc(id int(5)) engine=innodb;  //创建数据表
Query OK, 0 rows affected (0.02 sec)

mysql> select * from kgc;
Empty set (0.00 sec)

mysql> begin;  //开始事务
Query OK, 0 rows affected (0.01 sec)

mysql> insert into kgc value(1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into kgc value(2);
Query OK, 1 row affected (0.00 sec)

mysql> commit;  //提交事务
Query OK, 0 rows affected (0.00 sec)

mysql> select * from kgc;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

mysql> begin;  //开始事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into kgc value(3);
Query OK, 1 row affected (0.01 sec)
 
mysql> rollback;  //回滚
Query OK, 0 rows affected (0.00 sec)

mysql> select * from kgc;  //因为回滚所以数据没有插入
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

mysql> 

3、MySQL 存储引擎 

在数据库中保存的是一张张有着千丝万缕关系的表,所以表设计的好坏,将直接影响着整个数据库。而在设计表的时候,最关注的一个问题是使用什么存储引擎。 

MySQL 中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种都 使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的、不同的功能和能力。通过选择不同的技术,能够获得额外的速度或者功能,从而改善应用的整体性能。

例如,如果在研究大量的临时数据,也许需要使用内存类存储引擎。内存存储引擎能够 在内存中存储相关数据。又或者,需要使用一个支持事务处理的数据库(以确保事务处理不成功时数据的回退能力)。

这些不同的技术以及配套的相关功能在 MySQL 中被称作存储引擎(也称作表类型)。 MySQL 默认配置了许多不同的存储引擎,可以预先设置或者在 MySQL 服务器中启用。选择适用于服务器、数据库和表格的存储引擎,可以在存储信息、检索数据时,提供最大的灵活性。

关系数据库表是用于存储和组织信息的数据结构,可以将表理解为由行和列组成的表 格,类似于 Excel 电子表格的形式。有的表简单、有的表复杂、有的表根本不用来存储任何 长期数据、有的表读取时非常快,但是插入数据时却很差。在实际开发过程中,就可能需要 各种各样的表,不同的表就意味着存储不同类型的数据,数据的处理上也会存在着差异。那 么,对于 MySQL 来说,它提供了很多种类型的存储引擎(或者说不同的表类型),根据对 数据处理的需求,可以选择不同的存储引擎,从而最大限度的利用 MySQL 强大的功能。

在 MySQL 客户端中,使用以下命令可以查看 MySQL 支持的引擎。

mysql> show engines;

3.1、MyISAM 存储引擎 

MyISAM 存储引擎不支持事务,也不支持外键,特点是访问速度快,对事务完整性没有要求,以 SELECT、INSERT 为主的应用基本都可以使用这个引擎来创建表。

每个 MyISAM 表在磁盘上存储成 3 个文件,其中文件名和表名都相同,但是扩展名分别为:

  • frm(存储表定义)
  • MYD(MYData,存储数据)
  • MYI(MYIndex,存储索引) 

数据文件和索引文件可以放置在不同的目录,平均分配 IO,获取更快的速度。要指定数据文件和索引文件的路径,需要在创建表的时候通过 DATA DIRECTORY 和 INDEX DIRECTORY 语句指定,文件路径需要使用绝对路径。 

每个 MyISAM 表都有一个标志,服务器或 myisamchk 程序在检查 MyISAM 数据表时 会对这个标志进行设置。MyISAM 表还有一个标志用来表明该数据表在上次使用后是不是被 正常的关闭了。如果服务器意外宕机或崩溃,这个标志可以用来判断数据表是否需要检查和 修复。如果想让这种检查自动进行,可以在启动服务器时使用--myisam-recover 实现。这会 让服务器在每次打开一个MyISAM数据表时自动检查数据表的标志并进行必要的修复处理。 MyISAM 类型的表可能会损坏,可以使用 CHECK TABLE 语句来检查 MyISAM 表的健康,并用 REPAIR TABLE 语句修复一个损坏的 MyISAM 表。

MyISAM 表还支持 3种不同的存储格式:

  • 静态(固定长度)表
  • 动态表
  • 压缩表

其中静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固 定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占 用的空间通常比动态表多。静态表在数据存储时会根据列定义的宽度定义补足空格,但是在 访问的时候并不会得到这些空格,这些空格在返回给应用之前已经去掉。同时需要注意:在 某些情况下可能需要返回字段后的空格,而使用这种格式时后面的空格会被自动处理掉。 

动态表包含可变字段,记录不是固定长度的,这样存储的优点是占用空间较少,但是频 繁的更新、删除记录会产生碎片,需要定期执行 OPTIMIZE TABLE 语句或 myisamchk -r 命令来改善性能,并且出现故障的时候恢复相对比较困难。 

压缩表由 myisamchk 工具创建,占据非常小的空间,因为每条记录都是被单独压缩的, 所以只有非常小的访问开支。 

3.2、InnoDB 存储引擎 

InnoDB 是一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为 用户操作非常大的数据存储提供了一个强大的解决方案。MySQL 从 5.5.5 版本开始,默认 的存储引擎为 InnoDB。InnoDB 存储引擎还引入了行级锁定和外键约束,在以下场景中使 用 InnoDB 存储引擎是最理想的选择:

  • 更新密集的表:InnoDB 存储引擎特别适合处理多重并发的更新请求。
  • 事务:InnoDB 存储引擎是支持事务的标准 MySQL 存储引擎。
  • 自动灾难恢复:与其它存储引擎不同,InnoDB 表能够自动从灾难中恢复。
  • 外键约束:MySQL 支持外键的存储引擎只有 InnoDB。
  • 支持自动增加列 AUTO_INCREMENT 属性。 

一般来说,如果需要事务支持,并且有较高的并发读取频率,InnoDB 是不错的选择。 而 MyISAM 和 InnoDB 两种存储引擎的区别主要表现在以下几个方面。

  • InnoDB 支持事务,MyISAM 不支持,这一点是非常重要的。事务是一种高级的处理方 式,如对一些表中的列进行增删改的过程中只要哪个出错还可以回滚还原,而 MyISAM就不可以。
  • MyISAM 适合查询、插入为主的应用,InnoDB 适合频繁修改以及涉及到安全性较高的应用。
  •  InnoDB 支持外键,MyISAM 不支持。
  • 从 MySQL5.5.5 以后,InnoDB 是默认引擎。
  • MySQL 从 5.6 版本开始 InnoDB 引擎才支持 FULLTEXT 类型的索引。
  • InnoDB 中不保存表的行数,如 select count(*) from table 时,InnoDB 需要扫描一遍整 个表来计算有多少行,但是 MyISAM 只要简单的读出保存好的行数即可。需要注意的 是,当 count(*)语句包含 where 条件时 MyISAM 也需要扫描整个表。
  • 对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在 MyISAM 表中可以 和其他字段一起建立组合索引。
  • 清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM 则会重建表。
  • InnoDB 支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like '%lee%';)。

3.3、关于 MyISAM 与 InnoDB 选择使用 

MyISAM 和 InnoDB 是 MySQL 数据库提供的两种存储引擎。两者的优劣可谓是各有千 秋。InnoDB 会支持一些关系数据库的高级功能,如事务功能和行级锁,MyISAM 不支持。 MyISAM 的性能更优,占用的存储空间少。所以,选择何种存储引擎,视具体应用而定。 

(1)如果应用程序一定要使用事务,毫无疑问要选择 InnoDB 引擎。但要注意,InnoDB 的行级锁是有条件的。在 where 条件没有使用主键时,照样会锁全表。比如 DELETE FROM mytable 这样的删除语句。

(2)如果应用程序对查询性能要求较高,就要使用 MyISAM 了。MyISAM 索引和数据 是分开的,而且其索引是压缩的,可以更好地利用内存。所以它的查询性能明显优于 InnoDB。 压缩后的索引也能节约一些磁盘空间。 

有人说 MyISAM 只能用于小型应用,其实这只是一种偏见。如果数据量比较大,这是 需要通过升级架构来解决,比如分表分库,而不是单纯地依赖存储引擎。

3.4、修改默认的存储引擎 

修改默认的存储引擎有几种方法,分别如下。 

(1)通过 alter table 修改。 

mysql> alter table info engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 

(2)通过修改 my.cnf,指定默认存储引擎并重启服务。 

[root@centos7-1 ~]# vim /etc/my.cnf
default-storage-engine=INNODB

(3)通过 create table 创建表时指定存储引擎。 

mysql> create table test(id int) engine=MyISAM;
Query OK, 0 rows affected (0.01 sec)

mysql> 
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值