сумасшедшая кардинальность имеет значение для отображения статуса таблицы - PullRequest
4 голосов
/ 06 марта 2012

Итерация1:

mysql> show table status LIKE "mybigusertable";
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+
| Name            | Engine | Version | Row_format | Rows    | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation       | Checksum | Create_options | Comment                  |
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+
| mybigusertable | InnoDB |      10 | Compact    | 3089655 |           1686 |  5209325568 |               0 |    797671424 |         0 |        3154997 | 2011-12-04 03:46:43 | NULL        | NULL       | utf8_unicode_ci |     NULL |                | InnoDB free: 13775872 kB | 
+-----------------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+--------------------------+

mysql> show index from mybigusertable;
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table           | Non_unique | Key_name        | Seq_in_index | Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| mybigusertable |          0 | PRIMARY         |            1 | someid         | A         |     3402091 |     NULL | NULL   |      | BTREE    

Итерация 2

mysql> show index from mybigusertable;
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table           | Non_unique | Key_name        | Seq_in_index | Column_name        | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-----------------+--------------+--------------------+-----------+-------------+----------+--------+------+------------+---------+
| mybigusertable |          0 | PRIMARY         |            1 | someid         | A         |     2811954 |     NULL | NULL   |      | BTREE    

Время, указанное выше между двумя, было менее 5 секунд.Почему такая резкая разница каждый раз, когда вызывается индекс шоу?

Это происходит только с этой таблицей, я проверил несколько больших таблиц, и они отображают одни и те же числа каждый раз, когда к ним обращаются

Счет FYI в таблице:

mysql> select count(*) from mybigusertable;
+----------+
| count(*) |
+----------+
|  3109320 | 
+----------+
1 row in set (4 min 34.00 sec)

Несколько вопросов:

  1. Почему кардинальность так сильно меняется и имеет ли это значение?
  2. Насколько важна Оптимизация таблицы ?и это сделает запросы быстрее?

Ответы [ 2 ]

1 голос
/ 06 марта 2012

Я думаю, что проблема связана с тем, как обрабатываются метаданные таблицы для InnoDB.

InnoDB имеет тенденцию использовать некоторую форму приближения глубины поиска (продиктовано optimizer_search_depth )что влечет за собой погружение в индексы, определяющие количество элементов.

Попробуйте отключить innodb_stats_on_metadata

SET GLOBAL innodb_stats_on_metadata = 0;

Это поможет прочитать метаданные немного быстрее истабилизировать планы выполнения запросов.

ОБНОВЛЕНИЕ 2012-03-06 11:55 EST

Выполнение команды OPTIMIZE TABLE для таблицы InnoDB бесполезно, поскольку однажды вы попытаетесь выполнить попыткускомпилировать статистику индекса, она будет перечитана заново, если innodb_stats_on_metadata по-прежнему равен 1. Я писал об этом в DBA StackExchange еще в июне 2011 года.

ОБНОВЛЕНИЕ 2012-03-0611:59 EST

OK. Так как вы используете MySQL 5.0.77, OPTIMIZE TABLE просто старая и бесполезна для восстановления статистики индекса в InnoDB.

OPTIMIZE TABLE иANALYZE TABLE отлично работает только для MyISAM.

0 голосов
/ 06 марта 2012

MySQL определяет мощность индекса путем выборки случайных страниц из индекса.Страницы имеют различное количество записей и распределение.

Для индексов, где количество элементов не меняется, вполне вероятно, что индекс помещается на одной странице, или страницы имеют равномерное распределение (например, из таблицы оптимизации).

Если количество сильно различается, вы можете подумать об оптимизации таблицы для перераспределения записей.Это поможет MySQL выбрать лучший индекс.

...