MySQL Query: подсчет повторяющихся значений в действительно огромной таблице - PullRequest
5 голосов
/ 19 апреля 2011

У меня есть таблица MySQL:

CREATE TABLE `triple` (
  `id_one` int(11) NOT NULL,
  `id_two` int(11) NOT NULL,
  `id_three` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Содержит около 10 миллионов строк. Идентификаторы в среднем столбце («id_two») могут появляться в разных строках в разное время.

Краткий пример:

id_one    id_two    id_three
1         2         3
2         2         3
3         2         1
68        98        1
1         4         3
2         4         4
4         5         33
6         5         3
90        5         3
34        5         83
9         3         98

Теперь я хочу посчитать разные идентификаторы ("id_two"), которые в этом примере:

id_two     count
2     ->  3
98    ->  1
4     ->  2
5     ->  4
3     ->  1

Как добиться этого эффективно? (Это разовая работа ...) Это первое. Второе, что мне нужно, это подсчитать, как указано выше, а затем выбрать только те идентификаторы, у которых количество больше, чем, скажем, 100.

Большое спасибо за помощь!

С уважением Aufwind

Ответы [ 6 ]

5 голосов
/ 19 апреля 2011

Основная команда для выполнения этой команды:

SELECT id_two, count(*) FROM triple GROUP BY id_two;

Вы можете сохранить это во временной таблице, если хотите…

CREATE TEMPORARY TABLE xxx SELECT id_two, count(*) AS c FROM …
SELECT * FROM xxx WHERE c > 100;

… или использовать результат во внешнем запросе…

SELECT * FROM (SELECT id_two, count(*) AS c FROM triple GROUP BY id_two) t WHERE c > 100;

… или используйте HAVING-предложение (как предложено Марком в комментариях):

SELECT id_two, count(*) AS c FROM triple GROUP BY id_two HAVING c > 100;
4 голосов
/ 19 апреля 2011
SELECT id_two, COUNT(*)
    FROM triple
    GROUP BY id_two
    HAVING COUNT(*) > 100
3 голосов
/ 19 апреля 2011

Для вопроса 1:

SELECT id_two, COUNT(1)
  FROM triple
GROUP BY id_two

Для вопроса 2:

SELECT id_two, COUNT(1)
  FROM triple
GROUP BY id_two
HAVING COUNT(1) > 100
1 голос
/ 19 апреля 2011

Для одноразовой работы с таблицей из 10 миллионов строк я бы просто полностью пропустил SQL. Попытка использовать GROUP BY может заблокировать вашу таблицу слишком долго.

SELECT id_two FROM TRIPLE INTO OUTFILE('/tmp/idtwo.txt')

В Unix-подобной системе это создаст список с двумя столбцами: количество вхождений, ID

# sort -n /tmp/idtwo.txt | uniq -c

.. если вы должны использовать GROUP BY, добавьте ORDER BY NULL в конец вашего оператора select, чтобы сэкономить время. В противном случае MySQL попытается упорядочить ваши группы на порядок по умолчанию (значение id_two).

1 голос
/ 19 апреля 2011

Для вашей «второй вещи» используйте HAVING

SELECT id_two, count(*) nb FROM triple GROUP BY id_two HAVING nb >= 100;

Поле индексации id_two должно повысить производительность.

0 голосов
/ 19 апреля 2011

Попробуйте это:

select id_two,Frequency=count(*)
from triple
group by id_two
having count(*) > 1 -- replace 1 with desired threshold
...