簡體   English   中英

MySQL:在 WHERE IN 子句中使用復合鍵的查詢非常慢

[英]MySQL: very slow query using composite key in WHERE IN clause

我有一個帶有復合主鍵的 MySQL 表:(id1, id2)。 我想獲取 (id1, id2) 在對列表中的所有行,例如 ((1,2), (2,6), (1,6))。 當這個對列表只包含一個元素時,索引似乎被使用,因為查詢非常快。 當對列表包含多個元素時,查詢速度極慢:

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1817279, 0));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1817279 |      0 |
+---------+--------+
1 row in set (0.00 sec)

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1819781, 2));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1819781 |      2 |
+---------+--------+
1 row in set (0.00 sec)

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1817279, 0), (1819781, 2));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1817279 |      0 |
| 1819781 |      2 |
+---------+--------+
2 rows in set (1 min 22.72 sec)

我嘗試使用FORCE INDEX (PRIMARY)沒有成功。 知道為什么 MySQL 無法使用索引嗎?

這是我的 MySQL 版本: mysql Ver 14.14 Distrib 5.6.33, for debian-linux-gnu (x86_64) using EditLine wrapper

“行構造函數”直到 5.7.3 才被優化。 示例WHERE (id1, id2) = (11, 22) 來自更新日志:2013-12-03 5.7.3

里程碑 13 -- 添加或更改的功能:

優化器現在可以將范圍掃描訪問方法應用於這種形式的查詢:

SELECT ... FROM t1 WHERE (col_1, col_2) IN (('a', 'b'), ('c', 'd'));

以前,要使用范圍掃描,必須將查詢編寫為:

SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' );

要使優化器使用范圍掃描,查詢必須滿足以下條件:

  • 只能使用 IN 謂詞,不能使用 NOT IN。

  • 在 IN 謂詞左側的行構造函數中可能只有列引用。

  • IN 謂詞的右側必須有多個行構造函數。

  • IN 謂詞右側的行構造函數必須僅包含運行時常量,即在執行期間綁定到常量的文字或本地列引用。

適用查詢的 EXPLAIN 輸出將從全表或索引掃描更改為范圍掃描。 通過檢查Handler_read_firstHandler_read_keyHandler_read_next狀態變量的值也可以看到更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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