Mysql 5.1.49 InnoDB / оптимизатор запросов действует странно? - PullRequest
0 голосов
/ 25 декабря 2011

У меня есть следующая таблица InnoDB, которая работает немного странно в MySQL 5.1.49 (mysql Ver 14.14 Distrib 5.1.49, для debian-linux-gnu (x86_64) с использованием readline 6.1)

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, где вышеупомянутые запросы дали согласованные результаты.В чем может быть проблема?!?!Что заставляет оптимизатора сходить с ума?

1 Ответ

0 голосов
/ 25 декабря 2011

Вы пытались запустить OPTIMIZE для таблицы?

UPD:

Для таблиц InnoDB OPTIMIZE TABLE сопоставляется с ALTER TABLE, который перестраиваеттаблица для обновления статистики индекса и освобождения неиспользуемого пространства в кластерном индексе.

Я думаю, что проблема на самом деле в Using intersect(id_member,id_topic);.Я бы расширил индекс id_topic до (id_topic, id_member), чтобы он использовал один ключ для поиска вместо слияния индекса (что на самом деле довольно редко в MySQL).

...