对于char / varchar / text列,为什么该列的索引会使搜索更快?

时间:2009-09-09 12:56:07

标签: sql mysql data-structures

如果是int,我知道它会更快,只是无法理解字符串类型。

注释: 大多数亚洲语言之间没有空格。和mysql不能将句子分成单词。而且,我的意思是随机搜索,也就是说,单词可以出现在句子的任何位置。

6 个答案:

答案 0 :(得分:6)

一个重点是索引对某些类型的搜索根本没有帮助。例如:

SELECT * FROM [MyTable] WHERE [MyVarcharColumn] LIKE '%' + @SearchText + '%'

没有任何正常索引可以帮助该查询。它永远注定要慢。 LIKE表达式不是sargable

为什么呢?首先需要了解索引的工作原理。它们基本上将被索引的列与主键(记录指针)一起放入新表中。然后,他们在索引列而不是键上对该表进行排序。当您使用索引进行查找时,它可以非常快速地找到您想要的行,因为该索引已经过排序,以便使用二进制搜索等算法进行更有效的搜索。

现在再次查看该查询。通过在搜索文本前面放置一个通配符,您刚刚告诉数据库您不确定列的起始位置。没有多少分类会有所帮助;你仍然需要遍历整个表格,以确保找到与表达式匹配的每条记录。这意味着该列的任何正常索引对于此查询都毫无价值。

如果要在列中的任何位置搜索文本列以查找搜索字符串,则需要使用稍微不同的内容:全文索引。

现在对比看看这个查询:

SELECT * FROM [MyTable] WHERE [MyVarcharColumn] LIKE @SearchText + '%'

对于普通索引,这将完全正常,因为您知道您希望列如何开始。它仍然可以与存储在索引中的排序值匹配,因此我们可以说它是可以搜索的。

答案 1 :(得分:4)

索引已排序,表格未排序。因此,当您在索引上搜索时,即使表中的每一行都有不同的值,也可以找到查找字符串的位置的线索。

此外,索引(通常)比表小(因此),因此要扫描表中的每一列,您必须遍历每一行。索引搜索只是在索引中找到正确的位置,选择它,抓取指向聚簇索引的指针,然后离开你去获取行的其余部分。

答案 2 :(得分:2)

最简单的答案是另外几个问题:

  • 为什么在电话簿中以他/她的最后名称非常快速找到一个人?
  • 为什么在电话簿中快速找到一个人第一个名称而不是

答案 3 :(得分:1)

索引基本上就像书中的索引一样,书中出现的每个单词(取决于书)都放在索引中,并带有出现该单词的页码。索引按字母顺序排序,因此可以快速找到索引中的单词。如果您没有书中的索引,找到特定单词的每个实例的唯一方法是阅读整本书,注意该单词的出现位置。

表格是一样的。如果您搜索具有特定列值的记录,并且您没有索引,则数据库可以执行的唯一操作就是遍历整个表以查找任何匹配项。

答案 4 :(得分:1)

电话簿以姓氏为索引。你能想象一下,如果不是这样,数字会有多缓慢吗?

答案 5 :(得分:0)

索引本质上是一个2列表,索引字段按排序顺序以及PK查找。对于字符串,它具有按排序顺序排列的字符串。然后可以使用二进制搜索而不是表扫描来完成搜索,这对于几乎任何长度的表来说都会更快。