为什么'IS NULL'比blob列上的'length()= 0'慢100倍?

Sim*_*rta 5 sql sqlite

我有一个~90 MB的数据库,主要包括消息附件,包括BLOB列content,存储二进制附件数据.

我认为在BLOB上创建索引是不明智的,因此除了autoindex之外没有其他索引.

为了获得空的附件,我比较了以下查询:

SELECT message_id FROM attachments WHERE content IS NULL;
Run Code Online (Sandbox Code Playgroud)

SELECT message_id FROM attachments WHERE length(content) = 0;
Run Code Online (Sandbox Code Playgroud)

这导致我的用例中的行相同.

为什么第一个需要250ms而第二个只需1-2ms(两者都在SSD上)?这背后的原因是什么?有隐藏的长度索引还是什么?有任何见解赞赏.

附加信息

  1. EXPLAIN QUERY PLAN这两种情况下是

    0 | 0 | 0 | SCAN TABLE附件

  2. 否定IS NOT NULLlength() != 0导致相同的性能差异250ms与2ms.

  3. 在组合查询中,只包含{NULL}列WHERE content IS NULL AND length(content) = 0;需要250 WHERE length(content) = 0 AND content IS NULL;毫秒,需要2毫秒.

dav*_*igh 4

这些只是不同的查询:LENGTH是一个返回的标量函数(请参见此处

(i)NULL如果输入是NULL
(ii)0如果输入是零长度的字符串(或者如果它可转换为字符串)。

length(content)=0因此,当 content 为空字符串时,条件为 true;当 content 为空字符串时,条件为 false NULL(因为与NULLalways 比较为 false)。

基于此,我猜测您的表包含多个NULL字段,但只有少数字段实际包含值。您的第二个附加信息也支持这一点,您说这IS NOT NULL显示了可比较的性能。