[英](Bitwise) Supersets and Subsets in MySQL
以下查詢在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
該指數可以通過兩種方式有效:
上述查詢中的任何條件都不是sargable ,這是索引不會用於范圍掃描(具有現在的條件)。
但是,第1
點仍然存在,索引可能很有用。
如果您的表包含平均每行100
個字節和1,000,000
記錄,那么表掃描將需要掃描100 Mb
的數據。
如果你有一個索引(帶有4
字節密鑰, 6
字節行指針和一些內部開銷),如果過濾器成功,查詢將只需要掃描10 Mb
數據以及表中的其他數據。
這兩個查詢都需要掃描整個索引。
但是通過重寫AND
查詢,您也可以從索引的范圍中受益。
這個條件:
field & number = number
如果在field
也設置了number
集的最高位,則只能匹配字段。
您應該為查詢提供以下額外條件:
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”,則可以實現進一步的增益。 當然,高效創建此表意味着原始表中的Field索引。
我自己試過這個,並且按位操作不足以阻止Mysql在“field”列上使用索引。 但是,很可能正在對索引進行全面掃描。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.