SQL索引:无,单列和多列

时间:2012-02-14 22:29:22

标签: sql indexing

索引如何在SQL中工作以及它提供了哪些好处?没有索引的原因是什么?索引单列与索引多列之间的区别是什么?

2 个答案:

答案 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中使用的所有字段也在索引中,则数据库可以检索所需的所有信息,而无需返回基表。这称为覆盖指数。如果所有字段都在单独的索引中,那么它只会使用连接和其中的那些字段,然后返回到基表中选择列中的列。