Покажите нам образец, скажем, первых 10 значений.
Вот почему вы, вероятно, "врезались в стену" ... Индексы можно разделить (на уровне) на две разновидности:
Непрерывный, такой как AUTO_INCREMENT
значения или TIMESTAMPs
, где вы вставляете строки в хронологическом или даже приблизительно в хронологическом порядке. Эти значения вставляются в «конец» таблицы или индекса и попадают только в последний блок (или несколько блоков) BTree. Имея всю активность всего в нескольких блоках, вы получаете мало операций ввода-вывода.
Случайные, такие как UUID, MD5 и другие «случайные» значения, предположительно включая ваши. В этом случае «следующее» значение для вставки в таблицу / индекс вряд ли все еще будет кэшироваться в ОЗУ. Так что ввод / вывод нужен. Несмотря на то, что таблица не слишком большая, все блоки индекса могут храниться в оперативной памяти, поэтому требуется небольшой ввод-вывод. Но после того, как индекс становится больше кеша, чаще всего для добавления значения «следующий» потребуется ввод / вывод. Ваш процесс будет становиться все медленнее и медленнее.
Что делать?
План A: добавить «случайный» индекс после , вставив все строки. Добавление индекса будет очень медленным, но, вероятно, быстрее в долгосрочной перспективе, поскольку он может использовать другой алгоритм.
План Б: Не создавайте все значения заранее. Вместо этого создайте следующий, когда вам это нужно.
План C: Купите достаточно ОЗУ, чтобы полностью хранить «случайный» индекс в ОЗУ. (Планируйте примерно в 2 раза больше размера индекса.)
План D: Вы пробовали TokuDB? Я ожидаю, что он выживет дольше, прежде чем он попадет в серьезные неприятности. Каким был ваш опыт.
Вы упомянули транзакции. Пожалуйста, дополните. Вы имели в виду, что каждые 5000 кодов были INSERTed
в транзакции? Это, вероятно, оптимально.
Какую кодировку и сопоставление вы используете для своего уникального номера? Вам, вероятно, следует использовать ascii и ascii_bin - для скорости и во избежание проблем с свертыванием регистра.
И ... Вот еще одна мысль о том, как их генерировать. Вам не нужно будет проверять уникальность, так как они будут сгенерированы уникально:
Думайте о ваших 10-символьных строках как о числах, закодированных в кодировке целых чисел base-95. (или сколько угодно разных символов, которые вы разрешаете). Мы будем генерировать числа последовательно, преобразовывать их в строки, а затем рандомизировать их.
Значение «next» вычисляется как случайное значение после значения «current». Случайное значение должно быть от 1 до некоторого приращения, которое может составлять около миллиарда (это зависит от того, сколько чисел вы в конечном итоге хотите, кодировка и т. Д.)
INSERT
пакетов по 5 КБ (или чего-либо другого) в таблицу MyISAM, которая не имеет индексов.
Когда закончите, сделайте это:
CREATE TABLE real (
id ... AUTO_INCREMENT, -- do you really need this??
random CHAR(10), NOT NULL CHARSET ascii COLLATE ascii_bin,
PRIMARY KEY(id), -- what for?
INDEX(random) -- uniqueness has been checked
INSERT INTO real (random)
SELECT random FROM myisam_table
ORDER BY RAND();
Вот как это будет работать:
- Извлекает все «случайные» строки из практически плоского файла (таблица MyISAM).
- Используйте unix sort для их шифрования.
INSERT
их в таблицу real
, последовательно создавая ids
.
Примечание: это создаст огромную таблицу отмен, поэтому убедитесь, что на диске много места.
Что касается моих комментариев об отмене id
, UNIQUE
и т. Д., Пожалуйста, предоставьте информацию о том, как вы намереваетесь использовать real
, чтобы я мог согласиться или оспорить их необходимость.
Другой план
Не создавайте предварительно значения. Вместо этого сгенерируйте новое значение из приблизительно 14T возможных значений, проверьте наличие дуплетов, сгенерируйте другое при необходимости. В этом плане таблица постепенно увеличивается по мере необходимости, а не изо всех сил, чтобы построить ее изначально. Вместо этого небольшое усилие (миллисекунды) затрачивается всякий раз, когда требуется новое значение. Это можно обернуть в сохраненную функцию, чтобы упростить для пользователя.
Таблица будет иметь только один столбец, unique_code CHAR(10) CHARSET ascii PRIMARY KEY
.