У меня есть таблица с 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 становится очень медленным, когда размер таблицы становится очень большим. А разбиение сокращает таблицу на меньшие стволы.
CREATE INDEX
выражения?Ответы:
Может быть, ваша система просто не подходит для этой задачи? Я не использую MySQL (здесь SQL Server), но я знаю, как индексировать таблицу с 800 миллионами записей. В основном .... вам нужно подходящее оборудование для этого (как в: много быстрых дисков). Сейчас я использую почти дюжину Velociraptors, и производительность просто великолепна;)
Серверы SQL (не как MS SQL Server, а как серверы баз данных, использующие SQL) живут и умирают с доступом к диску, а обычные диски просто не справляются с задачей более крупных операций.
источник
Возможно, вы захотите создать индекс по первым (например, 10) символам текстового поля.
Из документов:
Могут быть созданы индексы, которые используют только начальную часть значений столбца, используя синтаксис col_name (length) для указания длины префикса индекса:
источник
Я решил проблему, разделив таблицу.
Стол разбит на 40 столбцов
text
. Затем создание индекса для таблицы занимает около 1 часа.Кажется, что создание индекса MySQL становится очень медленным, когда размер таблицы становится очень большим. А разбиение сокращает таблицу на меньшие стволы.
источник
Установите sort_buffer_size на 4 ГБ (или столько, сколько вы можете в зависимости от того, сколько у вас памяти).
Прямо сейчас создание индекса выполняет сортировку, но, поскольку у вас есть sort_buffer_size 32 МБ, он в основном без необходимости перебивает жесткий диск.
источник
Если вам не нужно делать запросы, такие как:
Я бы предложил создать новый столбец хеша и индексировать таблицу по столбцу. Общий размер таблицы + индекс может быть намного меньше.
UPD : Кстати, 1,4 миллиарда целых чисел первичного ключа занимают около 6 ГБ, то есть средняя длина строки составляет менее 30 символов, то есть индексирование по префиксу может быть более предпочтительным.
Вы также должны взглянуть на механизм хранения MERGE .
источник
Один из способов сделать это - создать новую таблицу с установленным индексом и скопировать данные в новую таблицу.
Также убедитесь, что у вас достаточно временного пространства.
источник
Если вам все еще интересно, как это сделать лучше всего, я бы посоветовал вам использовать онлайн-инструмент для изменения таблицы.
В интернете их много, одним из известных являются:
http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
У нас те же проблемы с большими таблицами (более 500 миллионов записей), и изменения идут отлично. Он создает новую таблицу tmp, добавляет триггер к исходной таблице (для новых записей обновления / удаления / вставки) и в то же время копирует все записи в новую таблицу (с новой структурой)
Удачи!
источник