Mysql: создать индекс на 1,4 миллиарда записей

У меня есть таблица с 1,4 миллиарда записей. Структура таблицы следующая:

CREATE TABLE text_page (
    text VARCHAR(255),
    page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii

Требуется создать индекс по столбцу text,

Размер стола составляет около 34G.

Я попытался создать индекс с помощью следующего утверждения:

ALTER TABLE text_page ADD KEY ix_text (text)

После 10 часов ожидания я наконец отказался от этого подхода.

Есть ли реальное решение по этой проблеме?

ОБНОВЛЕНИЕ: таблица вряд ли будет обновлена ​​или вставлена ​​или удалена. Причина, по которой нужно создать индекс по столбцу text потому что этот вид SQL-запроса будет часто выполняться:

SELECT page_id FROM text_page WHERE text = ?

ОБНОВЛЕНИЕ: я решил проблему, разделив таблицу.

Стол разбит на 40 шт. По колонке text, Затем создание индекса для таблицы занимает около 1 часа.

Кажется, что создание индекса MySQL становится очень медленным, когда размер таблицы становится очень большим. А разбиение сокращает таблицу на меньшие стволы.

7 ответов

Может быть, ваша система просто не подходит для этой задачи? Я не использую MySQL (здесь SQL Server), но я знаю, как индексировать таблицу с 800 миллионами записей. В основном.... вам нужно подходящее оборудование для этого (как в: много быстрых дисков). Сейчас я использую почти дюжину велоцирапторов, и производительность великолепна;)

Серверы SQL (не как MS SQL Server, а как серверы баз данных, использующие SQL) живут и умирают с доступом к диску, а обычные диски просто не подходят для более крупных операций.

Я решил проблему, разделив таблицу.

Стол разбит на 40 шт. По колонке text, Затем создание индекса для таблицы занимает около 1 часа.

Кажется, что создание индекса MySQL становится очень медленным, когда размер таблицы становится очень большим. А разбиение сокращает таблицу на меньшие стволы.

Возможно, вы захотите создать индекс по первым (например, 10) символам текстового поля.

Из документов:

Могут быть созданы индексы, которые используют только начальную часть значений столбца, используя синтаксис col_name(length) для указания длины префикса индекса:

CREATE INDEX ix_text ON text_page (text(10))

Установите sort_buffer_size на 4 ГБ (или столько, сколько сможете, в зависимости от того, сколько у вас памяти).

Прямо сейчас создание индекса выполняет сортировку, но, поскольку у вас есть 32 МБ sort_buffer_size, в основном он без необходимости перебивает жесткий диск.

Если вам не нужно делать запросы, такие как:

SELECT page_id FROM text_page WHERE text LIKE '?%';

Я бы предложил создать новый столбец хеша и индексировать таблицу по столбцу. Общий размер таблицы + индекс может быть намного меньше.

UPD: Кстати, 1,4 миллиарда целых чисел первичного ключа занимают около 6 ГБ, то есть средняя длина строки составляет менее 30 символов, то есть индексирование по префиксу может быть более предпочтительным.

Вы также должны взглянуть на механизм хранения MERGE.

Один из способов сделать это - создать новую таблицу с установленным индексом и скопировать данные в новую таблицу.

Также убедитесь, что у вас достаточно временного пространства.

Если вам все еще интересно, как это сделать лучше всего, я бы посоветовал вам использовать онлайн-инструмент для изменения таблицы.

В интернете их много, одним из известных являются:

У нас те же проблемы с большими таблицами (более 500 миллионов записей), и изменения идут отлично. Он создает новую таблицу tmp, добавляет триггер к исходной таблице (для новых записей обновления / удаления / вставки) и в то же время копирует все записи в новую таблицу (с новой структурой)

Удачи!

Другие вопросы по тегам