2015-09-10 4 views
0

У меня очень большой стол, 25+ миллионов записей.Группа с графом на очень большом столе

Мне нужно создать новую таблицу, в которой три поля уникальны.

Я попытался

SELECT Field1,Field2,Field3, Count(*) FROM `Table` group by Field1,Field2,Field3 having Count(*)>1 

Я получаю err- из памяти от Mysql

Есть более эффективный способ найти все уникальные записи с этими полями с числом> 1, так что я могу работать с ними дальше (создать новую таблицу и т. д.)?

+0

Если вам нужен счет, вам придется использовать 'group by'. –

+0

У вас есть идентификатор столбца auto_inc? Также сколько строк – Drew

+0

В зависимости от типов данных и значений, хранящихся в Field1, Field2 и Field3; вы можете использовать тщательно сконструированные условия в предложении WHERE, чтобы разделить данные на более управляемые отдельные «куски» и запустить несколько таких запросов для получения целого. (Пример: если поле1 является числовым типом с грубо равномерно распределенными значениями, вы можете запросить на основе поддиапазонов значений, натянутых, если это тип строки, вы могли бы отделить данные на основе первого или двух символов.) – Uueerdo

ответ

0

Возможное решение без изменения конфигурации памяти сервера:

CREATE TEMPORARY TABLE ttt AS 
SELECT Field1,Field2,Field3, Count(*) AS counter 
FROM `Table` group by Field1,Field2,Field3; 

Это может предотвратить из памяти, так как имеющий пункт не должен быть оценен. Затем после этого снова запустите таблицу ttt для счетчика > 1.

Вам необходимо будет проверить, не работает ли он. Он будет медленным (особенно второй запрос, так как нет индекса, который он может использовать во временной таблице, и сначала создание индекса не имеет смысла, когда вы просто запускаете этот оператор where).

1

Если вам не нужен подсчет, то следующее может производить то, что вы хотите:

select field1, field2, field3 
form table t 
where exists (select 1 
       from table t2 
       where t2.field1 = t.field1 and t2.field2 = t.field2 and 
        t2.field3 = t.field3 and t2.id > t.id 
      ) and 
     not exists (select 1 
        from table t2 
        where t2.field1 = t.field1 and t2.field2 = t.field2 and 
         t2.field3 = t.field3 and t2.id < t2.id 
       ); 

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

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

create index idx_table_field1_field2_field3 on table(field1, field2, field3) 

Если group by не удается, то это также может произойти сбой. Но если это удастся, то этот метод может быть довольно быстрым - если индекс может вписаться в память.

+0

@ Gordan индекс на трех полях вместе сделал трюк даже с использованием моего первоначального запроса. Я думал, что индекса на каждом поле достаточно, но ясно, что это было необходимо для группы. Благодаря! – user3649739

+0

@ пользователь3649739. , ,Интересно. Может быть сложно заставить MySQL использовать индекс для агрегации, но это, безусловно, случай, когда это работает правильно. –

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