索引如何在SQL中工作以及它提供了哪些好处?没有索引的原因是什么?索引单列与索引多列之间的区别是什么?
答案 0 :(得分:5)
索引如何在SQL中工作以及它提供了哪些好处?
当您对列进行索引时,您表达了在条件表达式中查询索引列的意图,例如相等或范围查询。有了这些信息,存储引擎可以构建一个结构,使这些查询更快,通常将它们安排在树结构中。 B树是最常见的,但存在许多不同的结构,例如哈希索引,空间数据的R树索引等。每个结构专门用于某种类型的查找。例如,对于相等条件,哈希索引非常快,例如:
SELECT * FROM example_table WHERE type = "example";
SELECT * FROM example_table WHERE id = X;
对于平等查询,B树也相当快,但它们的主要优势在于它们支持范围查询:
SELECT * FROM example_table WHERE id > 5 AND id < 10
SELECT * FROM example_table WHERE type = "example" and value > 25
然而,当您构建B树索引以了解树以“从左到右”的方式排序时,这非常重要。即,如果你在{type,value}上构建一个B树索引(让我们称之为A),那么你需要在type-column上有一个条件,以便查询能够利用索引。示例索引不能在条件仅依赖于值的查询中使用。 此外,如果混合使用相等和范围条件,请确保在索引中列出 first 的相等列,否则只能部分使用索引。
没有索引的原因是什么?
如果索引的选择性很低,那么您可能无法在表扫描中获得太多收益。比如说你有一个名为性别的字段的索引。然后该索引的选择性将很低,因为对该索引的查找将返回原始表的一半行。你可以在这里阅读关于选择性的非常简单的解释,以及它背后的推理:http://mattfleming.com/node/192
此外,维护索引需要付出代价。对于每个数据操作,索引可能需要重组。因此,可能需要将索引量保持在对该表的查询执行良好所需的最小值。
索引单个列与索引多个列有什么区别?
再一次,这取决于您发出的查询类型。索引单列性别可能不是一个好主意,因为选择性很低。当选择性高时,这样的指数更有意义。例如,主键上的索引是一个非常好的索引,因为选择性很高(实际上,它高达它。索引中的每个键对应于完全记录),以及具有唯一或高度的列上的索引不同的值(例如slugs,密码哈希和什么不是)也是很好的单列索引。
还有涵盖指数的概念。基本上,索引中的每个叶子都包含一个指向存储行的表的指针(除非索引是聚簇索引。在这种情况下,叶子是记录)。因此,对于每个索引命中,查询引擎必须获取相应的表行,从而增加I / O操作的数量。由于I / O非常慢,因此您希望将其保持在最低限度。现在,假设您经常需要查询某些内容,并获取一些额外的列,然后您可以创建覆盖索引,交换存储空间以进行查询性能。示例:让我们找到过去6个月加入的所有用户的姓名和电子邮件(假设MySQL):
索引在{joined_at}:
SELECT first_name, last_name, email
FROM users
WHERE joined_at > NOW() - INTERVAL 6 MONTH;
查询说明:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users ALL test NULL NULL NULL 873 Using where
正如您在type
- 列中所看到的,查询引擎采用全表扫描,因为索引选择性太低而不值得在此查询中使用(将返回太多结果,并且因此进入表格,在I / O中花费太多)
索引在{joined_at,first_name,last_name,email}:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users range test,test2 test2 8 NULL 514 Using where;
Using index
现在,由于索引中提供了完成查询所需的所有信息,因此查询引擎会评估使用索引(包含514行)而不是执行全表扫描要好得多。 正如您所看到的,通过使用覆盖索引,我们可以加快查询表的部分选择,即使索引的选择性非常小。
答案 1 :(得分:2)
索引如何在SQL中工作
这是一个非常开放的问题,但基本上数据库存储的结构可以更快地查找信息。该结构取决于实现,但通常是一种树。
它提供了哪些好处?
SARGable的查询速度要快得多。*
没有索引的原因是什么?
某些数据修改查询可能需要更长时间并且索引存在成本,但一般而言,这些考虑因素都可以忽略不计。
索引单个列与索引多个列之间有什么区别?
没有太大区别,但有时人们创建覆盖索引**,索引多个列以提高特定查询的性能。
* SARGable来自搜索ARGument ABLE。基本上如果你做WHERE FOO > 5
,如果FOO被索引,它会更快。另一方面,WHERE h(FOO) > 5
可能不会从索引中受益。
**如果语句的SELECT JOIN和WHERE中使用的所有字段也在索引中,则数据库可以检索所需的所有信息,而无需返回基表。这称为覆盖指数。如果所有字段都在单独的索引中,那么它只会使用连接和其中的那些字段,然后返回到基表中选择列中的列。