龙空技术网

「MySQL入门」MySQL引擎知多少?

猿学堂 340

前言:

而今看官们对“mysql查询引擎”大约比较着重,朋友们都想要分析一些“mysql查询引擎”的相关文章。那么小编同时在网上收集了一些有关“mysql查询引擎””的相关内容,希望看官们能喜欢,咱们快快来了解一下吧!

数据库存储引擎是数据库底层软件组件,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。MySQL的核心就是存储引擎。

数据库引擎简介

MySQL提供了多个不同的存储引擎,包括处理事务安全表的引擎和处理非事务安全表的引擎。在MySQL中,不需要在整个服务器中使用同一种存储引擎,针对具体的要求,可以对每一个表使用不同的存储引擎。MySQL 8.0支持的存储引擎有InnoDB、MyISAM、Memory、Merge、Archive、Federated、CSV、BLACKHOLE等。

可以使用SHOW ENGINES语句查看系统支持的引擎类型。

Support列的值表示某种引擎是否能使用:YES表示可以使用,NO表示不能使用,DEFAULT表示该引擎为当前默认存储引擎。

InnoDB引擎

InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。MySQL 5.5.5之后,InnoDB作为默认存储引擎,主要特性如下:

InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供一个类似Oracle的非锁定读。这些功能增加了多用户部署和性能。在SQL查询中,可以自由地将InnoDB类型的表与其他MySQL表的类型混合起来,甚至在同一个查询中也可以混合。InnoDB存储引擎完全与MySQL服务器整合,为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB将它的表和索引存在一个逻辑表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与MyISAM表不同,比如在MyISAM表中每个表被存在分离的文件中。InnoDB表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上。InnoDB支持外键完整性约束(FOREIGN KEY)。存储表中的数据时,每张表的存储都按主键顺序存放,如果没有显示在表定义时指定主键,InnoDB会为每一行生成一个6B的ROWID,并以此作为主键。InnoDB被用在众多需要高性能的大型数据库站点上。InnoDB不创建目录,使用InnoDB时,MySQL将在数据目录下创建一个名为ibdata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件。MyISAM存储引擎

MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事务。MyISAM的主要特性如下:

在支持大文件(达63位文件长度)的文件系统和操作系统上被支持。当把删除和更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块以及若下一个块被删除则扩展到下一块来自动完成。每个MyISAM表最大的索引数是64,这可以通过重新编译来改变。每个索引最大的列数是16个。最大的键长度是1000B,这也可以通过编译来改变。对于键长度超过250B的情况,一个超过1024B的键将被用上。BLOB和TEXT列可以被索引。NULL值被允许在索引的列中,这个值占每个键的0~1个字节。所有数字键值以高字节优先被存储,以允许一个更高的索引压缩。每个表一个AUTO_INCREMENT列的内部处理。MyISAM为INSERT和UPDATE操作自动更新这一列,这使得AUTO_INCREMENT列更快(至少10%)。在序列顶的值被删除之后就不能再利用。可以把数据文件和索引文件放在不同目录。每个字符列可以有不同的字符集。有VARCHAR的表可以固定或动态记录长度。VARCHAR和CHAR列可以多达64KB。MEMORY存储引擎

MEMORY存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问。MEMORY的主要特性如下:

MEMORY表的每个表可以有多达32个索引,每个索引16列,以及500B的最大键长度。MEMORY存储引擎执行HASH和BTREE索引。可以在一个MEMORY表中有非唯一键。MEMORY表使用一个固定的记录长度格式。MEMORY不支持BLOB或TEXT列。MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引。MEMORY表在所有客户端之间共享(就像其他任何非TEMPORARY表)。MEMORY表内容被存在内存中,内存是MEMORY表和服务器在查询处理时的空闲中创建的内部表共享。当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行DELETE FROM或TRUNCATE TABLE,或者删除整个表(使用DROPTABLE)。MEGER存储引擎

