Индекс MySQL больше, чем хранимые данные - PullRequest
12 голосов
/ 19 апреля 2011

У меня есть база данных со следующей статистикой

Tables     Data   Index   Total
11     579,6 MB  0,9 GB  1,5 GB

Так что, как вы можете видеть, индекс почти в 2 раза больше.И есть одна таблица с ~ 7 миллионами строк, которая занимает как минимум 99% от этого.

У меня также есть два очень похожих индекса

a) UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`),
b) KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`)

Обновление : Вот определение таблицы (по крайней мере, структурно) самой большой таблицы

CREATE TABLE `invoices` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `customer_id` int(10) unsigned NOT NULL,
  `order_no` varchar(10) default NULL,
  `invoice_no` varchar(20) default NULL,
  `customer_no` varchar(20) default NULL,
  `name` varchar(45) NOT NULL default '',
  `archived` tinyint(4) default NULL,
  `invoiced` tinyint(4) default NULL,
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `group` int(11) default NULL,
  `customer_group` int(11) default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`),
  KEY `idx_time` (`time`),
  KEY `idx_order` (`order_no`),
  KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`)
) ENGINE=InnoDB AUTO_INCREMENT=9146048 DEFAULT CHARSET=latin1 |

Обновление 2 :

mysql> show indexes from invoices;
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table    | Non_unique | Key_name                   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| invoices |          0 | PRIMARY                    |            1 | id          | A         |     7578066 |     NULL | NULL   |      | BTREE      |         |
| invoices |          0 | idx_customer_invoice       |            1 | customer_id | A         |          17 |     NULL | NULL   |      | BTREE      |         |
| invoices |          0 | idx_customer_invoice       |            2 | invoice_no  | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_time                   |            1 | time        | A         |      541290 |     NULL | NULL   |      | BTREE      |         |
| invoices |          1 | idx_order                  |            1 | order_no    | A         |        6091 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            1 | customer_id | A         |          17 |     NULL | NULL   |      | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            2 | invoice_no  | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            3 | order_no    | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

Мои вопросы:

  1. Есть ли способ найти неиспользуемые индексы в MySQL?
  2. Существуют ли распространенные ошибки, влияющие на размер индекса?
  3. Может ли indexAбезопасно удалить?
  4. Как вы можете измерить размер каждого индекса?Все, что я получаю, это сумма всех индексов.

Ответы [ 5 ]

10 голосов
/ 19 апреля 2011

Вы можете удалить индекс A, потому что, как вы заметили, это подмножество другого индекса.И это можно сделать, не нарушая нормальную обработку.

Размер индексных файлов сам по себе не вызывает тревогу, и вполне может быть верно, что чистая выгода является положительной.Другими словами, не следует сбрасывать со счетов полезность и ценность индекса, поскольку он приводит к большому файлу.

Разработка индекса - сложное и тонкое искусство, включающее глубокое понимание объяснений оптимизатора запросов и обширное тестирование.,Но одна из распространенных ошибок - включить в индекс слишком мало полей, чтобы сделать его меньше.Другой способ заключается в тестировании индексов с недостаточными или недостаточно репрезентативными данными.

6 голосов
/ 22 мая 2012

Я могу ошибаться, но первый индекс (idx_customer_invoice) является УНИКАЛЬНЫМ, второй (idx_customer_invoice_order) - нет, поэтому вы, вероятно, потеряете ограничение уникальности при его удалении.Нет

1 голос
/ 19 апреля 2011

используйте

show indexes from table;

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

Вы можете безопасно удалить свои индексы (это не сломает таблицу), но будьте осторожны: некоторые запросы могут выполняться медленнее.Сначала вы должны проанализировать свои запросы, чтобы решить, нужен ли вам определенный индекс.

Я не думаю, что вы можете узнать длину данных определенного индекса.

НО, яЯ думаю, вы, вероятно, думаете, что если длина индексов больше, чем длина данных в два раза, это что-то ненормальное ... Ну, вы не правы.Все ваши индексы могут быть полезны;) Если у вас есть таблица, которая предоставляет много информации, и вам нужно искать по ней по большому количеству столбцов, вполне может быть, что индексы этой таблицы в 2 раза больше по размеру, чемданные таблиц.

1 голос
/ 19 апреля 2011

Есть ли способ найти неиспользуемые индексы в MySQL?

Оптимизатор ядра СУБД выберет правильный индекс при попытке оптимизировать ваш запрос. В зависимости от того, когда вы в последний раз собирали статистику по вашим индексам, выбранный индекс будет меняться. Неиспользуемые индексы могут внезапно стать использованными из-за нового перераспределения данных.

Можно ли безопасно удалить indexA?

Я бы сказал да, если indexA и indexB являются индексами B-Tree. Это связано с тем, что индекс, начинающийся с одинаковых столбцов в одном и том же порядке, будет иметь одинаковую структуру.

0 голосов
/ 19 апреля 2011
  1. indexA можно удалить, потому что есть indexB, включая indexA
  2. , как влияет длина индекса на тип столбца и длину столбца
  3. использование:

    выберите index_length из information_schema.tables где table_name = 'your_table_name' и table_schema = 'your_db_name';

    получите вашу таблицу index_length

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...