Избавьтесь от s_id
, это, вероятно, бесполезно.Тогда рекламируйте UNIQUE(t_id, s_name) to be the
PRIMARY KEY`.Это сокращает количество тестов, которые нужно выполнить для каждой вставленной строки.
Рассмотрите возможность отключения FOREIGN KEYs
;в конце концов, они должны выполнить проверку, которая может быть избыточной.
INSERT IGNORE INTO my_data (t_id, s_name)
SELECT t_id, s_name
FROM temporary_data
ORDER BY t_id, s_name; -- Add this
Таким образом, вставки не прыгают в целевой таблице, таким образом (мы надеемся) избегая большого количества операций ввода-вывода.
Вы дополняете стол?Или заменить его?При замене есть гораздо лучший подход.
Подробнее ...
Заметили ли вы, что INSERT IGNORE
тратит впустую значение AUTO_INCREMENT
для каждой строки, которая не вставляется?Давайте попробуем другой подход ...
INSERT INTO my_data (t_id, s_name)
SELECT t.t_id, t.s_name
FROM temporary_data AS t
LEFT JOIN my_data AS m USING(t_id, s_name)
WHERE m.s_id IS NULL
ORDER BY t.t_id, t.s_name;
ORDER BY
избегает прыгать во время INSERT
.
LEFT JOIN
ограничивает активность "новыми" строками.
НетAUTO_INCREMENT
значения будут записаны.
Сколько строк будет вставлено каждый раз?Если это миллионы, то было бы лучше разбить его на куски.Смотрите мое обсуждение о чанкинге.Это может быть быстрее, чем построить огромный след отмены, чтобы в конечном итоге бросить.
Дальнейшее обсуждение - Учитывая
my_data: PRIMARY KEY(s_id) -- and s_id is AUTO_INCREMENT
my_data: INDEX(t_id, s_name)
INSERT...SELECT...ORDER BY (t_id, s_name) -- same as index
Это эффективно:
- Поскольку
ORDER BY
и вторичный индекс одинаковы, добавления к индексу будут выполняться эффективно. - Между тем, новые значения
AUTO_INCREMENT
будут сгенерированы последовательно при«конец» таблицы.
Единственное, что было бы лучше, было бы, если бы (t_id, s_name)
были уникальными.Тогда мы могли бы рассмотреть возможность полного избавления от s_id
и изменения двух индексов на этот:
PRIMARY KEY(t_id, s_name)
Это было бы проблемой, если бы другие таблицы ссылались на s_id
. возможный обходной путь состоит в том, чтобы сохранить s_id и иметь
PRIMARY KEY(t_id, s_name)
INDEX(s_id) -- sufficient for AUTO_INCREMENT
. Я не знаю достаточно о большой картине и других запросах, чтобы судить, какое направление выбрать.Поэтому мое первоначальное предложение (до «Дальнейшего обсуждения») было «консервативным».