MERGE存储引擎是一组MyISAM表组合,将一组结构相同的MyISAM表组合成一个逻辑单元,通常也叫作MRG_MYISAM存储引擎。MERGE表本身没有数据,对于MERGE类型表的插入操作是通过INSERT_METHOD子句完成的,可以使用FIRST或者LAST值,使其数据增加到第一个表或者最后一个表上。其实,上述操作是对内部MyISAM表进行的操作,所以在创建MERGE表时,MySQL只会生成两个较小的文件:一个是.frm的文件,用于存放数据;还有一个.MRG文件,用于存放MERGE表的名称,包括MERGE表由哪些表组成。

BerkeleyDB存储引擎

BerkeleyDB存储引擎不是MySQL开发的存储引擎,是由Sleepycat Software开发的事务性存储引擎,简称为BDB。创建BDB表会生成两个数据文件,文件的名字用表名来开头,扩展名表示其不同的文件类型:一个.frm文件,存储表元数据;一个.db文件,包含数据和索引内容。另外,为了实现事务安全,BDB有自己的redo日志。

优化查询

查询是数据库中最频繁的操作,提高查询速度可以有效地提高MySQL数据库的性能。

分析语句

通过对查询语句的分析,可以了解查询语句执行情况,找出查询语句执行的瓶颈,从而优化查询语句。MySQL中提供了EXPLAIN语句和DESCRIBE语句,用来分析查询语句。本小节将为读者介绍使用EXPLAIN语句和DESCRIBE语句分析查询语句的方法。EXPLAIN语句的基本语法如下:

EXPLAIN SELECT .....

select_options是SELECT语句的查询选项,包括FROM WHERE子句等。

执行该语句,可以分析EXPLAIN后面SELECT语句的执行情况,并且能够分析出所查询表的一些特征。

使用EXPLAIN分析一个SQL语句:

下面对查询结果进行解释:

id:SELECT识别符。这是SELECT的查询序列号。select_type:表示SELECT语句的类型。它可以是以下几种取值:SIMPLE表示简单查询,其中不包括连接查询和子查询;PRIMARY表示主查询,或者是最外层的查询语句;UNION表示连接查询的第2个或后面的查询语句;DEPENDENT UNION,连接查询中的第2个或后面的SELECT语句,取决于外面的查询;UNION RESULT,连接查询的结果;SUBQUERY,子查询中的第1个SELECT语句;DEPENDENT SUBQUERY,子查询中的第1个SELECT,取决于外面的查询;DERIVED,导出表的SELECT(FROM子句的子查询)。table:表示查询的表。type:表示表的连接类型。下面按照从最佳类型到最差类型的顺序给出各种连接类型。System:该表是仅有一行的系统表。这是const连接类型的一个特例。const:数据表最多只有一个匹配行,将在查询开始时被读取,并在余下的查询优化中作为常量对待。const表查询速度很快,因为它们只读取一次。const用于使用常数值比较PRIMARY KEY或UNIQUE索引的所有部分的场合。SELECT * FROM ORDERS WHERE ORDER_ID = 1;eq_ref:对于每个来自前面的表的行组合,从该表中读取一行。当一个索引的所有部分都在查询中使用并且索引是UNIQUE或PRIMARY KEY时,即可使用这种类型。eq_ref可以用于使用“=”操作符比较带索引的列。比较值可以为常量或一个在该表前面所读取的表的列的表达式。在下面的例子中,MySQL可以使用eq_ref连接来处理ref_tables:ref:对于来自前面的表的任意行组合,将从该表中读取所有匹配的行。这种类型用于索引既不是UNIQUE也不是PRIMARY KEY的情况,或者查询中使用了索引列的左子集,即索引中左边的部分列组合。ref可以用于使用=或<=>操作符带索引的列。SELECT * FROM ORDERS O ,ORDER_DETAIL D WHERE D.ORDER_NUM = O.ORDER_NUM AND D.ORDER_NUM = 20198876544;ref_or_null:该连接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该连接类型的优化。index_merge:该连接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用索引的最长关键元素。unique_subquery:该类型替换了下面形式的IN子查询的ref,unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。index_subquery:该连接类型类似于unique_subquery,可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引。range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符用常量比较关键字列时,类型为range。index:该连接类型与ALL相同,除了只扫描索引树。这通常比ALL快,因为索引文件通常比数据文件小。ALL:对于前面的表的任意行组合,进行完整的表扫描。如果表是第一个没标记const的表,这样不好,并且在其他情况下很差。通常可以增加更多的索引来避免使用ALL连接。possible_keys:指出MySQL能使用哪个索引在该表中找到行。如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看它是否引用某些列或适合索引的列来提高查询性能。如果是这样,可以创建适合的索引来提高查询的性能。key:表示查询实际使用到的索引,如果没有选择索引,该列的值是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。key_len:表示MySQL选择的索引字段按字节计算的长度,如果键是NULL,则长度为NULL。注意通过key_len值可以确定MySQL将实际使用一个多列索引中的几个字段。ref:表示使用哪个列或常数与索引一起来查询记录。rows:显示MySQL在表中进行查询时必须检查的行数。Extra:表示MySQL在处理查询时的详细信息。索引索引简介

