Mysql如何适当的添加索引介绍

插入模拟数据

这里先简单介绍一下索引:

mysql强制索引 数据库强制索引mysql强制索引 数据库强制索引


mysql强制索引 数据库强制索引


添加索引是为了提高数据库查询性能,索引是最物美价廉的东西了,不用加内存,不用改程序,不用调sql,只要执行个正确的create index ,查询的速度就可能提高百倍千倍,这可是有力的,可是天下没有没费的午餐,查询的速度的提高是以牺牲insert update delete的速度为代价的。而且索引大小一般是数据的三分之一 ,再加上索引要加载进内存的,如果全部字段都加索引会以牺牲内存为代价的,所以才要设当的添加索引。

这里简单介绍一下mysql中常用索引:

在添加索引之前先查看一下该表中已存在哪些索引:show index from 表名;

1、主键索引

注意: 主键索引一张表中只能有一个,但是可以添加多个索引 比如:索引、普通索引、全文索引。

主键索引:一般在建表的时候就添加了 比如:id 一般是主键索引加自动递增。

建表后添加主键索引 :alter table table_name add primary key (column name);

主键索引的特点:不能为空且。

2、普通索引

创建普通索引:alter table table_name add index 索引名(column1,column2);

3、索引

创建索引:ALTER TABLE `table_name` ADD UNIQUE (`column`);

索引与主键索引的区别:

索引:可以有多个null 但数据内容不能重复

两个区别就在于主键索引不能为null 索引可以有多个null 其余都一样。

4、全文索引

全文索引只有MyISAM有效(mysql5.6之后InnoDB也支持了全文索引)[5.7不支持MyISAM]

在创建表时创建全文索引:

CREATE TABLE `article` (

`title` varchar(200) DEFAULT NULL,

` content` text,

PRIMARY KEY (`id`),

) ENGINE=MyISAM(5.6之后InnoDB也支持全文索引 、5.7不支持MyISAM引擎) DEFAULT CHARSET=utf8;

在现有表中创建全文索引:

ALTER TABLE article ADD FULLTEXT INDEX fulltext_article(title,content);

创建完全文索引之后使用也有要注意的地方:

众所周知在数据库中进行模糊查询是使用like关键字进行查询的,例如:

SELECT FROM article WHERE content LIKE ‘%查询字符串%';

那么,我们在使用全文索引也这样使用吗?当然不是,我们必须使用特有的语法才能使用全文索引进行查询,例如,我们想要在article表的title和content列中全文检索指定的查询字符串,我们可以如下编写SQL语句:

SELECT FROM article WHERE MATCH(title,content) AGAINST (‘查询字符串');

强烈注意:MySql自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。如果需要对包含中文在内的文本数据进行全文检索,我们需要采用Sphinx(斯芬克斯)/Coreseek技术来处理中文。

如果可能,请尽量先创建表并插入所有数据后再创建全文索引,而不要在创建表时就直接创建全文索引,因为前者比后者的全文索引效率要高。

删除索引sql语句:alter table table_name drop index 索引名;

通过上面的简单介绍后,那么应该在哪些字段上添加索引呢?

1、 频繁查询的字段,应该创建索引。

2、更新非常频繁的字段,不应该创建索引。

3、性太的字段,比如 gender字段,就不应该创建索引。

4、不会出现在where条件之后的字段,不应该创建索引。

满足一下条件,应该创建索引:

1、频繁要查询的字段,经常出现在where条件后面的字段,应该创建索引。

2、更新不频繁的字段,可以创建索引。

索引使用的注意事项

1.对于IoDB刷页主要考虑以下两个因素:创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用。

比如我们对title,content 添加了复合索引

selec数据时,就可以停止查找了,因为后面的数据一定不满足要求。这样就可以利用索引了。t from table_name where;会用到索引

select from table_name where content = 'test';不会用到索引

2.对于使用like的查询,查询如果是‘%a'不会使用到索引,而 like 'a%'就会用到索引。最前面不能使用%和_这样的变化值

3.如果条件中有or,即使其中有条件带索引也不会使用。

handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。

handler_read_rnd_next:这个值越高,说明查询低效。

总结

mysql怎么创建索引

type:index

1.添加PRIMARY KEY(主键索引)

for i in `seq 1 50` ; do mysql -vvv -uroot test -e 'insert into employee values ("zhou",27760)'; done

mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )

