sqlite中的位掩码vs IN()效率?

sqlite中的位掩码vs IN()效率?,sql,sqlite,binary,query-optimization,mask,Sql,Sqlite,Binary,Query Optimization,Mask,我有两种方法可以从数据库中选择一组条目: SELECT ... WHERE `level` IN (1,2,4,8) LIMIT ...; 或 总共有4个“级别”,编号为1、2、4、8(因为在其他地方也可以使用相同的掩码)。IN()的大括号或掩码可以包含4个级别中的一个或多个级别的任意集合。该列已编入索引。查询仍然需要更长的时间,我们正在尝试优化它的速度 昨天有人说,决定使用naivein()会导致多达四次比较,我应该使用一个位掩码。今天我听说位掩码将完全阻碍列上索引的优势,并且速度会

我有两种方法可以从数据库中选择一组条目:

  SELECT ... WHERE `level` IN (1,2,4,8) LIMIT ...;  

总共有4个“级别”,编号为1、2、4、8(因为在其他地方也可以使用相同的掩码)。
IN()
的大括号或
掩码可以包含4个级别中的一个或多个级别的任意集合。该列已编入索引。查询仍然需要更长的时间,我们正在尝试优化它的速度

昨天有人说,决定使用naivein()会导致多达四次比较,我应该使用一个位掩码。今天我听说位掩码将完全阻碍列上索引的优势,并且速度会慢得多


你能告诉我哪种方法更快吗?

你的问题很老了,但我还是会回答

位掩码很可能会较慢,因为它必须计算按位的值,而
中的
将使用
level
索引值在括号内的参数中查找它(我认为这应该是一个
O(log(n))
操作)

现在,你可能缺少的是,他们不做同样的事情

第一个查询只需检查
级别
是1、2、4还是8

您的第二个查询,或者实际上类似于:

SELECT ... WHERE (`level` & mask) = mask LIMIT ...;
能够查找包含所需掩码的
级别
,在您的情况下,可能会检查1到15之间的所有值组合。因此,演出大受欢迎


至于@AlanFoster建议的暴力基准,我不同意他的观点

最好在查询前加上以下任一前缀:

  • 解释
    ,或
  • 解释查询计划
并检查SQLite匹配了多少行


更新
解释查询计划选择*自。。。其中第(2,3)级
解释查询计划选择*自。。。式中(2级)=2

如您所见,按位AND运算符需要进行全表扫描。

+1用于建议解释和澄清IN AND和MASKhelpful调查之间的差异!一个老掉牙的回答一个老掉牙的问题引发了新的争论:)。我认为
(level&mask)=mask
应该在
O(klog(n))
中完成,其中
k
是掩码的位长度。问这个问题的另一种方式是,给我所有的级别值,这些值包含掩码的所有位,如果我用列替换位,则是:给我所有的级别,其中列等于掩码列。如果我对它应用哈希优化,我们也可以说它是
O(log(n))
,与
查询中的
性能相同,但结果与您提到的不同。
SELECT ... WHERE (`level` & mask) = mask LIMIT ...;
SEARCH TABLE ... USING INDEX ..._level (level=?) (~20 rows)
SCAN TABLE ... (~500000 rows)