“SARGable”这个词的真正含义是什么?

Eva*_*oll 37 terminology

SQL Server 用户使用术语“sargable”。我想知道“sargable”是否有一个客观的、与实现无关的永恒定义。

例如,WHERE foo LIKE '%bar%'很多人说它不可 sargable 的,但一些 RDBMS能够在此类查询上使用索引。那么“不可以”是什么意思呢?

其他参考

mus*_*cio 47

“sargable”一词最早由 P. Griffiths Selinger 等人提出。在他们 1979 年由 ACM 发表的论文“关系数据库管理系统中的访问路径选择”中。对于非 ACM 成员,该论文的副本位于http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf

该术语在本段中定义:

索引和段1扫描都可以选择采用一组谓词,称为搜索参数(或 SARGS),在元组返回到 RSI 2调用方之前将其应用于元组。如果元组满足谓词,则返回;否则,扫描将继续,直到找到满足 SARGS 的元组或用尽该段或指定的索引值范围。这通过消除对可以在 RSS 中被有效拒绝的元组进行 RSI 调用的开销来降低成本。并非所有谓词都具有可以成为 SARGS 的形式。阿可优化搜索谓词是形式中的一个(或它可以被放入表格)“列比较运算符值”。SARGS 以析取范式表示为此类谓词的布尔表达式。

换句话说,sargable 谓词可以由存储引擎(访问方法)通过直接观察表或索引记录来解析。相反,不可 sargable 谓词需要更高级别的 DBMS 才能采取行动。例如,WHERE lastname = 'Doe'存储引擎可以通过简单地查看lastname每条记录的字段内容来决定结果。另一方面,WHERE UPPER(lastname) = 'DOE'需要 SQL 引擎执行一个函数,这意味着存储引擎必须将它读取的所有行(前提是它们与可能的其他可判断谓词匹配)返回给 SQL 引擎进行评估,从而产生额外的 CPU 成本.

从最初的定义可以看出,sargable predicates 不仅可以应用于索引扫描,还可以应用于表(System R 术语中的段)扫描,只要满足“列比较-运算符值”条件,因此它们可以由存储引擎评估。Db2 确实是这种情况,它是系统 R在许多方面的后代:

索引 sargable 谓词不用于括起搜索,但如果选择了索引,则从索引评估,因为谓词中涉及的列是索引键的一部分。这些谓词也由索引管理器评估。

数据 sargable 谓词是不能由索引管理器评估但可以由数据管理服务 (DMS) 评估的谓词。通常,这些谓词需要访问基表中的各个行。如有必要,DMS 将检索评估谓词所需的列,

事实上,在 SQL Server 中,sargable 谓词只是那些可以使用索引查找解析的谓词,这可能是由其存储引擎无法在表扫描期间应用此类谓词决定的。

Sargable 和非 sargable 谓词有时分别被描述为“阶段 1”和“阶段 2”谓词(这也来自Db2 术语)。在读取表或索引记录时,可以在查询处理的最低级别评估阶段 1 谓词。与第 1 阶段条件匹配的行(如果有)被发送到评估的下一个级别,即第 2 阶段。


1 -- System R 中的 Segment 是表元组的物理存储;段扫描在某种程度上相当于其他 DBMS 中的表扫描。

2 -- RSI -- RSS 3 Interface,一个面向元组的查询接口。与本次讨论相关的接口函数是 NEXT,它返回匹配查询谓词的下一行。

3 -- RSS,或研究存储系统,系统 R 的存储子系统。

  • @EvanCarroll 这意味着直接查看表或索引记录,而无需求助于在存储引擎之外(例如在查询处理器/执行引擎/表达式服务中)实现的数据库功能。在 ypercube 的示例中,查询由规划器/优化器预处理,以便非 SARGable 搜索以 SARGable 术语表示。 (5认同)
  • @EvanCarroll 花一些时间阅读引用的论文,然后再看一遍这个答案。如果您仍然有与此处相关的问题,您可以问他们。请注意,`DATE()` 不是真正的(SQL Server)函数,而是(我推测)Cube 先生的类型转换简写。如果您愿意,我们也可以[在聊天中](https://chat.stackexchange.com/rooms/179/the-heap--consultancy-) 讨论这个问题。 (2认同)

Bre*_*zar 22

对我来说,SARGable 意味着 SQL Server 可以使用您的搜索谓词执行索引查找。

您不能只说 DBMS 可以“利用”索引,因为对于不可 sargable 谓词,SQL Server 最终可能会扫描非聚集索引。


Vic*_*ork 12

根据Dmitri Korotkevitch 的Pro SQL Server Internals的说法

如果存在索引,则搜索参数 ABLE 谓词是 SQL SERVER 可以利用索引查找操作的谓词。

SARGable 谓词是 SQL Server 可以隔离要处理的单个值或索引键值范围的谓词

SARGable 谓词包括以下运算符:=, >, >=, <, <=, IN, BETWEEN, and LIKE(在前缀匹配的情况下)

非可优化搜索操作符包括:NOTNOT IN<>,和LIKE不前缀匹配),以及使用功能或计算对表,和类型转换,其中的数据类型不符合所创建的索引。

示例

WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'
Run Code Online (Sandbox Code Playgroud)

演示

DROP TABLE dbo.Testing;
GO

CREATE TABLE Testing (
    WeirdDatatype   int NOT NULL,
    SomethingElse   char(200)
);

CREATE NONCLUSTERED INDEX IDX_ALWAYS_SARGable
    ON dbo.Testing( SomethingElse);

CREATE NONCLUSTERED INDEX IDX_NOT_ALWAYS_SARGable
    ON dbo.Testing(SomethingElse);

INSERT INTO dbo.Testing
        ( WeirdDatatype, SomethingElse )
SELECT TOP 1000 m.message_id, CONVERT(char(200), m.text)
FROM sys.messages AS m;
Run Code Online (Sandbox Code Playgroud)

现在我们运行:

SELECT *
FROM dbo.Testing AS t
WHERE  t.WeirdDatatype = 1001;
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE 'Line%'
SELECT *
FROM dbo.Testing AS t
WHERE t.SomethingElse LIKE '%Line%'
     AND t.WeirdDatatype = 1001;
Run Code Online (Sandbox Code Playgroud)

结果是:

[1]

我们来看看SARGable查询的属性(Index Seek)

在此处输入图片说明

查询优化器能够在开始和结束的索引中定义限制。它有一个用于查询的搜索参数。

现在是非 SARGable 查询:

在此处输入图片说明

您可以看到谓词 '%non..%' 的开头不允许查询优化器在索引中定义开始和结束或范围。它现在必须搜索整个表(扫描)。

  • 当然,它是特定于实现的。`WHERE DATE(datetime_column) = '2001-01-01'` 例如在较新的 SQL Server 版本(我认为是 2008+)中是“sargable”(将进行索引查找),但不是在旧版本中。 (2认同)