Mysql
為什麼 MySQL 8 在使用具有降序 PRIMARY KEY、2 個索引和現有行的有效連接條件的表時不返回任何行
使用 2 個表(A 和 B),可通過它們的 PK 連接,其中 A 的 PRIMARY KEY 排序為 DESC(PK 按 MySQL 8 允許的降序排列),並且 A 在 ASC 排序中具有 2 個索引。
當我執行類似的查詢時
SELECT * FROM `A` a LEFT JOIN `B` b ON a.id <=> b.id WHERE a.idx1 = 'X' AND a.idx2 = 'Y';
它不會返回任何內容……但是,如果我添加一個精確的條件,例如:
SELECT * FROM `A` a LEFT JOIN `B` b ON a.id <=> b.id WHERE a.idx1 = 'X' AND a.idx2 = 'Y' AND a.id = 1337;
它將找到具有指定值作為 PRIMARY KEY 的行。
一個解釋表明,當 MySQL 沒有找到任何東西時,它會使用 ‘index_merge_intersection’ 優化。如果我們禁用 ‘index_merge’ 優化,第一個查詢將按預期返回所有結果。
為什麼?
它實際上是一個 MySQL 8.0 錯誤(針對 MySQL 8.0.27-debug / 8.0.28 報告),但在 (8.0.23) 之前也存在,並且似乎也存在於 fork (MariaDB/Percona/AWS Aurora/…) 上。
您可以在此處檢查該錯誤是否最終得到修復:https ://bugs.mysql.com/bug.php?id=106207
在此之前,您可以使用以下解決方案之一來緩解問題:
不要在你的 PRIMARY KEYS 上使用 DESC 排序,只有 ASC
(這也可以避免由於 MySQL 無法理解 FK 可以使用 DESC PK 而出現的 FOREIGN_KEY INDEX 的重複)
或者
從 optimizer_switch 設置中禁用 index_merge 優化
通過使用以下查詢:
SET optimizer_switch='index_merge=off,index_merge_intersection=off';
(或通過更改 optimizer_switch 的預設/全域值)因此 MySQL 將無法陷入此錯誤。
“index_merge_intersection”幾乎總是表明需要更有效的“複合”索引。添加此索引:
INDEX(idx1, idx2)
(和 Drop
INDEX(idx1)
)這應該會加快查詢速度;我不知道它是否可以解決 DarkCenobyte 提到的錯誤。