【索引】索引的作用?为什么能够提高查询速度?以及索引用法(索引的原理)

分类: beat365app下载官网 时间: 2026-06-30 09:06:28 作者: admin 阅读: 430

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。

创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

建立索引会占用磁盘空间的索引文件。

为什么能够提高查询速度?

索引就是通过事先排好序,从而在查找时可以应用二分查找等高效率的算法。一般的顺序查找,复杂度为O(n),而二分查找复杂度为O(log2n)。当n很大时,二者的效率相差及其悬殊。 举个例子:表中有一百万条数据,需要在其中寻找一条特定id的数据。如果顺序查找,平均需要查找50万条数据。而用二分法,至多不超过20次就能找到。二者的效率差了2.5万倍!

在一个或者一些字段需要频繁用作查询条件,并且表数据较多的时候,创建索引会明显提高查询速度,因为可由全表扫描改成索引扫描。

(无索引时全表扫描也就是要逐条扫描全部记录,直到找完符合条件的,索引扫描可以直接定位)

不管数据表有无索引,首先在SGA的数据缓冲区中查找所需要的数据,如果数据缓冲区中没有需要的数据时,服务器进程才去读磁盘。1、无索引,直接去读表数据存放的磁盘块,读到数据缓冲区中再查找需要的数据。2、有索引,先读入索引表,通过索引表直接找到所需数据的物理地址,并把数据读入数据缓冲区中。

索引有什么副作用吗?

(1)索引是有大量数据的时候才建立的,没有大量数据反而会浪费时间,因为索引是使用二叉树建立.

(2)当一个系统查询比较频繁,而新建,修改等操作比较少时,可以创建索引,这样查询的速度会比以前快很多,同时也带来弊端,就是新建或修改等操作时,比没有索引或没有建立覆盖索引时的要慢。

(3)索引并不是越多越好,太多索引会占用很多的索引表空间,甚至比存储一条记录更多。对于需要频繁新增记录的表,最好不要创建索引,没有索引的表,执行insert、append都很快,有了索引以后,会多一个维护索引的操作,一些大表可能导致insert 速度非常慢。

例子:

建立索引:(在username列建立索引)

ALTER table tableName ADD INDEX indexName(username)

利用explain分析索引: 参考 :http://www.cnblogs.com/qlqwjy/p/7767479.html

1.没有查询username(不用索引)

EXPLAIN SELECT * FROM USER

2.根据username进行比对:(使用索引)

EXPLAIN SELECT * FROM USER WHERE username='qlq'

索引用法:

普通索引

创建索引

这是最基本的索引,它没有任何限制。它有以下几种创建方式:

CREATE INDEX indexName ON mytable(username(length));

如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。

修改表结构(添加索引)

ALTER table tableName ADD INDEX indexName(columnName)

创建表的时候直接指定

CREATE TABLE mytable(

ID INT NOT NULL,

username VARCHAR(16) NOT NULL,

INDEX [indexName] (username(length))

);

删除索引的语法

DROP INDEX [indexName] ON mytable; ALTER TABLE `exam5`.`questions` DROP KEY `question_type_index`;

唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:

创建索引

CREATE UNIQUE INDEX indexName ON mytable(username(length))

修改表结构

ALTER table mytable ADD UNIQUE [indexName] (username(length))

创建表的时候直接指定

CREATE TABLE mytable(

ID INT NOT NULL,

username VARCHAR(16) NOT NULL,

UNIQUE [indexName] (username(length))

);

使用ALTER 命令添加和删除索引

有四种方式来添加数据表的索引:

ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。

ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。

ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。

ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。

以下实例为在表中添加索引。

mysql> ALTER TABLE testalter_tbl ADD INDEX (c);

你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引:

mysql> ALTER TABLE testalter_tbl DROP INDEX c;

使用 ALTER 命令添加和删除主键

主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:

mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;

mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);

你也可以使用 ALTER 命令删除主键:

mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;

删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。

显示索引信息

你可以使用 SHOW INDEX 命令来列出表中的相关的索引信息。

mysql查看表索引

mysql> show index from tblname;

mysql> show keys from tblname;

· 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

参考:http://www.jb51.net/article/73372.htm

自己的实践:

1.单列建立索引

表名 questions

结构:

未建立索引

查看一个数据量非常大的试题表,根据试题的类型查:

SELECT * FROM questions WHERE TYPE='单选题'

结果:花费1062ms

/*[15:03:40][1062 ms]*/ SELECT * FROM questions WHERE TYPE='单选题' LIMIT 0, 1000;

用explain解释语句之后:

EXPLAIN SELECT * FROM questions WHERE TYPE='单选题'

结果:可以简单的看到一些参数,扫描了7134行,命中率大概为10%.

建立索引

在type这一列建立索引

ALTER TABLE questions ADD INDEX index_ques_type(TYPE)

再次用explain分析执行语句

EXPLAIN SELECT * FROM questions WHERE TYPE='单选题'

结果: 扫描的行数明显减少,且命中率明显上升

2.建立组合索引

(1)未加索引

SELECT *

FROM questions

WHERE TYPE = '单选题'

AND questionBankId = '40b7fedfbd1c4cc680d93782a033a518'

结果:

explain解释执行

EXPLAIN

SELECT *

FROM questions

WHERE TYPE = '单选题'

AND questionBankId = '40b7fedfbd1c4cc680d93782a033a518'

(2)建立多列索引

ALTER TABLE `exam5`.`questions` ADD INDEX `index_duolie` (`questionBankId`, `type`)

(3) 查询:(速度明显提高)

SELECT *

FROM questions

WHERE

questionBankId = '40b7fedfbd1c4cc680d93782a033a518' AND TYPE = '单选题'

explain解释语句(使用了索引)

EXPLAIN

SELECT *

FROM questions

WHERE

questionBankId = '40b7fedfbd1c4cc680d93782a033a518' AND TYPE = '单选题'

(4)查看索引

SHOW INDEX FROM questions

(5)使用单列索引中的一列

1.只使用questionBankId 这一列看到查询时使用了索引

EXPLAIN

SELECT *

FROM questions

WHERE

questionBankId = '40b7fedfbd1c4cc680d93782a033a518'

2.只使用type这一列没有使用索引

EXPLAIN

SELECT *

FROM questions

WHERE TYPE = '单选题'

3 type和questionBankId交换位置使用索引

EXPLAIN

SELECT *

FROM questions

WHERE TYPE = '单选题' AND questionBankId = '40b7fedfbd1c4cc680d93782a033a518'

总结:对于单列索引,使用where条件就可以进行查询

对于多列索引(A,B),如果where中只有A可以起到作用,只有B不会使用索引,A、B都有会使用索引,也就是在有A的条件下才会使用索引。

参考:

http://www.runoob.com/mysql/mysql-index.html

相关文章

365bet官网体育娱乐

怎么捉苍蝇?如何在家里的房间里快速捕捉?为什么很难捉苍蝇?没有特殊工具,你怎么能在厨房里捉蠓?

365bet亚洲版官

patience更多的中文(简体)翻译

365bet亚洲版官

诛仙3玩家心得交流,第一行者轮回世界