2015-09-16 3 views
0

SQL-запрос является довольно стандартным внутренним типом объединения. Например, сравнение n таблиц, чтобы увидеть, какой clientId существует во всех n таблицах, будет основным запросом WHERE ... AND.Перегородка очень большой ВХОДНЫЙ JOIN SQL-запрос

Проблема заключается в размере таблиц> 10 миллионов записей. База данных денормализуется. Нормализация - это не вариант. Запрос либо длится до завершения, либо не завершается.

Я не уверен, имеет ли это значение, но мы используем весовые модули задания xd для других типов запросов.

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

Другие сообщения с аналогичной проблемой предполагают использование альтернативных методов, помимо механизма базы данных, например, внедрение LOOP JOIN в коде или использование MapReduce или Hadoop, никогда не использовавшееся либо я не уверен, стоит ли рассматривать этот вариант использования.

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

Довольно загадочное оригинальное требование было:

Сравнить party_id колонки в трех очень больших таблицах для идентификации клиента, доступного в три таблице т.е. если это операция И между три. SAMPLE1.PARTY_ID AND SAMPLE2.PARTY_ID AND SAMPLE3.PARTY_ID

Если операция OR, то выберите всех клиентов, доступных в трех таблицах. SAMPLE1.PARTY_ID ИЛИ SAMPLE2.PARTY_ID ИЛИ SAMPLE3.PARTY_ID

И/ИЛИ используются между таблицами, после чего выполняется сравнение по мере необходимости. SAMPLE1.PARTY_ID И SAMPLE2.PARTY_ID ИЛИ SAMPLE3.PARTY_ID

Я создал несколько 4 тестовых таблиц, каждый с этим определением

CREATE TABLE `TABLE1` (
    `CREATED` datetime DEFAULT NULL, 
    `PARTY_ID` varchar(45) NOT NULL, 
    `GROUP_ID` varchar(45) NOT NULL, 
    `SEQUENCE_ID` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`SEQUENCE_ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=978536 DEFAULT CHARSET=latin1; 

Затем добавляют 1000000 записей каждый раз случайных чисел в диапазоне, который должен привести к присоединяется.

Я использовал следующий тестовый запрос

SELECT `TABLE1`.`PARTY_ID` AS `pi1`, `TABLE2`.`PARTY_ID` AS `pi2`, `TABLE3`.`PARTY_ID` AS `pi3`, `TABLE4`.`PARTY_ID` AS `pi4` FROM `devt1`.`TABLE2` AS `TABLE2`, `devt1`.`TABLE1` AS `TABLE1`, `devt1`.`TABLE3` AS `TABLE3`, `devt1`.`TABLE4` AS `TABLE4` WHERE `TABLE2`.`PARTY_ID` = `TABLE1`.`PARTY_ID` AND `TABLE3`.`PARTY_ID` = `TABLE2`.`PARTY_ID` AND `TABLE4`.`PARTY_ID` = `TABLE3`.`PARTY_ID` 

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

+1

«Сравнение n таблиц, чтобы увидеть, какой клиентId существует во всех n таблицах» не звучит как «довольно стандартный тип внутреннего соединения» для меня. Вероятно, это поможет, если вы разместите пример запроса того, что вы пытаетесь сделать. – Uueerdo

+0

Выполнение собственного разбиения - это дело, конечно. Если вы достаточно часто достигаете этого уровня обработки, можете ли вы перейти к среде с большими данными? Если это так, я предлагаю http://trustedanalytics.github.io - я знаю, что он может справиться с уровнем соединения, которое вы пытаетесь сделать. – Prune

+0

@Uueerdo Я добавил описание требования. Это было мое первоначальное предположение, что это будет внутреннее соединение. Но явно использование sql - не лучшее решение, так как оно занимает слишком много времени. Я думаю, что может быть какой-то альтернативный алгоритм в науке о данных или что-то такое. – justify

ответ

0

Следующая может работать лучше, чем существующие нарисуй на основе запроса:

select party_id from 
(select distinct party_id from SAMPLE1 union all 
select distinct party_id from SAMPLE2 union all 
select distinct party_id from SAMPLE3) as ilv 
group by party_id 
having count(*) = 3 

Изменить условия count(*), чтобы соответствовать количество запрашиваемых таблиц.

Если вы хотите вернуть party_id значения, которые присутствуют в любой таблицы, а не все, а затем опустить окончательное having положение.

+0

В сценарии «любой таблицы» часть 'all'' union all' также может быть опущена. – Uueerdo

+0

Если UNION объединяет результаты строк из одной таблицы с строками другой таблицы (по вертикали), можете ли вы объяснить, как этот запрос будет исключать какие-либо party_id, которых нет в SAMPLE2, например? – justify

+0

@justify: Это то, что имеет значение 'count count (*) = 3' - любые значения' party_id', которые не во всех трех таблицах, будут иметь счет меньше трех. (Вот почему условие счета должно быть изменено, чтобы соответствовать общему количеству таблиц в запросе.) –

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