SF.*_*SF. 10 sql sqlite binary mask query-optimization
我有两种方法从数据库中选择一组条目:
SELECT ... WHERE `level` IN (1,2,4,8) LIMIT ...;
Run Code Online (Sandbox Code Playgroud)
要么
SELECT ... WHERE `level` & mask LIMIT ...;
Run Code Online (Sandbox Code Playgroud)
总共有4个'级别',编号为1,2,4,8(因为其他地方也可以使用相同的面具).两者的括号IN()或mask可以包含任何一组的一个或多个的4个级别的.该列已编入索引.查询仍然比舒适更长,我们正在努力优化速度.
昨天一个人说决定使用天真的IN()导致最多四次比较,而我应该使用位掩码代替.今天我听说位掩码将完全阻止列上索引的优势,并且会慢得多.
你能告诉我哪种方法会更快吗?
Ali*_*xel 18
你的问题很老,但我仍然会回答它.
位掩码很可能会更慢,因为它必须计算出按位AND的计算,而IN将使用索引值level在括号内的参数中查找它(我认为应该是单个O(log(n))操作).
现在,你可能会遗漏的是,他们不会做同样的事情.
您的第一个查询将只检查level是1,2,4还是8.
你的第二个查询,或实际上是这样的:
SELECT ... WHERE (`level` & mask) = mask LIMIT ...;
Run Code Online (Sandbox Code Playgroud)
能够查找levels包含您想要的掩码以及可能更多的掩码,在您的情况下,它可以检查1到15之间的所有值组合.因此性能命中.
至于强制基准@AlanFoster建议,我不同意他的观点.
使用以下任一方法为查询添加前缀要好得多:
EXPLAIN, 要么EXPLAIN QUERY PLAN并检查SQLite匹配的行数.
EXPLAIN QUERY PLAN SELECT * FROM ... WHERE level IN (2, 3);SEARCH TABLE ... USING INDEX ..._level (level=?) (~20 rows)
Run Code Online (Sandbox Code Playgroud)
EXPLAIN QUERY PLAN SELECT * FROM ... WHERE (level & 2) = 2;SCAN TABLE ... (~500000 rows)
Run Code Online (Sandbox Code Playgroud)
如您所见,按位AND运算符需要全表扫描.
| 归档时间: |
|
| 查看次数: |
3248 次 |
| 最近记录: |