簡體   English   中英

(按位)MySQL中的Supersets和Subsets

[英](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

該指數可以通過兩種方式有效:

  1. 避免早期表掃描(因為要比較的值包含在索引本身中)
    • 限制檢查值的范圍。

上述查詢中的任何條件都不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM