[英]SQL Indexing: None, Single Column, and Multiple Columns
索引在SQL中是如何工作的,它提供了什么好处? 为什么没有索引呢? 索引单个列与索引多个列之间有什么区别?
索引在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),则您需要在类型列上设置条件,以便查询能够利用索引。 示例索引不能用于条件仅取决于值的查询中。 此外,如果混合使用相等性和范围条件,请确保在索引中首先列出相等性列,否则只能部分使用索引。
为什么没有索引呢?
如果索引的选择性很低,那么通过表扫描可能不会获得太多收益。 例如,假设您在名为“性别”的字段上有一个索引。 然后,该索引的选择性将很低,因为对该索引的查找将返回原始表的一半行。 您可以在此处阅读有关选择性的非常简单的说明及其背后的原因: http : //mattfleming.com/node/192
而且,维持索引具有成本。 对于每个数据操作,索引可能需要重组。 因此,可能希望将索引数量保持在对该表的查询中能很好执行所需的最小值。
索引单个列与索引多个列之间有什么区别?
同样,它取决于您发出的查询的类型。 索引单个列的性别可能不是一个好主意,因为选择性低。 当选择性高时,这样的指标就更有意义了。 例如,主键上的索引是一个很好的索引,因为选择性很高(实际上,它具有尽可能高的选择性。索引中的每个键都完全对应于记录),并且列上的索引具有唯一或高度不同的值(例如slug,密码哈希和其他值)也是不错的单列索引。
还有覆盖索引的概念。 基本上,索引中的每个叶子都包含一个指向存储行的表的指针(除非索引是聚集索引。在这种情况下,叶子是记录)。 因此,对于每个索引命中,查询引擎必须获取对应的表行,从而增加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
如您在-column 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行)比进行全表扫描要好得多。 如您所见,通过使用覆盖索引,即使索引的选择性非常小,我们也可以加快对表的部分选择的查询。
如何在SQL中建立索引
这是一个非常开放的问题,但是基本上数据库存储的结构可以更快地查找信息。 该结构取决于实现,但通常是树的类型。
它提供什么好处?
可SARGable的查询可以大大加快。*
为什么没有索引呢?
某些数据修改查询可能需要更长的时间,并且索引会产生存储成本,但通常来说,这两个考虑都可以忽略不计。
索引单个列与索引多个列之间有什么区别?
差别不大,但有时人们会创建覆盖索引**,该索引包含多个列以提高特定查询的性能。
* SARGable来自Search ArGument ABLE。 基本上,如果您将WHERE FOO > 5
为WHERE FOO > 5
,则可以更快。 另一方面, WHERE h(FOO) > 5
可能不会从索引中受益。
**如果语句的SELECT JOIN和WHERE中使用的所有字段也在索引中,则数据库可以检索其所需的所有信息,而无需返回基表。 这称为覆盖指数。 如果所有字段都在单独的索引中,则它将仅使用那些字段进行连接以及在何处使用,然后返回到基表中用于选择的列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.