2016-03-31 2 views
12

У меня есть проблема с этим запросом:Different план объяснить в том же кластере

SELECT 
    uca.user_activity_id, 
    uca.user_call_id, 
    uca.call_activity_id, 
    uca.user_activity_token, 
    uc.call_group_id, 
    uc.user_id 
FROM users_calls_activities uca 
INNER JOIN users_calls_activities uca2 ON uca2.user_activity_id = uca.user_activity_is_validated_with 
    AND aux.user_call_id = 1744136 
INNER JOIN users_calls uc ON uc.user_call_id = uca.user_call_id; 

У нас есть кластер с Percona сервера (5.6.29) с 5 узлами (от 0 до 4) в Azure. Разница между узлами 0-3 и 4 заключается в том, что первые из них находятся в балансе, а узел 4 выходит из балансира (но в кластере)

Проблема заключается в том, что на четырех серверах (узлах 0 -3) запрос выполняется очень медленно (15 секунд), а в другом (узел 4) запрос выполняется очень быстро (0,002)

Afaik, план объяснения должен быть таким же, но я выполняю EXPLAIN и результат заключается в следующем:

Узлы 0-3 (Медленная)

 
+----+-------------+-------+------+-------------------------------------------------------------+--------------+---------+-------------------------------+---------+---------------------------------------+ 
| id | select_type | table | type | possible_keys            | key   | key_len | ref       | rows | Extra         | 
+----+-------------+-------+------+-------------------------------------------------------------+--------------+---------+-------------------------------+---------+---------------------------------------+ 
| 1 | SIMPLE  | uca2 | ref | PRIMARY,user_call_id,user_call_id_2       | user_call_id | 4  | const       |  1 | Using index       | 
| 1 | SIMPLE  | uc | ALL | PRIMARY,user_call_id          | NULL   | NULL | NULL       | 2098152 | Using join buffer (Block Nested Loop) | 
| 1 | SIMPLE  | uca | ref | user_call_id,user_call_id_2,is_validated_with    | user_call_id | 4  | db.uc.user_call_id   |  1 | Using where       | 
+----+-------------+-------+------+-------------------------------------------------------------+--------------+---------+-------------------------------+---------+---------------------------------------+ 

Узел 4 (быстрый)

 
+----+-------------+-------+--------+-------------------------------------------------------------+---------------------------------+---------+-----------------------------------+---------+-----------------------+ 
| id | select_type | table | type | possible_keys            | key        | key_len | ref        | rows | Extra     | 
+----+-------------+-------+--------+-------------------------------------------------------------+---------------------------------+---------+-----------------------------------+---------+-----------------------+ 
| 1 | SIMPLE  | uca2 | ref | PRIMARY,user_call_id,user_call_id_2       | user_call_id     | 4  | const        |  1 | Using index   | 
| 1 | SIMPLE  | uca | ref | user_call_id,user_call_id_2,is_validated_with    | is_validated_with    | 5  | db.uc2.user_activity_id   | 2755595 | Using index condition | 
| 1 | SIMPLE  | uc | eq_ref | PRIMARY,user_call_id          | PRIMARY       | 4  | db.uca.user_call_id    |  1 | NULL     | 
+----+-------------+-------+--------+-------------------------------------------------------------+---------------------------------+---------+-----------------------------------+---------+-----------------------+ 

Я заметил, что в медленном индексе не используется. поэтому я проверил показатели:

Узел 0:

 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| users_calls  |   0 | PRIMARY    |   1 | user_call_id   | A   |  2099153 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | call_group_id  |   1 | call_group_id  | A   |  16659 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_call_begin_date |   1 | user_call_begin_date | A   |  1049576 |  NULL | NULL | YES | BTREE  |   |    | 
| users_calls  |   1 | user_call_begin_date |   2 | user_call_end_date | A   |  2099153 |  NULL | NULL | YES | BTREE  |   |    | 
| users_calls  |   1 | user_call_id   |   1 | user_call_id   | A   |  2099153 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_call_id   |   2 | user_id    | A   |  2099153 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   1 | user_id    | A   |  91267 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   2 | call_id    | A   |  2099153 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   3 | user_call_status  | A   |  2099153 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | fk_users_calls_calls |   1 | call_id    | A   |  23067 |  NULL | NULL |  | BTREE  |   |    | 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

Узел 4:

 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table   | Non_unique | Key_name    | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| users_calls  |   0 | PRIMARY    |   1 | user_call_id   | A   |  2091476 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | call_group_id  |   1 | call_group_id  | A   |  26813 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_call_begin_date |   1 | user_call_begin_date | A   |  1045738 |  NULL | NULL | YES | BTREE  |   |    | 
| users_calls  |   1 | user_call_begin_date |   2 | user_call_end_date | A   |  2091476 |  NULL | NULL | YES | BTREE  |   |    | 
| users_calls  |   1 | user_call_id   |   1 | user_call_id   | A   |  2091476 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_call_id   |   2 | user_id    | A   |  2091476 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   1 | user_id    | A   |  53627 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   2 | call_id    | A   |  2091476 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | user_id    |   3 | user_call_status  | A   |  2091476 |  NULL | NULL |  | BTREE  |   |    | 
| users_calls  |   1 | fk_users_calls_calls |   1 | call_id    | A   |  15608 |  NULL | NULL |  | BTREE  |   |    | 
+-----------------+------------+----------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

Мой первый вопрос, почему это индексы разные? это должно быть одинаково из-за того, что оба находятся в одном и том же кластере?

Почему планы выполнения различны? Оба находятся в одном кластере, поэтому он должен быть таким же

Должен ли я использовать FORCE INDEX или STRAIGHT_JOIN?

+0

Каковы индексы для 'user_calls_activities',' is_validated_with', похоже, находятся на этой таблице. –

ответ

0

Я думаю, что у вас есть поле user_call_id на обеих таблицах. Если изменить запрос, как это он заставит сервер использовать индексы:

SELECT 
    uca.user_activity_id, 
    uca.user_call_id, 
    uca.call_activity_id, 
    uca.user_activity_token, 
    uc.call_group_id, 
    uc.user_id 
FROM users_calls_activities uca 
INNER JOIN users_calls_activities uca2 ON uca2.user_activity_id = uca.user_activity_is_validated_with AND uca2.user_call_id = 1744136 
INNER JOIN users_calls uc ON uc.user_call_id = uca.user_call_id uc.user_call_id = 1744136 
WHERE uca.user_call_id = 1744136; 
+0

Извините за задержку ответа, но ваше предложение не работает, такая же проблема – Sal00m

1

Ответ скрыт в двух объясняющих выходов - на узле 4, второе соединение является использование индекса is_validated_with на uca столе, но ожидаемое количество строк - 2755595, что больше количества строк для полного сканирования таблицы uc на другом плане.

Имея доступную информацию, трудно сказать наверняка, но поскольку узлы 0-3 видят активное использование, а node4 - нет, я предполагаю, что статистика, которую оптимизатор использует для определения планов запросов, может больше не отражать фактическое состояние таблицы. Вы можете попытаться запустить ANALYZE TABLE во всех трех таблицах на всех узлах, и я подозреваю, что вы увидите тот же самый сгенерированный план (при условии, что все узлы имеют одинаковые данные).

В дополнение к использованию FORCE_INDEX вы также можете настроить optimizer flags, чтобы попытаться использовать один план над другим, но, как правило, гораздо лучше исправить основную проблему, так как вы можете исправить эту проблему сейчас, только чтобы укусить что-то еще позже.

Смежные вопросы