Navicat 博客

一些最常见的 SQL 查询错误 - 第 2 部分 2022 年 4 月 26 日,由 Robert Gravelle 撰写

第 2 部分:非 SARGable 查询条件

像大多数编程人员一样,数据库开发人员或多或少倾向于编写直接翻译给定请求的代码。大多数编程语言(包括 SQL)被设计为更易于人们阅读,这也导致了一个问题。为什么会有问题?所有编程语言都能比其他语言更快地执行某些操作。在关系数据库中,查询优化器用于分析 SQL 查询并确定称为查询计划的有效执行机制。优化器能为每个查询生成一个或多个查询计划,每个查询计划代表运行查询的一种可能方式。然后选择并使用最有效的查询计划来运行查询。事实证明,模仿请求语言的 SQL 很少是最有效的方法。

在常见的 SQL 查询错误系列的这一部分中,我们将探讨一个编写不佳的 SQL 语句的示例,并以提高效率的方式重写它。

将索引列传递给函数

在数据库开发人员的代码中反复出现的一个错误是将索引列传递给函数。为了说明,我们会对这个表运行一个查询,该表在 varchar customerName 列上有一个索引:

customerName_index (95K)

当要求检索名称以字母“R”开头的所有客户时,可能倾向于使用 LEFT() 函数返回 customerName 列的第一个字符:

left_query (49K)

不幸的是,将索引的 customerName 列传递给函数,查询引擎必须评估表中每一行的结果!

SARGable 与非 SARGable 查询

在关系数据库中,有一个术语源自 Search ARGument ABLE 的缩写,又名 SARGable。如果 DBMS 引擎可以利用索引来加速查询的运行,则查询中的条件(或谓词)被称为 SARGable。另一方面,未能成为 SARGable 的查询称为非 SARGable 查询。其效果类似于在没有索引的书中搜索特定术语,每次都从第一页开始,而不是跳到索引中标识特定页的列表。显然,这对查询时间有负面影响,因此查询优化的其中一个步骤是将此类条件转换为 SARGable。

若要将上述条件变为 SARGable 条件,我们需要避免在索引列上使用函数。为此,我们必须使用 Like 运算符,这个逻辑等效(和 SARGable)的查询来表达请求:

like_query (54K)

请注意,运行时间大大缩短。

总结

在关于常見的 SQL 查询错误的第二部分中,我们了解了非 SARGable 查询条件如何强制数据库引擎评估表的每一行,导致查询性能降低。解决方法是使用逻辑等效(和 SARGable)的条件来表达请求,而不依赖函数调用。

如果你想试用 Navicat 16 for MySQL,你可以在这里下载 14 天试用版。

Navicat 文章
频道条目
分享
文章归档