(Bitwise)超集和集中MySQL
-
12-09-2019 - |
题
以下是查询有效MySQL:
SELECT * FROM table WHERE field & number = number;
# to find values with superset of number's bits
SELECT * FROM table WHERE field | number = number;
# to find values with subset of number's bits
...如果一个指数领域已经建立?
如果没有,是否有办法让它运行速度更快?
解决方案
更新:
看到这个条目的,在我的博客的性能的详细信息:
SELECT * FROM table WHERE field & number = number
SELECT * FROM table WHERE field | number = number
这个指数可以有效地在两个方面:
- 为了避免早期表扫描(由于价值的比较载在索引本身)
- 限制的数值范围内审查。
既没有条件,在查询上 可优化搜索, 这是索引将不会被用于范围扫描(带条件,因为他们现在的).
然而,点 1
仍然拥有,而指标可能是有用的。
如果你的表包含的说, 100
字节每一行中的平均水平, 1,000,000
记录,然后该表格的扫描将需要扫描 100 Mb
数据。
如果你有一个指数(一个 4
字节的关键, 6
-byte行指针和一些内部开销),查询将需要只扫描 10 Mb
数据加上额外的数据表如果该过滤器成功。
- 该表格的扫描是更有效的如果你的状况不是选择性的(你已经高probablility到匹配的条件)。
- 索引扫描效率更高,如果你的条件是选择性的(你已经低probablility到匹配的条件)。
这些查询将需要扫描整个索引。
但是,通过改写的 AND
查询可以得益于范围上的索引。
这个条件:
field & number = number
只能相匹配的领域,如果最高位 number
设置 field
太。
你应该只是提供这种额外的条件来查询:
SELECT *
FROM table
WHERE field & number = number
AND field >= 0xFFFFFFFF & ~((2 << FLOOR(LOG(2, 0xFFFFFFFF & ~number))) - 1)
这将使用范围粗筛选和条件的细筛选。
越位 number
是取消在结束时,将更好。
其他提示
我怀疑优化器将可以认识到这一个...
也许你可以调用EXPLAIN这些查询并确认我的悲观猜测。 (当然记住这么多的查询计划决定是基于给定数据库的特定实例,即数据的不同量和/矿石仅仅数据具有不同统计分布可以产生不同的计划)。
假设表具有行的显著量,并且“bitwised”标准仍然足够选择性的)避免按位操作时在每个单列,通过用IN构造重写查询的可能的优化得以实现(或者用JOIN)
类似的东西(概念,即未测试)
CREATE TEMPORARY TABLE tblFieldValues
(Field INT);
INSERT INTO tblFieldValues
SELECT DISTINCT Field
FROM table;
-- SELECT * FROM table WHERE field | number = number;
-- now becomes
SELECT *
FROM table t
WHERE field IN
(SELECT Field
FROM tblFieldValues
WHERE field | number = number);
(所有这些具有相当大的数目在表的行中,因为否则直接“WHERE字段|数=数”的方法是足够有效的)这样需要的方法的全部好处与不同的使用情况进行评价,但我怀疑这可能是显著更快。进一步走高可能,如果“tblFieldValues”不需要每次都重新来实现。高效地创建该表当然的意味着原始表上的字段的索引。
我这个尝试我自己,和位运算不足以防止Mysql的从“田”列使用索引。它是可能的,虽然,该指数的完全扫描正在发生。