为什么喜欢运算符这么快



你们都知道SQL中的like运算符。例如:

select * 
from customer 
where email like '%goog%'

所以我的问题是数据库怎么能这么快返回结果?当我应该编写这样的函数时,我会遍历所有客户和每封电子邮件。但这非常缓慢。我听说过索引。当数据库不知道第一个或最后一个字母是哪个时,数据库如何使用索引?还是他们的另一种方式?

我不想编程这样的东西。我只想知道它是如何工作的。

我不知道

您正在使用什么引擎以及其实际引擎盖下是什么,但这里有一些有关此问题的有用信息:

  1. 通常,SQL 引擎在列内使用自由文本搜索,以便能够更快地提取此类查询。这是通过创建一个倒排索引来完成的,该索引从每个单词映射到包含它们的"文档"(行,列)。一个广泛使用的库是Apache Lucene。不幸的是,大多数 IR(信息检索)库在查询开始时不支持通配符(但它们在其他任何地方都支持通配符),因此无法在此类索引中搜索您的特定示例。
  2. 可以使用后缀树创建索引以支持索引开头的通配符。后缀树非常适合搜索子字符串,就像您的示例一样。但是,它们对于搜索中间带有通配符的字符串并不是很优化。

据我了解,这种查询方式不是很有效 - 如果有影响单词开头的通配符,则需要整个扫描。但是,如果对列编制索引,则DBMS只需将整个索引放入内存中并扫描它,而不是扫描表的全部内容 - 通常这将是一个相对较快的任务。

由于我们不知道您正在使用哪种RDBMS,让我们看一下在这种情况下数据库可以从索引中受益的一种方式 - 让我们通过book/index的比喻来探索它:

想象每行数据占据一本书的一页,每一页上都有一个电子邮件地址。在本书的末尾,有一个电子邮件地址索引 - 对于每个电子邮件地址,它告诉你哪些页面包含该电子邮件地址。此索引的每一页仅包含电子邮件地址和页码。假设每页有 50 个电子邮件地址。

如果您想查找电子邮件地址包含字母的所有页面 goog ,尽管不知道电子邮件地址的第一个或最后一个字母是什么,您认为 a) 浏览整本书中的每一页,或 b) 扫描书后面的电子邮件索引,记下哪些页面有用(然后转到那些页面,如果您需要更多信息)?