Индексирование для быстрого соединения между регулярно усекаемой таблицей и большой таблицей в MySQL

#mysql #join #indexing #truncate

#mysql #Присоединиться #индексирование #усечение

Вопрос:

У меня есть две таблицы, которые регулярно соединяются.

Первая таблица содержит около 1 миллиона строк и растет ежедневно. Вторая таблица всегда примерно на 200 кб меньше первой таблицы. Кроме того, вторая таблица усекается и заполняется заново каждую ночь из отчета, загруженного из внешней службы. Запрос UPDATE ..JOIN, который я использую, не слишком быстрый, поэтому я ищу возможное решение.

Структура первой таблицы:

 #I grow daily and currently am around 1 million rows.
CREATE TABLE table_one(
 id INT NOT NULL AUTO_INCREMENT,
 sku VARCHAR(30), 
 other_one VARCHAR(30),
 PRIMARY KEY(id)
);
  

Структура второй таблицы:

 #I get truncated every night and am about 200k less rows than Table One.
CREATE TABLE table_two(
 id INT NOT NULL AUTO_INCREMENT,
 sku VARCHAR(30), 
 other_two INT,
 PRIMARY KEY(id)
);
  

Обратите внимание, что поля other_one и other_two в обеих таблицах предназначены только для демонстрации того, что в каждой таблице есть поля (в основном varchar) помимо id и sku, но на самом деле в каждой таблице много разных столбцов. Я не уверен, что это имеет значение, но артикул уникален во второй таблице и уникален только в 95% случаев в первой таблице. Из-за этого уникальность не применяется ни к одной таблице в MySQL.

Итак, вот мой рабочий процесс и вопрос:

1) В первую таблицу в течение дня добавляется множество новых строк.
2) Каждая вторая таблица усекается (все строки удаляются)
3) Отчет загружается от третьей стороны в виде плоского файла CSV. Затем этот отчет загружается во вторую таблицу с помощью команды LOAD DATA LOCAL INFILE .
4) выполняются 3 запроса, которые обновляют данные первой таблицы и включают СОЕДИНЕНИЕ. Все они выглядят очень похоже на это:

 UPDATE table_one t1
JOIN table_two t2 ON t2.sku = t1.sku
SET t1.other_one = "Other two was greater than zero!"
WHERE t1.other_one IS NULL AND t2.other_two > 0
  

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

Ответ №1:

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

Комментарии:

1. Звучит как план. Я бы даже не подумал удалять индекс перед усечением, если бы вы не указали на это. В какой-то момент я наткнулся на сообщение в блоге, в котором говорилось о различных типах индексации с MySQL, в частности, о табличных соединениях. IIRC, в нем были описаны некоторые ситуации, когда обычное индексирование может не ускорить процесс. Хоть убей, я не могу его найти. В любом случае, я воспользуюсь вашим советом и посмотрю, что из этого получится. Если это не позаботится обо всем, я снова начну поиск этого сообщения. Спасибо!