MySQL 5.5 «выбор отдельного» работает очень медленно

Одно из моих приложений делает изрядное количество:

select count(distinct id) from x;

с id основным ключ для таблицы x . В MySQL 5.1 (и 5.0) это выглядит так:

mysql> explain SELECT count(distinct id) from x;
+----+-------------+----------+-------+---------------+-----------------+---------+------+---------+-------------+
| id | select_type | table    | type  | possible_keys | key             | key_len | ref  | rows    | Extra       |
+----+-------------+----------+-------+---------------+-----------------+---------+------+---------+-------------+
|  1 | SIMPLE      | x        | index | NULL          | ix_blahblahblah | 1       | NULL | 1234567 | Using index |
+----+-------------+----------+-------+---------------+-----------------+---------+------+---------+-------------+

В InnoDB это не совсем так, но и неплохо.

На этой неделе я Я пробую MySQL 5.5.11 и с удивлением обнаружил, что тот же запрос выполняется во много раз медленнее. С заполненным кешем это занимает около 90 секунд по сравнению с 5 секундами ранее. Теперь план выглядит следующим образом:

mysql> explain select count(distinct id) from x;
+----+-------------+----------+-------+---------------+---------+---------+------+---------+-------------------------------------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows    | Extra                               |
+----+-------------+----------+-------+---------------+---------+---------+------+---------+-------------------------------------+
|  1 | SIMPLE      | x        | range | NULL          | PRIMARY | 4       | NULL | 1234567 | Using index for group-by (scanning) |
+----+-------------+----------+-------+---------------+---------+---------+------+---------+-------------------------------------+

Один из способов ускорить процесс - использовать select count (id) from x , что безопасно, потому что id является первичным ключом, но я прохожу через некоторые уровни абстракции (например, NHibernate), которые делают эту задачу нетривиальной.

Я пробовал анализировать таблицу x , но это не дало заметной разницы.

Это похоже на ] эта ошибка , хотя неясно, к каким версиям она относится и что происходит (никто не трогал ее за год, но она «серьезная / высокая / высокая»).

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

ОБНОВЛЕНИЕ:

По запросу, вот способ более или менее воспроизвести его. Я написал этот SQL-скрипт для генерации 1 миллиона строк фиктивных данных (выполнение занимает 10-15 минут):

  • выберите количество (отдельный идентификатор) из x
    • EXPLAIN is: key: ix_a, Extra: использование индекса
    • занимает менее 1,0 секунды для выполнения
  • выберите количество (идентификатор) из x
    • EXPLAIN: key: ix_a, Extra: использование индекса
    • занимает менее 0,5 секунды
  • 5.5.11
    • выберите счетчик (отдельный идентификатор) из x
      • EXPLAIN is: key: PRIMARY, Extra: использование индекса для группировки по
      • занимает более 7,0 секунд для выполнения
    • выберите счетчик (идентификатор) из x
      • EXPLAIN is: key: ix_a, Extra: Использование индекса
      • занимает менее 0,5 секунды для выполнения
  • EDIT:

    Если я изменю запрос в 5.5, сказав

    select count(distinct id) from x force index (ix_a);
    

    , он будет выполняться намного быстрее. Индексы b и c также работают (в разной степени), и даже принудительный индекс PRIMARY помогает.

    5
    задан Ken 19 April 2011 в 22:37
    поделиться