提起优化 SQL,你可能会把它理解为优化索引。简单来说这也不算错,索引在 SQL 优化中占了很大的比重。索引用得好,可以将 SQL 查询的效率提升 10 倍甚至更多。但索引是万能的吗?既然索引可以提升效率,只要创建索引不就好了吗?实际上,在有些情况下,创建索引反而会降低效率。
今天我们就来讲一下索引,索引涉及到的内容比较多,今天先来对索引有个整体的认知。
- 什么情况下创建索引,什么时候不需要索引?
- 索引的种类有哪些?
索引的原理很好理解,在今天的内容里,我依然会通过 SQL 查询实验验证今天的内容,帮你进一步加深理解。
索引是万能的吗?
首先我们需要了解什么是索引(Index)。数据库中的索引,就好比一本书的目录,它可以帮我们快速进行特定值的定位与查找,从而加快数据查询的效率。
索引就是帮助数据库管理系统高效获取数据的数据结构。
如果我们不使用索引,就必须从第 1 条记录开始扫描,直到把所有的数据表都扫描完,才能找到想要的数据。既然如此,如果我们想要快速查找数据,就只需要创建更多的索引就好了呢?
其实索引不是万能的,在有些情况下使用索引反而会让效率变低。
索引的价值是帮我们从海量数据中找到想要的数据,如果数据量少,那么是否使用索引对结果的影响并不大。
在数据表中的数据行数比较少的情况下,比如不到 1000 行,是不需要创建索引的。另外,当数据重复度大,比如高于 10% 的时候,也不需要对这个字段使用索引。我之前讲到过,如果是性别这个字段,就不需要对它创建索引。这是为什么呢?如果你想要在 100 万行数据中查找其中的 50 万行(比如性别为男的数据),一旦创建了索引,你需要先访问 50 万次索引,然后再访问 50 万次数据表,这样加起来的开销比不使用索引可能还要大。
当然,空口无凭,我们来做两个实验,更直观地了解索引。
实验 1:数据行数少的情况下,索引效率如何
我在百度网盘上提供了数据表,heros_without_index.sql 和 heros_with_index.sql,提取码为 wxho。
在第一个数据表中,除了自增的 id 以外没有建立额外的索引。第二张数据表中,我对 name 字段建立了唯一索引。
heros 数据表一共有 69 个英雄,数据量很少。当我们对 name 进行条件查询的时候,我们观察一下创建索引前后的效率。
SELECT id, name, hp_max, mp_max FROM heros_without_index WHERE name = '刘禅'
运行结果(1 条数据,运行时间 0.072s):
我对 name 字段建立索引后,再进行查询:
SELECT id, name, hp_max, mp_max FROM heros_with_index WHERE name = '刘禅'
留言