但行好事,莫问前程

挖了太多坑,一点点填回来

MySQL 索引知识点

mysql

索引是一种特殊的文件,InnoDB 数据表上的索引是表空间的一个组成部分。它们包含着对数据表里所有记录的引用指针。

从理论上讲,完全可以为数据表里的每一个字段分别创建一个索引,但是 MySQL 把同一个数据表里的索引总数限制为 16 个。MySQL 还允许为多个字段的组合创建索引,这种索引对涉及多个字段的查询/排序操作——例如 WHERE coutry='China' AND city='Shanghai' 特别有帮助。

InnoDB 表的索引

和 MyISAM 数据表相比,索引对 InnoDB 数据表的重要性大得多。在 InnoDB 数据表上,索引不仅会在搜索数据记录时发挥作用,还是数据行级锁定机制的基础。“数据行级锁定”的意思是在事务操作的执行过程中锁定正在被处理的个别记录,不让其他的用户访问。这种锁定将影响到(但是不限于) SELECT ... LOCK IN SHARE MODESELECT ... FOR UPDATE 命令以及 INSERTUPDATEDELETE 命令。

出于对效率的考虑,InnoDB 数据表的数据行级锁定机制实际发生在它们的索引上,而不是数据表自身上。显然,数据行级锁定机制只有在有关的数据表有一个合适的索引可供锁定的时候才能发挥作用。

限制

如果 WHERE 子句的查询条件里有不等号(WHERE column!=…), MySQL 将无法使用索引。

类似的,如果在 WHERE 子句的查询条件里使用了函数(WHERE DAY(column )=…), MySQL 也不能使用索引。

JOIN 操作中,MySQL 只有在主键和外键的数据类型相同时才能使用索引。

如果 WHERE 子句的查询条件里使用了 LIKEREGEXP ,MySQL 只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是 LIKE 'abc%' ,MySQL 将使用索引;如果查询条件是 LIKE '%abc' ,MySQL 将不使用索引。

ORDER BY 操作中,MySQL 只有在排序条件不是一个查询条件表达式的情况下才能使用索引。

如果某个数据列包含许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列包含的都是诸如“0/1”或者“Y/N”等值,就没有必要为它建立索引。

索引的长度限制

在为 CHARVARCHAR 类型的数据列定义索引时,可以把索引的长度限制为一个给定的字符个数,这个数字必须小于这个字段所允许的最大字符个数。这么做的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置为 10-15 个字符已经足以把搜索范围缩小到和很少的几条数据记录了。

在为 BLOBTEXT 类型的数据列创建索引时,必须对索引的长度作出限制;MySQL 所允许的最大索引长度是 255 个字符。

全文索引

文本字段上普通索引只能加快对出现在字段内容最前面的字符串进行的检索操作。如果字段里存放的是由几个、甚至是许多个单词构成的大段文字,普通索引就没什么作用了。这种索引往往以 LIKE '%word%' 的形式出现,这对 MySQL 来说很复杂,如果需要处理的数据量很大,响应时间就会很长。

这类场合正是全文索引可以大显身手的地方。在生成这种类型的索引时,MySQL 将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数据记录。全问索引既可以随数据表一起创建,也可以等日后有必要时再使用下面这条命令添加:

1
ALTER TABLE tablename ADD FULLTEXT(column1, column2);

有了全文索引,就可以用 SELECT 查询命令去检索那些包含着一个或者多个给定单词的数据记录了。下面是这类查询命令的基本用法:

1
2
SELECT * FROM tablename
WHERE MATCH(column1, column2) AGAINST('word1', 'word2', 'word3');

上面这条命令将把 column1 和 column2 字段里有 word1 、word2 、word3 的数据记录全部查找出来。

InnoDB数据表不支持全文索引。

当然,使用 Sphinx 这个全文搜索引擎将更加能有效的查找数据。

Have a nice day!