索引及其优化

MySQL索引

      索引是一种特殊的文件 (InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。在没有索引的情况下,数据库会遍历全部200条数据后选择符合条件的;而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。
     索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。

1. 普通索引

     这是最基本的索引,它没有任何限制, MyIASM 中默认的 BTREE 类型的索引,也是我们大多数情况下用到的索引
(1)直接创建索引

CREATE INDEX index_name ON table(column(length))

(2)修改表结构的方式添加索引

ALTER TABLE table_name ADD INDEX index_name ON (column(length))

(3)创建表的时候同时创建索引

 CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX index_name (title(length))
)

(4)删除索引

 DROP INDEX index_name ON table

2. 唯一索引

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

CREATE UNIQUE INDEX indexName ON table(column(length))

(2)修改表结构

ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))

(3)创建表的时候直接指定

CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
UNIQUE indexName (title(length))
);

3. 全文索引(FULLTEXT)

      FULLTEXT 索引仅可用于 MyISAM 表;他们可以从 CHAR、VARCHAR 或 TEXT 列中作为 CREATE TABLE 语句的一部分被创建,或是随后使用 ALTER TABLE 或 CREATE INDEX 被添加。对于较大的数据集,将你的资料输入一个没有 FULLTEXT 索引的表中,然后创建索引,其速度比把资料输入现有 FULLTEXT 索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
(1)创建表的适合添加全文索引

 CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
FULLTEXT (content)
);

(2)修改表结构添加全文索引

ALTER TABLE article ADD FULLTEXT index_content(content)

(3)直接创建索引

CREATE FULLTEXT INDEX index_content ON article(content)

4. 单列索引、多列索引

     多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL 只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。

5. 组合索引(最左前缀)

     平时用的 SQL 查询语句一般都有比较多的限制条件,所以为了进一步榨取 MySQL 的效率,就要考虑建立组合索引。例如上表中针对 title 和 time 建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:
–title,time
–title
     为什么没有 time 这样的组合索引呢?这是因为 MySQL 组合索引 “最左前缀” 的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引,如下面的几个 SQL 所示:
(1)使用到上面的索引

SELECT * FROM article WHREE title='测试' AND time=1234567890;
SELECT * FROM article WHREE utitle='测试';

(2)不使用上面的索引

SELECT * FROM article WHREE time=1234567890;

索引缺点:

     虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 INSERT、UPDATE 和 DELETE。因为更新表时,MySQL 不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的 MySQL 有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

索引的优化

(1)何时使用聚集索引或非聚集索引?

动作描述使用聚集索引使用非聚集索引
列经常被分组排序使用使用
返回某范围内的数据使用不使用
一个或极少不同值不使用不使用
小数目的不同值使用不使用
大数目的不同值不使用使用
频繁更新的列不使用使用
外键列使用使用
主键列使用使用
频繁修改索引列不使用使用

(2)索引不会包含有 NULL 值的列
     只要列中包含有 NULL 值都将不会被包含在索引中,复合索引中只要有一列含有 NULL 值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为 NULL。
(3)使用短索引
     对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个 CHAR(255) 的列,如果在前 10 个或 20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和 I/O 操作。
(4)索引列排序
     MySQL 查询只使用一个索引,因此如果 where 子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
(5)like 语句操作
     一般情况下不鼓励使用 like 操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而 like “aaa%” 可以使用索引。
(6)不要在列上进行运算
     例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′。关于这一点可以围观:一个单引号引发的 MYSQL 性能损失。

Show index on tablename;
Explain select * from table;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值