Оправдывает ли низкая кардинальность индекса и наличие слишком большого количества других индексов удаление индекса из таблицы, несмотря на использование ограничения внешнего ключа?

У меня есть таблица под названием customer_type с полями (id, customer_type). Он состоит из 5 строк, каждая из которых описывает тип клиента.

У меня также есть таблица с именем quote, которая использует customer_type_id в качестве одного из столбцов внешнего ключа:

CREATE TABLE `quote` (
    `id` int NOT NULL AUTO_INCREMENT,
    `number` int NOT NULL,
    `customer_type_id` tinyint(4) DEFAULT NULL,
    `comments` text,
    PRIMARY KEY (`id`),
    KEY `fk_customer_type` (`customer_type_id`),
    CONSTRAINT `fk_customer_type` 
        FOREIGN KEY (`customer_type_id`) 
        REFERENCES `customer_type` (`id`),
);

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

И вот я хочу удалить некоторые, в том числе например, fk_customer_type. Мощность этого индекса равна 5, тогда как мощность некоторых других индексов намного выше (например, 5000 или 20000).

Я не могу просто удалить индекс из-за ограничения внешнего ключа.

Вопрос

Оправдывает ли моя ситуация удаление этого внешнего ключа и соответствующего ограничения внешнего ключа? Где мои причины для удаления:

  1. уменьшите количество индексов в надежде улучшить производительность INSERT
  2. количество элементов «customer_type_id» очень низкое, поэтому производительность вряд ли пострадает.

Моими причинами против удаления могут быть:

  1. Я потеряю ссылочную целостность (ограничение внешнего ключа)

Есть ли какие-то конкретные недостатки, которые произойдут, если я удалю индекс? Стоит ли сохранять индекс только для того, чтобы сохранить ограничение индекса?


person Dennis    schedule 15.07.2020    source источник


Ответы (1)


Медленный журнал — отличный способ определить самые медленные запросы. Подробнее: mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog

Я начал с этого комментария, потому что подозреваю, что ваш вопрос о количестве элементов, FK и удалении индексов имеет очень мало общего с вашими проблемами с производительностью.

  • Мощность этого TINYINT ниже в таблице quote. Так? Если вы просматриваете все строки с customer_type_id = 2, оптимизатор, вероятно, проигнорирует INDEX(customer_type_id). Но я не думаю, что у вас есть это. Посмотрим SHOW CREATE TABLE quotes.

  • Таблица customer_type крошечная. Его данные и индекс(ы) настолько тривиальны, что я даже не хочу их обсуждать. И вы, вероятно, никогда не добавите к этому многого.

  • Во время INSERT INTO customer_type ... ограничение FOREIGN KEY должно проверять наличие соответствующей строки в customer_type; это занимает небольшое количество ресурсов ЦП, но, вероятно, не требует ввода-вывода. В первый раз будет прочитан один блок, затем этот блок останется в кеше (см. innodb_buffer_pool_size) до завершения работы.

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

Я вижу 2 индекса в quotes.

  • PRIMARY KEY сгруппировано с данными и необходимо. И, поскольку это AUTO_INCREMENT, вставки будут идти в конец таблицы — весьма эффективно.
  • KEY(customer_type_id) -- Я уже объяснил, что это, наверное, бесполезно. Но это не имеет большого значения. То есть это не объясняет ваше предполагаемое замедление.

В таблице котировок есть другие столбцы и индексы

Давайте посмотрим на них!

Обычно 10 индексов не имеют большого значения. Но может быть UUID или GUID или что-то еще, что вызывает тревогу. Кроме того, если quotes состоит из миллиарда строк, другие проблемы поднимают свою уродливую голову. Или большие текстовые/BLOB-столбцы.

(Конечно, если у вас есть миллиард строк, вы рискуете переполнить AUTO_INCREMENT. Это грязно для исправления.

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

Пакетные вставки могут значительно ускорить их. Опишите вставки (случайно поступающие от нескольких клиентов / 1000 за раз / что угодно).

person Rick James    schedule 16.07.2020