索引是一个单独的、存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。使用索引可以快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。例如,数据库中有2万条记录,现在要执行一个查询“SELECT * FROM tablewhere num=10000”,如果没有索引,就必须遍历整个表,直到num等于10000的这一行被找到为止;如果在num列上创建索引,MySQL不需要任何扫描,直接在索引里面找10000,就可以得知这一行的位置。可见,索引的建立可以提高数据库的查询速度。

索引是在存储引擎中实现的,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型。根据存储引擎定义每个表的最大索引数和最大索引长度。所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节。大多数存储引擎有更高的限制。MySQL中索引的存储类型有两种,即BTREE和HASH,具体和表的存储引擎相关;MyISAM和InnoDB存储引擎只支持BTREE索引;MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。

索引的优点主要有以下几条:

通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。可以大大加快数据的查询速度,这也是创建索引的主要原因。在实现数据的参考完整性方面,可以加速表和表之间的连接。在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。

索引也有许多不利的方面,主要表现在如下几个方面:

创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。索引的分类

在关系数据库中,索引是一种单独的、物理的数对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。

MySQL的索引可以分为以下几类:

普通索引和唯一索引

普通索引是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值。唯一索引要求索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。主键索引是一种特殊的唯一索引,不允许有空值。

单例索引和组合索引

单列索引即一个索引只包含单个列,一个表可以有多个单列索引。组合索引是指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合。

全文索引

全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。MySQL中只有MyISAM存储引擎支持全文索引。

空间索引

空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING和POLYGON。MySQL使用SPATIAL关键字进行扩展,使得能够用创建正规索引类似的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MyISAM的表中创建。

创建索引创建普通索引

最基本的索引类型,没有唯一性之类的限制,其作用只是加快对数据的访问速度

创建索引的语句如下:

CREATE TABLE TEST1(  ID INT NOT NULL,  NAME VARCHAR(10),  INDEX (ID) );

也可以使用如下语句:

CREATE INDEX index_name ON TEST1(ID);
创建唯一索引

创建唯一索引的主要原因是减少查询索引列操作的执行时间,尤其是对比较庞大的数据表。它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

创建索引语句如下:

CREATE TABLE TEST2(  ID INT NOT NULL,  NAME CHAR(30),  UNIQUE INDEX UNIQIDX(ID) );

也可以使用如下语句:

CREATE UNIQUE index_name ON TEST2 (ID)
创建单列索引

单列索引是在数据表中的某一个字段上创建的索引,一个表中可以创建多个单列索引。前面两个例子中创建的索引都为单列索引。

创建单列索引语句如下:

CREATE TABLE TEST3(  ID INT NOT NULL,  NAME CHAR(50),  INDEX SINGLEIDX(NAME(50)) )
创建组合索引

组合索引是在多个字段上创建一个索引。

CREATE TABLE TEST4(  ID INT NOT NULL,  NAME CHAR(30) NOT NULL,  AGE INT NOT NULL,  INDEX MULTIINDEX(ID,NAME,AGE) )

组合索引可起几个索引的作用,但是使用时并不是随便查询哪个字段都可以使用索引,而是遵从“最左前缀”:利用索引中最左边的列集来匹配行,这样的列集称为最左前缀。例如,这里由id、name和age 3个字段构成的索引,索引行中按id、name、age的顺序存放,索引可以搜索(id, name, age)、(id, name)或者id字段组合。如果列不构成索引最左面的前缀,那么MySQL不能使用局部索引,如(age)或者(name,age)组合则不能使用索引查询。

