索引是数据库优化中最常用也是最重要的手段之一,通过索引可以帮助用户解决大多数的 SQL 性能问题。
多数情况下,查询速度很慢时,加上索引便能解决问题。但也并非总是如此,因为优化不是件简单的事情。但是如果你不使用索引,在许多情况下,尝试通过其它途径来提高性能都纯粹是在浪费时间。应该首先使用索引来最大程度的改善性能,然后再看看是否还有其它有用的技术。
索引提供了高效访问数据的方法,能够快速的定位表中的某条记录,加快数据库查询的速度,从而提高数据库的性能。
如果查询时不使用索引,那么查询语句将查询表中的所有字段。这样查询的速度会很慢。使用索引进行查询,查询语句不必读完表中的所有记录,而只查询索引字段。这样可以减少查询的记录数,达到提高查询速度的目的。
下面通过对比使用索引和不使用索引来分析索引对查询速度的影响。
为了便于读者更好的理解,分析之前,我们先查询一下 tb_students_info 数据表中的记录,SQL 语句和运行结果如下:
mysql> SELECT * FROM tb_students_info; +----+------+ | id | name | +----+------+ | 1 | 张三 | | 2 | 李四 | | 3 | 王五 | | 4 | 赵六 | | 5 | 周七 | | 6 | 吴八 | | 7 | 朱九 | | 8 | 苏十 | +----+------+ 8 rows in set (0.02 sec)
使用 EXPLAIN 分析未使用索引时的查询情况,SQL 语句和运行结果如下:
mysql> EXPLAIN SELECT * FROM tb_students_info WHERE name='张三' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: tb_students_info partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 8 filtered: 12.50 Extra: Using where 1 row in set, 1 warning (0.00 sec)
由结果可以看到,rows 列的值是 8,说明查询语句扫描了表中的 8 条记录。
没有索引的表就相当于一组无序的行,如果我们想找到某条记录就必须检查表的每一行,看看它是否与那个期望值相匹配。这是一个全表扫描操作,其效率很低,如果表很大,而且仅有少数几条记录与搜索条件相匹配,那么整个扫描过程的效率将会超级低。
在 tb_students_info 表的 name 字段添加索引,SQL 语句和运行结果如下:
mysql> CREATE INDEX index_name ON tb_students_info(name); Query OK, 8 rows affected (0.14 sec)
使用 EXPLAIN 再次执行上面的查询语句,SQL 语句和运行结果如下:
mysql> EXPLAIN SELECT * FROM tb_students_info WHERE name='张三' \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: tb_students_info partitions: NULL type: ref possible_keys: index_name key: index_name key_len: 63 ref: const rows: 1 filtered: 100.00 Extra: NULL 1 row in set, 1 warning (0.00 sec)
结果显示,rows 列的值为 1,表示这个查询语句只扫描了表中的 1 条记录。创建索引后访问的行由 8 行减少到 1 行,其查询速度自然比扫描 8 条记录快。而且 possible_keys 和 key 的值都是 index_name,这说明查询时使用了 index_name 索引。所以,在查询操作中,使用索引不仅能自动优化查询效率,还会降低服务器的开销。
注意:由于 tb_students_info 表中记录较少,所以在这没有分析运行时间。表中记录多时,运行时间的差异也会体现出索引对查询速度的影响。