Является ли CREATE INDEX в MySQL линейной операцией?

20

Я имею в виду следующее:

Если создание индекса для таблицы со nстроками занимает tвремя. Будет ли создание индекса для той же таблицы 1000*nзаймет примерно 1000*tвремя.

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

Nifle
источник

Ответы:

16

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

Если все ваши соответствующие страницы данных помещаются в ОЗУ и уже находятся в ОЗУ, и индекс также будет соответствовать, и ваша СУБД не заставляет страницы индекса записываться до завершения создания (поэтому блоки индекса не обновляются на диске несколько раз в течение операции), тогда скорость записи результирующего индекса на диск будет более значительной, чем время, затрачиваемое на выполнение сортировки - так что вы можете обнаружить, что приближаетесь к линейной зависимости между числом строк и временем, которое занимает создание индекса - но если вы предполагаете худший случай, вы менее вероятно будете неприятно удивлены!

Помните, что если вы не собираетесь останавливать доступ к производственной базе данных во время операции, любое создание индекса будет конкурировать за пропускную способность ввода-вывода и / или блокироваться с другой активностью, поэтому вы должны попытаться учесть это, если вы проводите тесты оценки времени. в другой системе, даже если она одинаково настроена.

Дэвид Спиллетт
источник
7

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

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

ПРЕДОСТЕРЕЖЕНИЯ: Я сам парень MSSQL, и поэтому я не уверен насчет MySQL, но я должен представить, что концепция разделения шпинделей не специфична для SQLServer и Oracle (где я слышал, что об этом тоже говорили, IIRC ). Я просто не знаю, как сделать это. Но в терминах SQLServer это означало бы наличие отдельной файловой группы помимо этого PRIMARYи размещение индексов в другой файловой группе, а другая файловая группа была назначена на набор неиспользуемых шпинделей PRIMARY(предоставленное размещение шпинделя по сравнению с файловыми группами - это совсем другая история)

Jcolebrand
источник
1
Почти то же самое в Oracle - только табличные
Джо
2

Если бы этот вопрос был задан около 6 лет назад, я бы категорически сказал «НЕТ», поскольку это относится к MySQL 4.x. Тем не менее, MySQL 5.x выполняет линейное создание индекса сегодня. У меня просто был ностальгический опыт, объясняющий это в моем ответе на этот предыдущий вопрос.

RolandoMySQLDBA
источник
1

По-разному.

Переменная # 1: Если MySQL решает построить индекс (ы) на лету или подождать, пока все данные не будут введены, выполните сортировку и т. Д., Чтобы построить индекс. Примечание: УНИКАЛЬНЫЕ индексы (я думаю) должны быть построены на лету, чтобы УНИКАЛЬНОСТЬ могла быть проверена. ПЕРВИЧНЫЙ КЛЮЧ для InnoDB хранится с данными (или вы могли бы заявить об этом наоборот), так что ДОЛЖЕН быть построен случайным образом.

Переменная # 2: Индекс отслеживает данные (например, AUTO_INCREMENT или метка времени) в зависимости от случайного (GUID, MD5) или где-то посередине (номер детали, имя, friend_id).

Переменная # 3 (если индекс создается на лету): индекс может помещаться в кэш (key_buffer или innodb_buffer_pool) или может пролиться на диск.

Индексы, которые отслеживают данные, являются эффективными и практически линейными, независимо от ответа на # 1.

Случайные идентификаторы - это боль. Если индекс не помещается в кеше, время его создания будет намного хуже линейного, независимо от других переменных. (Я не согласен с Роландо в этом случае.) Огромная таблица InnoDB с GUID для PK мучительно медленна для INSERT в план на 100 строк / сек для обычных дисков; возможно 1000, если у вас есть SSD. ЗАГРУЗКА ДАННЫХ и пакетные вставки не избавят вас от медлительности случайного хранения.

3,53 - 5,6 - мало что изменилось.

Несколько шпинделей? Чередование RAID лучше практически в любой ситуации, чем ручное назначение этого здесь и этого туда. Ручное разбиение приводит к неуравновешенным ситуациям - сканирование таблицы застревает на диске с данными; операция только для индекса застревает на диске индекса; одиночный запрос сначала попадает на индексный диск, затем на диск с данными (без перекрытия); и т.п.

Рик Джеймс
источник