2011-12-25 63 views
0

我有以下InnoDB表,其作用MySQL的49年5月1日 下有點奇怪(MySQL的版本14.14 DISTRIB 49年5月1日,使用readline的6.1 Debian的Linux-GNU(x86_64的))Mysql 5.1.49 InnoDB /查詢優化器動作怪異?

mysql> desc forum_favorite; 
+-----------+----------------------+------+-----+---------+-------+ 
| Field  | Type     | Null | Key | Default | Extra | 
+-----------+----------------------+------+-----+---------+-------+ 
| id_member | smallint(5) unsigned | YES | MUL | NULL |  | 
| id_topic | int(10) unsigned  | YES | MUL | NULL |  | 
+-----------+----------------------+------+-----+---------+-------+ 
2 rows in set (0.00 sec) 

mysql> show index from forum_favorite; 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| forum_favorite |   1 | id_member |   1 | id_member | A   |  2134 |  NULL | NULL | YES | BTREE  |   | 
| forum_favorite |   1 | id_topic |   1 | id_topic | A   |  3201 |  NULL | NULL | YES | BTREE  |   | 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
2 rows in set (0.00 sec) 

現在,檢查查詢:

mysql> SELECT id_topic FROM forum_favorite WHERE (id_member = 2); 
+----------+ 
| id_topic | 
+----------+ 
|  1249 | 
| 20209 | 
| 91878 | 
| 99026 | 
| 90257 | 
|  1179 | 
|  1179 | 
+----------+ 
7 rows in set (0.00 sec) 

當我搜索與給定成員一個特定的主題,它提供了一個空的結果集。爲什麼?

mysql> select * from forum_favorite where id_member = 2 and id_topic = 1249; 
Empty set (0.00 sec) 

但是,當我尋找另一個話題,它回來確定...

可以毫不id_member where子句中找到:

mysql> select * from forum_favorite where id_topic = 1249; 
+-----------+----------+ 
| id_member | id_topic | 
+-----------+----------+ 
|   2 |  1249 | 
+-----------+----------+ 
1 rows in set (0.00 sec) 

指標:

mysql> show index from forum_favorite; 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| forum_favorite |   1 | id_member |   1 | id_member | A   |  2134 |  NULL | NULL | YES | BTREE  |   | 
| forum_favorite |   1 | id_topic |   1 | id_topic | A   |  3201 |  NULL | NULL | YES | BTREE  |   | 
+----------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
2 rows in set (0.00 sec) 

解釋犯罪查詢:

mysql> explain select * from forum_favorite where id_member = 2 and id_topic = 1249; 
+----+-------------+----------------+-------------+--------------------+--------------------+---------+------+------+---------------------------------------------------------------+ 
| id | select_type | table   | type  | possible_keys  | key    | key_len | ref | rows | Extra               | 
+----+-------------+----------------+-------------+--------------------+--------------------+---------+------+------+---------------------------------------------------------------+ 
| 1 | SIMPLE  | forum_favorite | index_merge | id_member,id_topic | id_member,id_topic | 3,5  | NULL | 1 | Using intersect(id_member,id_topic); Using where; Using index | 
+----+-------------+----------------+-------------+--------------------+--------------------+---------+------+------+---------------------------------------------------------------+ 
1 row in set (0.00 sec) 

用另一個topicid解釋查詢。搞什麼鬼???

mysql> explain select * from forum_favorite where (id_member = 2) and id_topic = 20209; 
+----+-------------+----------------+------+--------------------+----------+---------+-------+------+-------------+ 
| id | select_type | table   | type | possible_keys  | key  | key_len | ref | rows | Extra  | 
+----+-------------+----------------+------+--------------------+----------+---------+-------+------+-------------+ 
| 1 | SIMPLE  | forum_favorite | ref | id_member,id_topic | id_topic | 5  | const | 1 | Using where | 
+----+-------------+----------------+------+--------------------+----------+---------+-------+------+-------------+ 
1 row in set (0.00 sec 

我已經從舊的mysql 4.x數據庫遷移到mysql 5.1最近,上述查詢給出一致的結果。 可能是什麼問題?!?!是什麼讓優化器變成瘋子?

+0

與此類似的錯誤:https://bugs.launchpad.net/ubuntu/+source/mysql-5.1/+bug/706988? – piotrekkr 2011-12-26 11:06:18

回答

0

您是否試過在桌上運行OPTIMIZE

UPD:

對於InnoDB表,OPTIMIZE TABLE被映射到ALTER TABLE,以重新生成表更新聚集索引指數統計和自由未使用的空間。

我覺得問題其實是在Using intersect(id_member,id_topic);。我會將id_topic索引擴展到(id_topic,id_member),以便它使用單個鍵進行查找,而不是索引合併(在MySQL中實際上很少見)。

+0

優化表是用於分段的,InnoDB表不建議這樣做。我重新創建了這個索引,但是這有點奇怪。 – Jauzsika 2011-12-25 16:53:02

+0

@jauzsika,我更新了我的答案。 – newtover 2011-12-26 10:58:07