2.添加UNIQUE(索引)

mysql>ALTER TABLE `table_name` ADD UNIQUE (

`column`

)3.添加INDEX(普通索引)

mysql>ALTER TABLE `table默认的分词器不支持中文,不能检索到中文中的英文单词。_name` ADD INDEX index_name ( `column` )

4.添加FULLTEXT(全文索引)

mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`)

5.添加多列索引

mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

下面是更加详细的方法

MySQL中可以使用alter table这个SQL语句来为表中的字段添加索引。

使用alter table语句来为表中的字段添加索引的基本语法是:

ALTER TABLE <表名> ADD INDEX (<字段>);

我们来尝试为test中t_name字段添加一个索引。

mysql> alter table test add index(t_name);

Query OK, 0 rows affected (0.17 sec)

Records: 0 Duplicates: 0 Warnings: 0

执行成功后,我们来看看结果。

+------------+-------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+------------+-------------+------+-----+---------+-------+

| t_id | int(11) | YES | | NULL | |

| t_name | varchar(50) | NO | MUL | NULL | |

| t_password | char(32) | YES | | NULL | |

| t_birth | date | YES | | NULL | |

+------------+-------------+------+-----+---------+-------+

4 rows in set (0.00 sec)

结果可以看出,t_name字段的Key这一栏由原来的空白变成了MUL。这个MUL是什么意思呢?简单解释一下:如果Key是MUL,那么该列的值可以重复,该列是一个非索引的前导列(列)或者是一个性索引的组成部分但是可以含有空值NULL。

MYSQL创建表的时候如何加“索引”?

mysql> describe ) ENGINE=InnoDB DEFAULT CHARSET=gbk;test;

兄弟,对于机械硬盘,开启连坐会减少随机IO的消耗,但对于SSD,没必要开启该参数。primary key是主键,每个表只能有一个主键,而且数据是的。x0dx0a可以这样写:x0dx0aCREATE TABLE IF NOT EXISTS `".$ctb_name."` (x0dx0a `id` INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,x0dx0a `keyid` VARCHAR(20) NOT NULL,x0dx0a `key` VARCHAR(20) NOT NULL,x0dx0a `stauts` BOOL NOT NULL DEFAULT'0',x0dx0aindex `idx_status`(`status`)x0dx0a )ENGINE = MYISAM DEFAULT CHARSET=utf8;x0dx0a不过,status是bool类型的字段,只有true和false,区分度太低,没有必要加索引。x0dx0ax0dx0a索引目的是为了使查询更快,区分度小的时候不如全表扫描。

MySQL的全文索引Fulltext Index | 包括ngram

当表的数量较少(少于search_depth,默认是63)的时候,这里直接蜕化为一个穷举搜索,优化器将穷举所有的left-deep树找到的执行。另外,优化器为了减少因为搜索空间庞大带来巨大的穷举消耗,所以使用了一个"偷懒"的参数prune_ll(默认打开),具体如何"偷懒",可以参考JOIN顺序选择的复杂度。不过至少需要有三个表以上的关联才会有"偷懒",所以本案例不适用。

InnoDB的全文索引使用反向索引的设计。反向索引存储了一个单词(word)列表,对于每个单词,都有一个文档的列表,来标识这个单词出现的地方。为了支持临近搜索(proximity search),每个单词的位置信息也以字节偏移的方式存储。

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。

当创建了InnoDB全文索引,一系列的索引表会一同被创建,见下面的例子:

最前面的六个表包含了反向索引,它们被称作附属索引表(auxiliary index table)。当输入的表被索引(tokenized)后,每个的单词(亦称作“tokens”)会被携带其DOC_ID和位置信息插入到索引表中。根据单词个字符的字符集排序权重,在六个索引表中对单词进行完全排序和分区。

反向索引分区到六个附属索引表以支持并行的索引创建。默认有2个线程索引(Tokenize)、排序、插入单词和关联数据到索引表中。工作的线程的数量由 innodb_ft_sort_pll_degree 配置项控制的。对于大表的全文索引,可以考虑增加线程数量。

如果主表创建在 xx表空间,索引表存储在它们自己的表空间中。反之,索引表存储于其索引的表空间中。

前面例子展示的另外一种索引表被称作通用索引表,它们被用于全文索引的“删除处理(deletion handing)”和存储内部状态。不同于为每个全文索引都各自创建的反向索引表,这组表对特定表的所有全文索引都是共用的。

即使全文索引删掉了,通用索引(Common Index)也会被保留,当全文索引删除后,为这个索引而创建的FTS_DOC_ID列依然保留,因为移除FTS_DOC_ID列会导致重构之前被索引的表。管理FTS_DOC_ID列需要用到通用索引表。

为了防止大量并发读写附属表,InnoDB使用全文索引缓存去临时缓存最近的插入行。在存满并刷入磁盘之前,缓存的内容一直存储在内存之中,可以通过查询 INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE 表去查看最近缓存的插入行。

缓存和批处理刷新行为避免了对辅助索引表的频繁更新,频繁更新可能会在繁忙的插入和更新期间导致并发访问问题。批处理还避免了对同一个word的多次插入,化的减少了重复的条目。相同的word会先merge再刷入到磁盘中,而不是为每个word单独插入,这样提高了插入效率并且使得索引附属表尽可能的小。

全文索引缓存只缓存最近插入的行,查询时,已经刷入磁盘(附属索引表)的数据不会再回到索引缓存中。附属索引表中的内容是直接查询的,最终返回的结果返回前需要将附属索引表的结果和索引缓存中的结果合并。

CREATE FULLTEXT INDEX ft_index ON xxxxxxxx(CONTEXT)

[2021-11-12 18:14:04] [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID

重点看一下这一行: [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID ,InnoDB重新构建了这个表,并且添加了一个列 FTS_DOC_ID 。

如果你自行定义 FTS_DOC_ID 列的话,你需要负责管理这个列,避免空值(empty)或者重复值。 FTS_DOC_ID 的值是不能被重复利用的,所以也就是说 FTS_DOC_ID 的值是需要一直增加的。

或者,你可以在 FTS_DOC_ID 列上创建所必须的索引FTS_DOC_ID_INDEX(全大写)。

mysql> CREATE UNIQUE INDEX FTS_DOC_ID_INDEX on opening_lines(FTS_DOC_ID);

如果你没有创建FTS_DOC_ID_INDEX,InnoDB会自动创建。

在MySQL 5.7.13前,允许FTS_DOC_ID与的FTS_DOC_ID之间的间隔为10000,在MySQL 5.7.13及之后的版本中,这个允许的间隔为65535。

为了避免重新构建表,FTS_DOC_ID列在删除了全文索引之后依然被保留。

删除被索引文件的一个记录,可能会在附属索引表中产生非常多的小的删除项,在并发访问时,会产生热点问题。为了避免这个问题,每当被索引表中的记录被删除时,会将被删文档的DOC_ID记录在一个特别的 FTS__DELETED 表中,同时全文索引中已经索引了的记录依然被保存。在返回查询结果前,使用 FTS__DELETED 中的信息去过滤掉已经删除掉了的DOC_ID。这种设计的优势在于删除速度快且消耗低。不好的地方在于索引的大小不能随着记录的删除而立即减少。为了删除已删除记录在全文索引中的项,需要对被索引的表执行OPTIMIZE TABLE,配合[ innodb_optimize_fulltext_only=ON ],去重构全文索引。

全文搜索只能看到已经提交了的数据。

你可以通过查询下面的INFORMATION_SCHEMA表,来或测试InnoDB的一些特殊文本处理。

InnoDB默认的Stopwords:

select from rmation_schema.INNODB_FT_DEFAULT_STOPWORD;

SQL中的(保留关键字):

Shell中的:for,while,echo

其他:###, , --,

被索引表数据量、索引表数据量

模糊匹配与严格匹配的性能距

需要将 innodb_optimize_fulltext_only 配置为ON,这里是否需要DBA在MySQL镜像中修改?

innodb_optimize_fulltext_only 设置为ON后,对系统有何影响需要评估。

innodb_optimize_fulltext_only

执行的时间、频率。查看索引的使用情况:show status like‘Handler_read%';

MySQL内建的全文检索解析器使用单词之间的空白作为分隔符以标识单词的头尾,但是这里有个限制,对于表意文字,它是没有单词分隔符的。为了解决这个限制,MySQL提供了支持中文、日语、韩语的 ngram 解析器。ngram解析器支持InnoDB和MyISAM。

Ngram是内建在服务中的插件,像其他自建在服务中的插件一样,服务启动时会自动加载它。全文检索的语法参考上面( Section 12.10, “Full-Text Search Functions” ),这里只讨论一些不同的地方。除了单词的最小、长度配置项([ innodb_ft_min_token_size ]innodb_ft_max_token_size,ft_min_word_len,ft_max_word_len,全文检索依赖一些配置项都是可以使用的。

Ngram默认索引的单词(token)的大小为2( 2bigram )。例如,索引的大小为2,Ngram解析器解析字符串“abc def”为四个单词元素(tokens):“ab”, “bc”, “de” and “ef”。

ngram token size is configurable using the ngram_token_size configuration option, which has a minimum value of 1 and maximum value of 10.

作为只读变量, ngram_token_size 只能在启动配置或者配置文件中指定

与默认的解析器相不大,多了一句: xxx WITH PARSER ngram

Ngram在解析时去除空格,如

MySQL内建的默认全文检索解析器将单词与Stopword列表中的做对比,如果单词与Stopword列表中的元素相同的话,这个单词则不会被索引。对于Ngram解析器,Stopword的处理方式不同。Ngram解析器不排除与stopword列表中的条目相等的token,而是排除包含stopwords的token。例如,设 ngram_token_size=2 ,包含“a,b”的文档将被解析为 “a,” h和“,b”。如果将逗号(“,”)定义为停止字,则 “a,”和“,b”都将不会加入索引中,因为它们包含逗号。

例子:

默认Ngram解析器使用默认的Stopword列表,这里面含有英文的Stopword。如果需要中文的Stopword,需要你自己创建。

Stopword的长度超过 ngram_token_size则会被忽略。

有两个文档,一个包含“ab”,另一个包含“abc”。对于搜索文本“abc”将转换成“ab”,“bc”。

略。

The search phrase “abc def” is converted to “ab bc de ef”, which returns documents containing “abc def” and “ab bc de ef”. A document that contains “abcdef” is not returned.

使用Ngram解析器好处是支持了中文的检索

如何在mysql中设置索引

() IND_L_D A.LastName = 'zhou'

1、首先打开Nicate,连接到数据库,打开表设计页面。

2、然后点击切换到索引,打开索引界面。

3、设置索引名,按下选择栏,打开栏位页面这里显效率高。索引列越多,通过索引筛选出的数据越少。有1000W条数据的表,有如下sql:selectfromtablewhereGid=1andCid=2andSId=3,设设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W10%=100w条数据,然后再回表从100w条数据中找到符合Gid=2andCid=3的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出1000w10%10%10%=1w,效率提升可想而知!示的是表的字段,选择要设置索引的字段。

4、然后按下索引类型观察上述两个explain结果中的type字段。查询中分别是:的下拉按钮,选择unique就是索引的意思。

5、按下索引方式选择btree,按下快捷键Crtl+S保存就完成索引设置了。

mysql如何建立索引

我们可以通过查看索引的属性来判断创建索引的方法。

查看索引的语法格式如下:

SHOW INDEX FROM <表名> [ FROM <数据库名>]

语法说明如下:

<表名>:指定需要查看索引的数据表名。

<数据库名>:指定需要查看索引的数据表所在的数据库,可省略。比如,SHOW INDEX FROM student FROM test; 语句表示查看 test 数据库中 student 数据表的索引。

示例

使用 SHOW INDEX 语句查看《MySQL创建索引》一节中 tb_stu_2 数据表的索引信息,SQL 语句和运行结果如下所示。

mysql> SHOW INDEX FROM tb_stu_2G

1. row

Non_unique: 0

Key_name: height

Seq_in_index: 1

Column_name: height

Collation: A

Cardinality: 0

Sub_part: NULL

Paand B.DepartmentName = 'TBX';cked: NULL

Null: YES

Index_type: BTREE

注:目前,使用MySql自带的全文索全文索引主要针对文本文件,比如文章、标题。引时,如果查询字符串的长度过短将无法得到期望的搜索结果。MySql全文索引所能找到的词默认最小长度为4个字符。另外,如果查询的字符串包含停止词,那么该停止词将会被忽略。Comment:

Index_comment:

1 row in set (0.03 sec)

其中各主要参数说明如下:

参数 说明

Key_name 表示索引的名称。

Seq_in_index 表示该列在索引中的位置,如果索引是单列的,则该列的值为 1;如果索引是组合索引,则该列的值为每列在索引定义中的顺序。

Column_name 表示定义索引的列字段。

Collation 表示列以何种顺序存储在索引中。在 MySQL 中,升序显示值“A”(升序),若显示为 NULL,则表示无分类。

Sub_part 表示列中被编入索引的字符的数量。若列只是部分被编入索引,则该列的值为被编入索引的字符的数目;若整列被编入索引,则该列的值为 NULL。

Packed 指示关键字如何被压缩。若没有被压缩,值为 NULL。

Null 用于显示索引列中是否包含 NULL。若列含有 NULL,该列的值为 YES。若没有,则该列的值为 NO。

Index_type 显示索引使用的类型和方法(BTREE、FULLTEXT、HASH、RTREE)。

Comment 显示评注。

MySQL字符串索引&amp;页刷盘

FULLTEXT KEY `title` (`title`,`content`)

对于字符串进行添加索引,我们除了对整个字符串加索引以外,还可以添加前缀索引。

什么是前缀索引?

前缀索引的好处?

使用前缀索引,定义好长度,可以做到即节省空间,又不用额外增加太多的查询成本。

前缀索引的弊端?

前缀索引会使覆盖索引失效,额外增加回表的消耗,如果前缀索引的长度选择区分度不高,会额外导致扫描行数增加。

什么是页?

当细节略,有例子: 内存被更新以后,内存中的数据页就会和磁盘上的数据页存在不一致的情况,该内存也就被称为 页 。

内存中的数据被写入磁盘以后,内容变为一致done,此时该内存页就被称为干净页。

什么叫刷页?

内存数据页中的内容被写入磁盘数据页中的过程称为刷页。

什么时候会刷页?

InnoDB如何控制刷页的频率?

首先确认InnoDB所在主机的IO能力,此时需要用到数据库的innodb_io_capacity参数,该参数设置为磁盘的IOPS。磁盘的IOPS可以通过fio工具进行测试。

页比例

参数innodb_max_dirty_pages_pct是页比例的上限,MySQL 8.0中是90%。

当前页比例可以通过Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total计算获得,具体sql计算指令如下:

连坐机制

InnoDB在刷页的时候,如果该页旁边的是页也是页,会同时把相邻的页刷掉。

该刷页行为由参数innodb_flush_neighbors控制:

“mysql”建表时使用key建立的索引有什么用?

主键索引:不能为null,且内容只能。

key 是数据库的物理结构,它包含两层意义,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的)。包括primary key, unique key, foreign key 等。

这两个条件都不是range,但是这里计算的值仍然会存储,在后面的ref访问方式评估的时候使用。这里的值是根据records_in_range接口返回,而对于InnoDB每次调用这个函数都会进行一次索引页的采样,这是一个很消耗性能的作,对于很多其他的关系数据库是使用"直方图"的统计数据来避免这次作(相信MariaDB后续版本ref:这种类型表示mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一一的扫描判断,也就是所谓你平常理解的使用索引查询会更快的取出数据。而要想实现这种查找,索引却是有要求的,要实现这种能快速查找的算法,索引就要满足特定的数据结构。简单说,也就是索引字段的数据必须是有序的,才能实现这种类型的查找,才能利用到索引。也将实现直方图统计信息)。

primary key 有两个作用,一是约束作用(constraint),用来规范一个存储主键和性,但同时也在此key上建立了一个index;

unique key 也有两个作用,一是约束作用(constraint),规范数据的性,但同时也在这个key上建立了一个index; foreign key也有两个作用,一是约束作用(constraint),规范数据的引用完整性,但同时也在这个key上建立了一个index;

(1)我们说索引分类,分为主键索引、索引、普通索引(这才是纯粹的index)等,也是基于是不是把index看作了key。 比如 create table t(id int, unique index inx_tx_id (id)); --index当作了key使用。

(2)最重要的也就是,不管如何描述,理解index是纯粹的index,还是被当作key,当作key时则会有两种意义或起两种作用。

mysql如何创建多个索引mysql如何创建多个索引文件

字符串加索引的方式?

关于MySQL复合索引的用法

可以创建多个MySQL的复合索引,每个复合索引可以包含一个或多个列。复合索引的基本原理是左对齐。例如,一个复合索引包含字段A、B和C,这实际上相当于创建五个索引,即:

那么问题来了,如果我们创建两个复合索引,复合索引1:包含A、B、C列,复合索引2:包含B、C列,MySQL会如何执行?

按照正常逻辑和复合索引原理,应该能命中的索引是A_B_C_index。让我们拭目以待!

结果:与上次检测不一致。虽然这个测试中有三个ABC列,但是命中索引是B_C_index。

结论:当命中两个或多个不同的复合索引时,MySQL会有不同的策略根据创建顺序选择其中一个复合索引。

mysql联合索引建立规则?

MySQL中联合索引规则:

1、需要加索引的字段,要在where条件中

2、数据量少的字段不需要加索引

3、如果where条件中是OR关系,加索引不起作用

4、符合最左原则。

create怎么加索引?

1.方式:在执行CREATE

2.方式:使用ALTERTABLE命令去增加索ALTERTABLEtable_nameADDINDEXindex_name(column_list);1ALTERTABLE用来创建普通索引、UNIQUE索引或PRIMARYKEY索引。其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。索引名index_name可自己命名,缺省时,MySQL将根据个索引列赋一个名称。另外,ALTERTABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。

3.方式:使用CREATEINDEX命令创建CREATEINDEXindex_nameONtab

mysql多表查询索引怎么使用?

1selectfromtable1,table2wheretable1.id=table2.id;2手册上有3是的4定期清理数据碎片

最左前缀匹配原则

在mysql建立联合索引时会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配,

示例:

对列Gid、列Cid和列Sid建一个联合索引

联合索引uni_Gid_Cid_SId实际建立了(Gid)、(Gid,Cid)、(Gid,Cid,SId)三个索引。

查询实例:

上面这个查询语句执行时会依照最左前缀匹配原则,检索时会使用索引(Gid,Cid)进行数据匹配。

注意

索引的字段可以是任意顺序的,如:

这两个查询语句都会用到索引(Gid,Cid),mysql创建联合索引的规则是首先会对联合合索引的最左边的,也就是个字段Gid的数据进行排序,在个字段的排序基础上,然后再对后面第二个字段Cid进行排序。其实就相当于实现了类似orderbyGidCid这样一种排序规则。

有人会疑惑第二个查询语句不符合最左前缀匹配:首先可以肯定是两个查询语句都保函索引(Gid,Cid)中的Gid、Cid两个字段,只是顺序不一样,查询条件一样,所查询的结果肯定是一样的。既然结果是一样的,到底以何种顺序的查询方式呢?此时我们可以借助mysql查询优化器explain,explain会纠正sql语句该以什么样的顺序执行效率,才生成真正的执行。

那么问题产生了?既然结果是一样的,到底以何种顺序的查询方式呢?

所以,而此时那就是我们的mysql查询优化器该登场了,sql语句中字段的顺序不需要和联合索引中定义的字段顺序一致,查询优化器会自己调整顺序,mysql查询优化器会判断纠正这条sql语句该以什么样的顺序执行效率,才生成真正的执行。所以,当然是我们能尽量的利用到索引时的查询顺序效率咯,所以mysql查询优化器会最终以这种顺序进行查询执行。

为什么要使用联合索引

减少开销。建一个联合索引(Gid,Cid,SId),实际相当于建了(Gid)、(Gid,Cid)、(Gid,Cid,SId)三个索引。每多一个索引,都会增加写作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!

覆盖索引。对联合索引(Gid,Cid,SId),如果有如下的sql:selectGid,Cid,SIdfromstudentwhereGid=1andCid=2。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io作。减少io作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。

缺点。联合索引越多,索引列越多,则创建的索引越多,索引都是存储在磁盘里的,通过索引算法(Btree代表索引算法使用二叉树的形式来做索引的)来查找数据,的确可以极大的提高查询效率,但是与此同时增删改的同时,需要更新索引,同样是需要花时间的,并且索引所占的磁盘空间也不小。

建议。单表尽可能不要超过一个联合索引,单个联合索引不超过3个字段。

引申

对于联合索引(Gid,Cid,SId),查询语句SELECTFROMstudentWHERECid=465176354;是否能够触发索引?大多数人都会说NO,实际上却是YES。

原因:

type:rTable 表示创建索引的数据表名,这里是 tb_stu_2 数据表。ef

index:这种类型表示mysql会对整个该索引进行扫描。要想用到这种类型的索引,对这个索引并无特别要求,只要是索引,或者某个联合索引的一部分,mysql都可能会采用index类型的方式扫描。但是呢,缺点是效率不高,mysql会从索引中的个数据一个个的查找到一个数据,直到找到符合判断条件的某个索引。所以,上述语句会触发索引。

索引类型?

索引就是一种将数据库中的记录按照特殊形式存储的数据结构。

通过索引,能够显著地提高数据查询的效率,从而提升的性能。

专业一点来说呢,索引是一个排好序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址。

在数据库十分庞大的时候,索引可以大大加快查询的速度,这是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据。

说起索引,其实并不是MySQL数据库特有的机制,在关系型数据库中都会有类似不同的实现。

这里我们也只是讨论MySQL数据库中的索引实现。

事实上,说是MySQL的mysql联合索引最左匹配原因?索引其实并不准确。

因为在MySQL中,索引是在存储引擎层而不是层实现的。

这意味着我们所讨论的索引准确来说是InnoDB引擎或MyISAM引擎或其它存储引擎所实现的。

所以索引即便是在MySQL中也没有统一的标准,不同存储引擎的所实现的索引工作方式也并不一样。

不是所有的存储引擎都支持相同类型的索引,即便是多个引擎支持同一种类型的索引,其底层的实现也可能不同。