创建全文索引

FULLTEXT全文索引可以用于全文搜索。只有MyISAM存储引擎支持FULLTEXT索引,并且只为CHAR、VARCHAR和TEXT列创建索引。索引总是对整个列进行。

CREATE TABLE TEST5(  ID INT NOT NULL,  NAME CHAR(30) NOT NULL,  AGE INT NOT NULL,  INFO VARCHAR(255),  FULLTEXT INDEX FULLTXTIDX(INFO) )ENGINE = MyISAML

注意:因为MySQL 8.0中默认存储引擎为InnoDB,在这里创建表时需要修改表的存储引擎为MyISAM,不然创建索引会出错。

创建空间索引

空间索引必须在MyISAM类型的表中创建,且空间类型的字段必须为非空。

CREATE TABLE TEST6(  NAME GEOMETRY NOT NULL,  SPATIAL INDEX SPALIDEX(NAME) )ENGINE = MyISAML

如果表在创建时没有添加索引,或者随着业务需求变化对数据表优化时可以使用ALTER语句添加索引,语法付下

ALTER TABLE TABLE_NAME ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX] [INDEX_NAME] (COL1,....)
删除索引

MySQL中删除索引使用ALTER TABLE或者DROP INDEX语句,两者可实现相同的功能,DROP INDEX语句在内部被映射到一个ALTER TABLE语句中。

ALTER TABLE TABLE_NAME DROP INDEX INDEX_NAME;

或者

DROP INDEX INDEX_NAME ON TABLE TABLE_NAME;
索引的原理B-Tree

B树,即平衡多路查找树(B-Tree),是为磁盘等外存储设备设计的一种平衡查找树。

B树简略示意图

B树的两个特点:

树内的每个节点都存储数据叶子节点之间无指针连接

B树每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点能存储的key的数量很小,要保存同样多的key,就需要增加树的高度。树的高度每增加一层,查询时的磁盘I/O次数就增加一次,进而影响查询效率。

B+Tree

MySQL 的存储方式根据存储引擎的不同而不同,我们最常用的就是 Innodb 存储引擎,它就是采用了 B+ 树作为了索引的数据结构。B+ 树就是对 B 树做了一个升级.

下图就是 Innodb 里的 B+ 树:

但是 Innodb 使用的 B+ 树有一些特别的点,比如:

B+ 树的叶子节点之间是用「双向链表」进行连接,这样的好处是既能向右遍历,也能向左遍历。B+ 树点节点内容是数据页,数据页里存放了用户的记录以及各种信息,每个数据页默认大小是 16 KB。

Innodb 根据索引类型不同,分为聚集和二级索引。他们区别在于,聚簇索引的叶子节点存放的是实际数据,所有完整的用户记录都存放在聚集索引的叶子节点,而二级索引的叶子节点存放的是主键值,而不是实际数据。

因为表的数据都是存放在聚集索引的叶子节点里,所以 InnoDB 存储引擎一定会为表创建一个聚集索引,且由于数据在物理上只会保存一份,所以聚簇索引只能有一个,而二级索引可以创建多个。

回表或者二次查询:使用聚集索引查询可以直接定位到记录,而普通索引通常需要扫描两遍索引树,即先通过普通索引定位到主键值,在通过聚集索引定位到行记录,这就是所谓的回表查询,它的性能比扫描一遍索引树低。解决办法是建立联合索引。

B-Tree和B+Tree的区别

MySQL 是会将数据持久化在硬盘,而存储功能是由 MySQL 存储引擎实现的,所以讨论 MySQL 使用哪种数据结构作为索引,实际上是在讨论存储引使用哪种数据结构作为索引,InnoDB 是 MySQL 默认的存储引擎,它就是采用了 B+ 树作为索引的数据结构。

而树的高度决定于磁盘 I/O 操作的次数,因为树是存储在磁盘中的,访问每个节点,都对应一次磁盘 I/O 操作,也就是说树的高度就等于每次查询数据时磁盘 IO 操作的次数,所以树的高度越高,就会影响查询性能。

