SQL Server用户使用术语“ sargable”。我想知道是否有一个客观的,与实现无关的永恒定义:“可精”。
例如,WHERE foo LIKE '%bar%'
许多人说sargable不可靠,但是某些RDBMS 可以在此类查询上使用索引。那么“不可燃”是什么意思呢?
其他参考
SQL Server用户使用术语“ sargable”。我想知道是否有一个客观的,与实现无关的永恒定义:“可精”。
例如,WHERE foo LIKE '%bar%'
许多人说sargable不可靠,但是某些RDBMS 可以在此类查询上使用索引。那么“不可燃”是什么意思呢?
其他参考
Answers:
P. Griffiths Selinger等人首先引入了“可燃”一词。在1979年由ACM发表的论文“关系数据库管理系统中的访问路径选择”中。对于非ACM成员,可以在http://cs.stanford.edu/people/chrismre/cs345/rl/selinger.pdf上获得该论文的副本。
该术语在本段中定义:
索引扫描和段1扫描都可以选择使用谓词集(称为搜索参数(或SARGS)),在将其返回给RSI 2调用者之前将它们应用于元组。如果元组满足谓词,则返回它;否则,返回它。否则,扫描将继续进行,直到找到满足SARGS的元组或用尽该段或指定索引值范围为止。通过消除对元组进行RSI调用的开销(可在RSS中有效拒绝),可以降低成本。并非所有谓词都具有可以变成SARGS的形式。阿可优化搜索谓词是形式中的一个(或它可以被放入表格)“列比较运算符值”。SARGS以析取正态形式表示为此类谓词的布尔表达式。
换句话说,可谓词可通过存储引擎(访问方法)通过直接观察表或索引记录来解析。相反,不可持久的谓词需要更高级别的DBMS才能采取行动。例如,WHERE lastname = 'Doe'
存储引擎可以通过简单地查看lastname
每个记录的字段的内容来确定的结果。另一方面,WHERE UPPER(lastname) = 'DOE'
需要由SQL引擎执行功能,这意味着存储引擎将必须将其读取的所有行(前提是它们与可能的其他可引用谓词匹配)返回给SQL引擎进行评估,从而产生额外的CPU成本。
从原始定义中可以看到,只要满足条件“列比较运算符值”,则可扩展谓词不仅可以应用于索引扫描,还可以应用于表(System R术语中的段)扫描。由存储引擎评估。Db2确实是这种情况,它是System R的后代,在许多方面:
可索引的谓词不用于包围搜索,但是如果选择了一个,则从索引进行评估,因为谓词中涉及的列是索引键的一部分。这些谓词也由索引管理器评估。
数据可存储谓词是不能由索引管理器评估但可以由数据管理服务(DMS)评估的谓词。通常,这些谓词需要访问基表中的各个行。如有必要,DMS将检索评估谓词所需的列,
在SQL Server中,可精析谓词只是可以使用索引查找解决的谓词,这一事实可能是由其存储引擎无法在表扫描期间应用此类谓词决定的。
可声明谓词和不可声明谓词有时分别称为“阶段1”和“阶段2”谓词(这也来自Db2术语)。在读取表或索引记录的同时,可以在查询处理的最低级别评估阶段1谓词。符合阶段1条件的行(如果有)将被发送到评估的下一个阶段2。
1 -System R中的Segment是表的元组的物理存储;段扫描在某种程度上等效于其他DBMS中的表扫描。
2 -RSI-RSS 3接口,一个面向元组的查询接口。与该讨论相关的接口函数是NEXT,该函数返回下一行匹配的查询谓词。
3 -RSS,或研究存储系统,系统R的存储子系统。
= UPPER()
是一个函数调用,但是memcmp
它本身也是。编写一个memcmp
假定ASCII并忽略大小写的a相对容易(只看第二个半字节)。这是否可维护?另请参阅@ Ypercube的例子,dba.stackexchange.com/questions/162263/...
x=0
储蓄吗?怎么样-0 = +0
,' ' = ''
还是空间的平等?可以肯定的例子是什么?当您说“不求助于存储引擎外部实现的数据库功能”时,您将包括在DATE()
存储引擎内部的Ypercube示例中。为什么它本身不可以保存?
对我来说,SARGable意味着SQL Server可以使用您的搜索谓词执行索引搜索。
您不能只说DBMS可以“利用”索引,因为使用不可分配的谓词,SQL Server可能最终会扫描非聚集索引。
根据Dmitri Korotkevitch的Pro SQL Server Internals:
搜索参数ABLE谓词是SQL SERVER可以利用索引查找操作(如果存在索引)的谓词。
SARGable谓词是SQL Server可以隔离单个值或索引键值范围进行处理的谓词
可优化搜索谓词包括以下运算符:
=
,>
,>=
,<
,<=
,IN
,BETWEEN
,和LIKE
(在前缀匹配的情况下)非可优化搜索操作符包括:
NOT
,NOT IN
,<>
,和LIKE
(不前缀匹配),以及使用功能或计算对表,和类型转换,其中的数据类型不符合所创建的索引。
范例:
WHERE name like 'SARGable%'
WHERE name like '%non-SARGable%'
演示:
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;
现在我们运行:
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;
结果是:
让我们看一下SARGable查询的属性(索引查找)
查询优化器能够在开始和结束的索引中定义一个限制。它有一个搜索参数供查询。
现在是非SARGable查询:
您可以看到谓词'%non ..%'的开头不允许查询优化器定义索引的开始和结束或范围。现在必须搜索整个表(扫描)。
WHERE name like '%non-SARGable%'
该条件的索引,该条件是否可保留?而且,如果是的话,我们不是在讨论实现的特定缺点吗?IE。,我们不应该说“ SQL Server 2016时不可靠”
WHERE DATE(datetime_column) = '2001-01-01'
例如在较新的SQL Server版本(我认为是2008+)中为“可精”(将执行索引查找),而在较旧的版本中则不是。