2016-10-19 2 views
0

У меня есть две таблицыКак сделать это соединение двумя огромными таблицами MySQL?

Table1:

column1: varchar(20) 
column2: varchar(20) 
column3: varchar(20) 

TABLE2:

column1: varchar(20) 
column2: varchar(20) 
column3: varchar(20) <- empty 
  • column1 и column2 оба имеют отдельный полнотекстовой индекс в table1

  • обе таблицы содержат 20 миллионов строк

мне нужно заполнить column3 из table2 путем сопоставления column1 & column2 от table2 до column1 & column2 от table1, затем возьмите значение в column3 от table1 и положите его в column3 от table2. column1 & column2 может не совпадать, поэтому запрос я использую для этого:

UPDATE table1, table2 
SET table2.column3 = table1.column3 
WHERE table2.column1 LIKE table1.'%column1%' AND 
     table2.column2 LIKE table1.'%column2%'; 

Этот запрос никогда не заканчивается. Я позволил ему работать в течение 2 недель и до сих пор не дал никакого результата. Он использовал один процессорный ядро ​​на 100%, имел мало SSD IO и, по-видимому, должен каким-то образом оптимизироваться.

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

EDIT1

Есть много оптимизации руководств, пожалуйста, используйте Google для этого. Вы можете увеличить потоки в config (InnoDB). Для самого обновления я рекомендую сначала создать temp_table, а затем скопировать на db2

Я знаю это, но не смог решить мой сценарий с помощью этих руководств. Я также знаю, что вопросы о всех возможных перестановках комбинаций для этой проблемы (огромные базы данных, производительность, узкие места, дизайн запросов) все вокруг, также в stackoverflow. Тем не менее, по сей день я не мог понять, что лучший способ для этого будет состоять в этом конкретном сочетании проблем и надеется получить помощь здесь. Сказанное: - больше потоков потребует осколки или разбиения на разделы, чтобы использовать более одного ядра ЦП, чего я бы хотел избежать, если я смогу решить проблему с помощью других средств - как бы вы предложили создать такую ​​временную таблицу здесь ?

Почему вы используете оператора, если вы не используете символы дикой карты? Замените их на =. Кроме того, есть ли у вас индекс нескольких столбцов в трех столбцах в критериях where в каждой из таблиц? Pls также делится результатами объяснения, а также с любыми существующими индексами в двух таблицах.

  • Я оставил эти символы в примере, но хочу использовать их, когда основной запрос работает, извините за путаницу. Я не совсем уверен, как поместить эти подстановочные знаки в сравнение столбцов.
  • У меня есть два отдельных индекса, следует ли вместо этого создать индекс с двумя столбцами? (есть только 2 столбца в критериях где)
  • Вы бы скорее объяснили структуру, которая у меня сейчас, или предпочитаете объяснение структуры с индексом с двумя столбцами?

Я думаю, вы говорите о базах данных, но вы говорите о таблицах, верно?

Точно, извините за путаницу.

Запрошенный вами запрос выполнит поиск 20 м x 20 м (для каждой строки в таблице 1 найдите все строки в таблице 2). Вы не можете писать что угодно и ожидать, что он будет работать, если у вас SSD или хороший процессор. Если вы пришли к этому моменту, пришло время подумать, прежде чем начинать писать SQL. Что вам нужно сделать, какие у вас есть инструменты, а какая средняя часть вы не знаете, - это те вопросы, которые вам нужно отвечать каждый раз, прежде чем вы выберете 400-миллиардный запрос поиска.

Это сценарий, с которым я столкнулся. Я не ожидаю, что он будет работать вообще, как в настоящий момент, если честно, поэтому я ищу указатели, которые могут сделать этот разрешимый сценарий. Основной запрос «update this, where that matches», по-видимому, здесь не применяется. Поэтому я пытаюсь найти способ более продвинутого решения. Любая критика очень приветствуется, поэтому спасибо за этот вклад. Как бы вы предложили продолжить здесь?

EDIT2

Дайте нам некоторые выборочные значения и без точных сравнений.

table1:

+---------+---------+-------------+---------+---------+---------+ 
| column1 | column2 | column3  | column4 | column5 | columnN | 
+---------+---------+-------------+---------+---------+---------+ 
| John | Doe_ | employee001 | xyz  | 12345 | ...  | 
| Jim  | Doe  | employee002 | abc  | 67890 | ...  | 
+---------+---------+-------------+---------+---------+---------+ 

table2:

+---------+---------+---------+ 
| column1 | column2 | column3 | 
+---------+---------+---------+ 
| John | Doe  |   | 
| Jim  | Doe  |   | 
+---------+---------+---------+ 

Здесь, LIKE запрос будет заполнить обе строки таблицы 2, если он будет соответствовать "Doe_" для " Doe». Но, написав это, я просто понял, что запрос LIKE здесь не является вариантом, потому что вариации не ограничивают суффикс столбца2 в таблице 1, скорее потребуются различные возможные симпатии (ведущие и конечные варианты для обоих столбцов в обоих таблицы). Это, в свою очередь, умножило бы количество необходимых совпадений. Итак, давайте забудем о LIKE и сосредоточимся только на точном сопоставлении.

FULLTEXT и LIKE не имеют никакого отношения друг к другу.

«Может не совпадать точно» - вам понадобятся дополнительные ограничения на это ограничение. Кроме того, любая попытка запроса будет продолжаться несколько недель.

t2.c1 КАК КОНКАТ ('%', t1.c1, '%') требует проверки любой строки t1 против каждой строки t2; это 400 триллионов тестов. Никакое оборудование не может сделать это за разумный промежуток времени.