B 树和 B+ 都是通过多叉树的方式,会将树的高度变矮,所以这两个数据结构非常适合检索存于磁盘中的数据。

两者的区别主要如下:

B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树高度更低,查询底层节点的磁盘 I/O次数会更少。B+ 树有大量的冗余节点(所有非叶子节点都是冗余索引),这些冗余索引让 B+ 树在插入、删除的效率都更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化。B+ 树叶子节点之间用链表连接了起来,有利于范围查询,而 B 树要实现范围查询,因此只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率不如 B+ 树。索引对查询速度的影响

MySQL中提高性能的一个有效方式就是对数据表设计合理的索引。索引提供了高效访问数据的方法,并且可加快查询的速度,因此,索引对查询的速度有着至关重要的影响。使用索引可以快速地定位表中的某条记录,从而提高数据库查询的速度、提高数据库的性能。本小节将为读者介绍索引对查询速度的影响。如果查询时没有使用索引,查询语句将扫描表中的所有记录。在数据量大的情况下,这样查询的速度会很慢。如果使用索引进行查询,查询语句可以根据索引快速定位到待查询记录,从而减少查询的记录数,达到提高查询速度的目的。

下面通过测试来查看索引对查询的影响,先新数据库和表:

CREATE DATABASE TEST_DB;USE TEST_DB;CREATE TABLE TEST(	ID INT,  NAME VARCHAR(30))

创建好表后,在数据表中插入10万条数据。并查询一条数据:

SELECT * FROM TEST WHERE ID = 99999;

结果如下:

使用EXPLAIN语句分析该查询:

因为没有创建索引,所以type值为ALL,也就是说进行了全表扫描。

接下来,为ID列添加唯一索引,并再次查询。

ALTER TABLE TEST ADD INDEX UNI_IDX(ID);

结果如下:

从结果可以看出查询时间明显缩短,再次使用EXPLAIN分析查询语句,结果如下:

从结果中可以看出使用了新建的索引。

索引失效的场景

索引可以提高查询的速度,但并不是使用带有索引的字段查询时索引都会起作用。

使用索引有几种特殊情况,在这些情况下有可能使用带有索引的字段查询时索引并没有起作用。

单字段有索引,WHERE条件使用多字段(含带索引的字段),例如select * from student where name ='张三' AND addr = '北京市';语句,如果name有索引而addr没索引,那么SQL语句不会使用索引。多字段索引,违反最佳左前缀原则。例如,student表如果建立了(name,addr,age)这样的索引,WHERE后的第一个查询条件一定要是name,索引才会生效。当查询条件为“等值或范围查询”时,索引可以根据查询条件去找对应的条目。否则,索引定位困难(结合查字典的例子去理解),执行计划此时可能更倾向于全表扫描,这类的查询条件有:<>、NOT、in、not exists使用LIKE关键字的查询语句:在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置,索引才会起作用。使用多列索引的查询语句:MySQL可以为多个字段创建索引。一个索引可以包括16个字段。对于多列索引,只有查询条件中使用了这些字段中的第1个字段时索引才会被使用(最左匹配原则)。使用OR关键字的查询语句:查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引;否则,查询将不使用索引。在索引上使用函数:例如select * from student where upper(name)='ZHANGFEI';会导致索引失效,而select * from student where name=upper('ZHANGFEI');是会使用索引的。在索引列上计算 :例如select * from student where age-1=17;。在索引列上使用mysql的内置函数,索引失效,例如:SELECT * FROM student WHERE create_time = now();索引了数据类型不匹配,例如:如果age字段有索引且类型为字符串但条件值为非字符串,索引失效,例如SELECT * FROM student WHERE age=18;会导致索引失效。索引列使用IS NOT NULL或者IS NULL可能会导致无法使用索引。优化子查询

MySQL从4.1版本开始支持子查询,使用子查询可以进行SELECT语句的嵌套查询,即一个SELECT查询的结果作为另一个SELECT语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作。子查询虽然可以使查询语句很灵活,但执行效率不高。执行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。

在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引,性能会更好。连接之所以更有效率,是因为MySQL不需要在内存中创建临时表来完成查询工作。

标签: #mysql查询引擎