SQLite likely() 函数使用指南

SQLite likely() 是一个特殊的内置查询优化器提示函数(Query Planner Hint)。在 SQL 执行阶段,它单纯原样返回其传入参数的值;但在 SQL 语句的编译与执行计划生成阶段,它会向 SQLite 查询规划器(Query Planner)发送一个极具指导意义的统计权重提示:该布尔表达式成立(为真)的概率极高。

SQLite 内核默认将普通未加提示的表达式估计为真假各 50% 概率,而使用 likely(X) 则向优化器告知表达式 X 为真的概率约为 93.75%(即 15/16)。在复杂多表 JOIN 或带分支计算的查询中,这一提示有助于规划器挑选更合理的循环驱动顺序与过滤策略。

SQLite likely() 语法

这里是 SQLite likely() 函数的调用语法:

likely(expression)

参数

expression
必需的。一个返回真、假或数值的布尔表达式、字段名或计算公式。

返回值

SQLite likely() 函数直接返回参数 expression 本身的计算值。

  • 该函数不会改变表达式的数据类型或布尔真伪。
  • 若 expression 计算结果为 NULL,则返回 NULL。

SQLite likely() 示例

以下示例演示如何在实际查询中应用 likely() 函数。

基本表达式调用

在简单的标量查询中,likely() 完全透传参数值:

SELECT 
    likely(10 > 5) AS is_true,
    likely(10 < 5) AS is_false,
    likely(NULL) AS is_null;

输出:

is_true  is_false  is_null
-------  --------  -------
1        0         NULL   

在复杂多表关联中指导优化器

假设有一张订单表 orders,其中 95% 以上的历史订单都处于已完成状态 status = 'COMPLETED':

CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    customer_id INTEGER,
    status TEXT,
    amount REAL
);

-- 使用 likely 告知优化器该状态具有压倒性的高概率
SELECT 
    customer_id, 
    COUNT(*) AS total_completed
FROM orders
WHERE likely(status = 'COMPLETED')
GROUP BY customer_id;

输出:

customer_id  total_completed
-----------  ---------------
101          15             
102          42             

当 SQLite 解析此查询时,由于明确知晓大部分行均满足该条件,在多条件并存时会更优先评估其他高选择性(低命中率)的谓词,从而减少无谓的评估开销。

结论

  • likely(X) 在逻辑运算上等价于 likelihood(X, 0.9375)。
  • 它是一个纯编译器提示,完全不改变实际查询结果,因此使用起来非常安全。
  • 当数据库因写入频繁尚未执行 ANALYZE 收集最新统计分布,或者数据严重倾斜导致规划器选择错误索引时,使用 likely() 能够有效纠偏。