FULLTEXT работает со словами «слова». Если ваши c1 и c2 являются строками слов, есть надежда на использование FULLTEXT. FULLTEXT намного быстрее, чем LIKE, потому что он имеет структуру индекса, основанную на словах.

Однако даже FULLTEXT не находится рядом со скоростью t2.c1 = t1.c1. Тем не менее, для этого потребуется составной INDEX (c1, c2). Тогда это будет полное сканирование таблицы (20M строк) одной таблицы, плюс 20M зондов с помощью индекса BTree в другую таблицу. Это похоже на 40M операций - намного лучше, чем 400T для LIKE.

Чтобы продолжить, пожалуйста, продумайте свое определение «Возможно, не так точно» и укажите лучшее, с чем вы можете жить.

Хорошо, так как я решил отказаться от требования LIKE, что именно вы предлагаете использовать в качестве индекса? Я прочитал ваш пост, как это:

ALTER TABLE `table1` ADD FULLTEXT INDEX `indexname1` (`column1`, `column2`); 

ALTER TABLE `table2` ADD FULLTEXT INDEX `indexname2` (`column1`, `column2`); 

UPDATE `table1`, `table2` 
SET `table2`.`column3` = `table1`.`column3 ` 
WHERE CONCAT(`table1`.`column1`, `table1`.`column2`) = CONCAT(`table2`.`column1`, `table2`.`column2`); 

Правильно ли это?

Два Followup вопросы, хотя: 1) Являются ли обновление в Ваших в школах, как быстрые, быстрее или медленнее, как создание новой таблицы, а именно:

CREATE TABLE `merged` AS 
SELECT `table1`.`column1`, `table1`.`column2`, `table1`.`column3` 
FROM `table1`, `table2` 
WHERE CONCAT(`table1`.`column1`, `table1`.`column2`) = CONCAT(`table2`.`column1`, `table2`.`column2`); 

2) Будет ли быть indizes и/или согласование деликатный случай? Если да, можно адаптировать запрос без изменения столбца & column2 ко всему верхнему регистру (или ко всему нижнему регистру)?

+1

Существует множество руководств по оптимизации, пожалуйста, используйте Google. Вы можете увеличить потоки в config (InnoDB). Для самого обновления я рекомендую сначала создать temp_table, а затем скопировать на db2 – Tiega

+0

Почему вы используете такой же оператор, если не используете символы wild card? Замените их '='. Кроме того, есть ли у вас индекс нескольких столбцов в трех столбцах в критериях where в каждой из таблиц? Pls также делится результатами объяснения, а также с любыми существующими индексами в двух таблицах. – Shadow

+0

Я думаю, вы говорите базы данных, но вы говорите о таблицах, верно? –

ответ

0

FULLTEXT и LIKE не имеют никакого отношения друг к другу.

«Может не совпадать точно» - вам понадобятся дополнительные ограничения на это ограничение. Кроме того, любая попытка запроса будет продолжаться несколько недель.

t2.c1 LIKE CONCAT('%', t1.c1, '%') требует проверки всегда ряда t1 против каждой строки t2; это 400 trillion тестов. Никакое оборудование не может сделать это за разумный промежуток времени.

FULLTEXT работает со словами «слова». Если ваши c1 и c2 являются строками слов, то есть надежда на использование FULLTEXT. FULLTEXT намного быстрее, чем LIKE, потому что он имеет структуру индекса, основанную на словах.

Однако даже FULLTEXT не находится рядом со скоростью t2.c1 = t1.c1. Тем не менее, для этого потребуется композитINDEX(c1, c2) Тогда это будет полное сканирование таблицы (строки 20M) одной таблицы, плюс 20M зондов с помощью индекса BTree в другую таблицу. Это похоже на 40M операций - намного лучше, чем 400T для LIKE.

Чтобы продолжить, пожалуйста, продумайте свое определение «Возможно, не так точно» и укажите лучшее, с чем вы можете жить.

Редактировать

WHERE CONCAT(t1.c1, t1.c2) = CONCAT(t2.c1, t2.c2) является много хуже, чем говорят WHERE t1.c1=t2.c2 AND t1.c2 = t2.c2. Последний будет работать быстро с INDEX(c1,c2).

+0

Я обновил описание соответствующим образом. – level20peon

+0

Рик, я только что нашел ваш блог, который ОТЛИЧНО! Вы должны были просто указать мне на это для справки, и я мог бы избавить остальных комментаторов от моих мелочных вопросов. – level20peon

+0

http://mysql.rjweb.org/ Спасибо за ваше время и силы! – level20peon

-1

Попробуйте это: 1. Добавить новый столбец в DB1 и DB2 с характером, который никогда не появляется в column1 и COLUMN2, например @

ALTER TABLE `db1` ADD `column4` VARCHAR(40) NOT NULL ; 

UPDATE db1 SET column4 = column1 + '@' + column2 

2. Сделайте то же самое db2. Затем создайте индекс (BTREE) в столбце 4 (в db1 и db2).

ALTER TABLE `db1` ADD INDEX ( `column4`) ; 

ALTER TABLE `db2` ADD INDEX ( `column4`) ; 

3. Затем запустите следующий запрос:

UPDATE db1, db2 SET db2.column3 = db1.column3 WHERE db1.column4 = db2.column4; 

Он должен работать достаточно быстро. Когда это будет сделано - просто опустите колонку4 и ее индекс

+0

(Используйте 'CONCAT (...)' вместо '+' в варианте MySQL MySQL.) –

Смежные вопросы