博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入MySQL数据库的索引
阅读量:4069 次
发布时间:2019-05-25

本文共 7371 字,大约阅读时间需要 24 分钟。

<div id="veryContent" class="real_blog" style="text-indent: 2em; height: auto! important;">
<table id="blogContentTable" style="width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td style="" valign="top">
<div id="blogContainer" style="overflow: hidden; height: 100%;">
<img id="paperPicArea0" style="display: none;" src="ac/b.gif" alt=""><img id="paperPicArea" style="display: none;" src="ac/b.gif" alt=""><div id="blogDetailDiv" style="font-size: 16px;">索引是加速表内容访问的主要手段,特别对涉及多个表的连接的查询更是如此。这是数据库优化中的一个重要内容,我们要了解为什么需要索引,索引如何工作以及怎样利用它们来优化查询。本节中,我们将介绍索引的特点,以及创建和删除索引的语法。 <br><span style="font-weight: bold;">索引的特点</span> <br>所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。 <br>一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。 <br>对于CHAR和VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。 <br>MySQL能在多个列上创建索引。一个索引可以由最多15个列组成。(在CHAR和VARCHAR列上,你也可以使用列的前缀作为一个索引的部分)。 <br>虽然随着 MySQL 的进一步开发创建索引的约束将会越来越少,但现在还是存在一些约束的。下面的表根据索引的特性,给出了 ISAM 表和 MyISAM 表之间的差别: <br><div style="text-align: center;">
<a href="http://b20.photo.store.qq.com/http_imgload.cgi?/rurl4_b=2f94ff2e6d798e1b1804ae9a3ce944be64a007a0b05f4c3ee2037d9cecaf8ba0bf69e458afbeac4e8c7ff34d01a5a1e8d00515faeb9ba936866c13331d55e8be49e978d2dc645202afa5cfd02e225bea9e2043a7" target="_blank"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px;" src="http://b20.photo.store.qq.com/http_imgload.cgi?/rurl4_b=2f94ff2e6d798e1b1804ae9a3ce944be64a007a0b05f4c3ee2037d9cecaf8ba0bf69e458afbeac4e8c7ff34d01a5a1e8d00515faeb9ba936866c13331d55e8be49e978d2dc645202afa5cfd02e225bea9e2043a7" alt=""></a> </div>
<br>从此表中可以看到,对于 ISAM 表来说,其索引列必须定义为 NOT NULL,并且不能对 BLOB 和 TEXT 列进行索引。MyISAM 表类型去掉了这些限制,而且减缓了其他的一些限制。两种表类型的索引特性的差异表明,根据所使用的 MySQL 版本的不同,有可能对某些列不能进行索引。例如,如果使用3.23 版以前的版本,则不能对包含 NULL 值的列进行索引。 索引有如下的几种情况: <br>INDEX索引:通常意义的索引,某些情况下KEY是它的一个同义词。索引的列可以包括重复的值。 <br>UNIQUE索引:唯一索引,保证了列不包含重复的值,对于多列唯一索引,它保证值的组合不重复。 <br>PRIMARY KEY索引:也UNIQUE索引非常类似。事实上,PRIMARY KEY索引仅是一个具有PRIMARY名称的UNIQUE索引。这表示一个表只能包含一个PRIMARY KEY。 <br>为了给现有的表增加一个索引,可使用 ALTER TABLE 或 CREATE INDEX 语句。ALTER TABLE 最常用,因为可用它来创建普通索引、UNIQUE 索引或 PRIMARY KEY 索引,如: <br>ALTER TABLE tbl_name ADD INDEX index_name(column_list)ALTER TABLE tbl_name ADD UNIQUE index_name(column_list)ALTER TABLE tbl_name ADD PRIMARY KEY index_name(column_list) <br>其中 tbl_name 是要增加索引的表名,而 column_list 指出对哪些列进行索引。一个(col1,col2,...)形式的列表创造一个多列索引。索引值有给定列的值串联而成。如果索引由不止一列组成,各列名之间用逗号分隔。索引名 index_name 是可选的,因此可以不写它,MySQL 将根据第一个索引列赋给它一个名称。ALTER TABLE 允许在单个语句中指定多个表的更改,因此可以在同时创建多个索引。 <br>同样,也可以用ALTER TABLE语句产出列的索引: <br>ALTER TABLE tbl_name DROP INDEX index_nameALTER TABLE tbl_name DROP PRIMARY KEY <br>注意上面第一条语句可以用来删除各种类型的索引,而第三条语句只在删除 PRIMARY KEY 索引时使用;在此情形中,不需要索引名,因为一个表只可能具有一个这样的索引。如果没有明确地创建作为 PRIMARY KEY 的索引,但该表具有一个或多个 UNIQUE 索引,则 MySQL 将删除这些 UNIQUE 索引中的第一个。 <br>如果从表中删除了列,则索引可能会受到影响。如果所删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。 <br>例如,对于上面所使用的student为例,你可能想为之创建这样的索引,以加速表的检索速度: <br>mysql> ALTER TABLE student -> ADD PRIMARY KEY(id),-> ADD INDEX mark(english,Chinese,history); <br><br>这个例子,既包括PRIMARY索引,也包括多列索引。记住,使用PRIMARY索引的列,必须是一个具有NOT NULL属性的列,如果你愿意产看创建的索引的情况,可以使用SHOW INDEX语句: <br>mysql> SHOW INDEX FROM student; <br>其结果为: <br>+---------+------------+----------+--------------+-------------+- <br>| Table | Non_unique | Key_name | Seq_in_index | Column_name | <br>+---------+------------+----------+--------------+-------------+- <br>| student |0 | PRIMARY|1 | id| <br>| student |1 | mark |1 | english | <br>| student |1 | mark |2 | chinese | <br>| student |1 | mark |3 | history | <br>+---------+------------+----------+--------------+-------------+- <br>由于列数太多,上表并没有包括所有的输出,读者可以试着自己查看。 <br>再使用ALTER TABLE语句删除索引,删除索引需要知道索引的名字,你可以通过SHOW INDEX语句得到: <br>mysql> ALTER TABLE student DROP PRIMARY KEY,-> DROP INDEX mark; <br>再产看表中的索引,其语句和输出为: <br>mysql> SHOW INDEX FROM student;Empty set (0.01 sec) <br><br>还可以用CREATE INDEX语句来创建索引.CREATE INDEX 是在 MySQL 3.23版中引入的,但如果使用3.23 版以前的版本,可利用 ALTER TABLE 语句创建索引(MySQL 通常在内部将 CREATE INDEX 映射到 ALTER TABLE)。该语句创建索引的语法如下: <br>CREATE UNIQUE INDEX index_name ON tbl_name (column_list)CREATE INDEX index_name ON tbl_name (column_list) <br>tbl_name、index_name 和 column_list 具有与 ALTER TABLE 语句中相同的含义。这里索引名不可选。很明显,CREATE INDEX 可对表增加普通索引或 UNIQUE 索引,不能用 CREATE INDEX 语句创建 PRIMARY KEY 索引。 <br>可利用 DROP INDEX语句来删除索引。类似于 CREATE INDEX 语句,DROP INDEX 通常在内部作为一条 ALTER TABLE 语句处理,并且DROP INDEX是在 MySQL 3.22 中引入的。 <br>删除索引语句的语法如下: <br>DROP INDEX index_name ON tbl_name <br>还是上一节的例子,由于CREATE INDEX不能创建PRIMARY索引,所以这里我们值创建一个多列索引: <br>mysql> CREATE INDEX mark ON student(english,chinese,history); <br>同样的检查student表,可知: <br>mysql> SHOW INDEX FROM student; <br>+---------+------------+----------+--------------+-------------+ <br>| Table | Non_unique | Key_name | Seq_in_index | Column_name | <br>+---------+------------+----------+--------------+-------------+ <br>| student |1 | mark |1 | english | <br>| student |1 | mark |2 | chinese | <br>| student |1 | mark |3 | history | <br>+---------+------------+----------+--------------+-------------+ <br>然后使用下面的语句删除索引: <br>mysql> DROP INDEX mark ON student; <br>要想在发布 CREATE TABLE 语句时为新表创建索引,所使用的语法类似于 ALTER TABLE 语句的语法,但是应该在您定义表列的语句部分指定索引创建子句,如下所示: <br>CREATE TABLE tbl_name(…INDEX index_name (column_list),KEY index_name (column_list),UNIQUE index_name (column_list),PRIMARY KEY index_name (column_list),…) <br><br>与ALTER TABLE 一样,索引名对于 INDEX 和 UNIQUE 都是可选的,如果未给出,MySQL 将为其选一个。另外,这里KEY时INDEX的一个别名,具有相同的意义。 <br>有一种特殊情形:可在列定义之后增加 PRIMARY KEY 创建一个单列的PRIMARY KEY 索引,如下所示: <br>CREATE TABLE tbl_name( i INT NOT NULL PRIMARY KEY)该语句等价于以下的语句:CREATE TABLE tbl_name(i INT NOT NULL,PRIMARY KEY (i)) <br>前面所有表创建样例都对索引列指定了 NOT NULL。如果是 ISAM 表,这是必须的,因为不能对可能包含 NULL 值的列进行索引。如果是 MyISAM 表,索引列可以为 NULL,只要该索引不是 PRIMARY KEY 索引即可。 <br>在CREATE TBALE语句中可以某个串列的前缀进行索引(列值的最左边 n 个字符)。 <br>如果对某个串列的前缀进行索引,应用 column_list 说明符表示该列的语法为 col_name(n) 而不用col_name。例如,下面第一条语句创建了一个具有两个 CHAR 列的表和一个由这两列组成的索引。第二条语句类似,但只对每个列的前缀进行索引: <br>CREATE TABLE tbl_name(name CHAR(30),address CHAR(60),INDEX (name,address))CREATE TABLE tbl_name(name CHAR(30),address CHAR(60),INDEX (name(10),address(20))) <br>你可以检查所创建表的索引: <br>mysql> SHOW INDEX FROM tbl_name; <br>+----------+------------+----------+--------------+-------------+- <br>| Table| Non_unique | Key_name | Seq_in_index | Column_name | <br>+----------+------------+----------+--------------+-------------+- <br>| tbl_name |1 | name |1 | name| <br>| tbl_name |1 | name |2 | address | <br>+----------+------------+----------+--------------+-------------+- <br>在某些情况下,可能会发现必须对列的前缀进行索引。例如,索引行的长度有一个最大上限,因此,如果索引列的长度超过了这个上限,那么就可能需要利用前缀进行索引。在 MyISAM 表索引中,对 BLOB 或 TEXT 列也需要前缀索引。 <br>对一个列的前缀进行索引限制了以后对该列的更改;不能在不删除该索引并使用较短前缀的情况下,将该列缩短为一个长度小于索引所用前缀的长度的列。 <br><span style="font-weight: bold;">总结</span> <br>本节对索引的类型,已经如何创建索引做了介绍,其中涉及三个比较重要的SQL语句——ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它们的用法。 <br>索引最重要的功能是,通过使用索引加速表的检索,有关这方面的知识,将在第十章数据库优化中介绍。 <br><span style="font-weight: bold;">思考题</span> <br>1、建立一个如下所述的表: <br>data:FLOAT列,使用随机函数填充数据 <br>birth:DATETIME列,填充当前时间。 <br>然后,请录入几条数据。最后计算data列的平均值、总和、极值,并且按照data列降序排序检索值。 <br>2、分别使用标准SQL模式和扩展正规表达式模式匹配,匹配上面创建的表,假设你创建表的当前日期为2001-01-01,用模式匹配检索出birth列包含该日期的值。(实际上,上面的表中记录都是同一日期录入的,因此实际将返回全部记录。) <br>3、为前几章使用的数据表创建索引: <br>student:为id段创建一个PRIMARY索引,为english、chinese和history创建一个多列索引。 <br>pet:为name和owner段创建一个多类索引。 <br>4、删除为pet表创建的索引。 <!--v:3.2-->
</div>
</div>
</td>
</tr></tbody></table>
</div>

转载地址:http://tbaji.baihongyu.com/

你可能感兴趣的文章
linux和windows内存布局验证
查看>>
本地服务方式搭建etcd集群
查看>>
安装k8s Master高可用集群
查看>>
忽略图片透明区域的事件(Flex)
查看>>
Xpath使用方法
查看>>
移动端自动化测试-Mac-IOS-Appium环境搭建
查看>>
Selenium之前世今生
查看>>
Selenium-WebDriverApi接口详解
查看>>
Selenium-ActionChains Api接口详解
查看>>
Selenium-Switch与SelectApi接口详解
查看>>
Selenium-Css Selector使用方法
查看>>
Linux常用统计命令之wc
查看>>
Java.nio
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
PHP那点小事--三元运算符
查看>>
fastcgi_param 详解
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>