2015-12-17 3 views
1

Я делаю некоторую работу над базой данных, чтобы сделать ее более организованной. В настоящее время каждая запись идентифицируется комбинацией из 3 столбцов, поэтому в настоящее время она имеет уникальный ключ, который состоит из трех элементов: u1, u2 и u3. Однако у меня есть еще одна таблица, которая связывает u1, u2 и u3, с другим уникальным идентификатором, uid. Таблица с тройным уникальным идентификатором имеет месячные значения, тогда как один с единственным идентификатором - это просто информационный столбец. Я хочу взять uid из информационной таблицы и поместить ее в ежемесячную таблицу. Поэтому я создал столбец uid в ежемесячной таблице и написал этот запрос.Более эффективно выполнять соединение и обновление

Объяснить выход ниже:

UPDATE monthly_table 
INNER JOIN information_table ON 
monthly_table.u1 = information_table.u1 AND monthly_table.u2 = information_table.u2 
AND monthly_table.u3 = information_table.u3 
SET monthly_table.uid = information_table.uid; 

К сожалению, у меня есть около 8 миллионов строк в ежемесячной таблице, и когда я запускаю этот запрос (из командной строки) она занимает около 1 часа, чтобы закончить. Я установил кэш InnoDB 3 или 4 ГБ. Я также поставил индексы на клавишах u1, u2 и u3 в обеих таблицах, а EXPLAIN говорит, что с этими клавишами будет 2 простых выбора.

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

+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+ 
| id | select_type | table     | type | possible_keys    | key  | key_len | ref           | rows | Extra  | 
+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+ 
| 1 | SIMPLE  | monthly_table   | ALL | u1,u2,u3     | NULL  | NULL | NULL           | 8284393 | Using where | 
| 1 | SIMPLE  | information_table  | ref | u2,u1,u3     | u3  | 33  |dbname.monthly_table.u1      |  2 | Using where | 
+------+-------------+-----------------------+------+---------------------------+----------+---------+-----------------------------------------------+---------+-------------+ 
+0

Вы можете включать вывод EXPLAIN. – dan08

+0

@ dan08 - добавлено объяснение вывода – user3413723

ответ

1

У вас есть три индекса для каждой таблицы для столбцов u1, u2 и u3 соответственно. Это не поможет, поскольку любой заданный запрос может использовать только один индекс за раз.

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

CREATE UNIQUE INDEX monthly_table_my_index 
ON monthly_table (u1, u2, u3); 

CREATE UNIQUE INDEX information_table_my_index 
ON information_table (u1, u2, u3); 
+0

Принял меня немного, чтобы подготовиться к другому тесту ... Спасибо! Я также использовал FORCE INDEX, чтобы убедиться, что он использовал этот индекс. – user3413723