Как эффективно определить наиболее популярные строки в большой таблице? - PullRequest
2 голосов
/ 08 июля 2011

Если предположить таблицу из 50 миллионов фамилий (например), как эффективно определить первые 10000?

Есть ли более эффективный запрос, чем этот?

SELECT count(last_name) as cnt, last_name
FROM last_name_table
GROUP BY last_name
ORDER BY cnt DESC
LIMIT 10000;

Предполагая, что:

CREATE TABLE last_name_table (
    `last_name` VARCHAR(255), 
     KEY `last_name` (`last_name`)
);

Я могу получить топ-1000 за 20 минут. Но топ 10000 занимает весь день (буквально). Есть предложения?

Ответы [ 4 ]

2 голосов
/ 08 июля 2011

Как эффективно определить наиболее популярные строки в большой таблице?

В соответствии с вашим вопросом, я предполагаю, что вам не нужны точные цифры, и приблизительных чисел будет достаточно.

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

2 голосов
/ 08 июля 2011

Предложение: предварительно рассчитать счет каждого last_name и сохранить его в отдельной таблице.

Поддерживайте его с помощью триггеров (если в last_name_table нет тысяч вставок в минуту, или если статистика в реальном времени имеет смысл) или планировщиком один раз в день (час и т. Д.) В противном случае.

0 голосов
/ 08 июля 2011

Если вы добавите пункт «HAVING count (last_name)> 10» или что-то в этом роде, то он исключит все необычные элементы из ваших результатов. Делая это таким образом, вам не понадобится «LIMIT» или «order by». Это может ускорить процесс. Кроме того, если вы индексируете cnt с полем last_name, индекс может повысить производительность.

0 голосов
/ 08 июля 2011

Для SQL92 определен оператор «TOP», поэтому в базе данных, совместимой с SQL92, вы должны иметь возможность писать
SELECT TOP 10000 ... FROM last_name_table;

Однако MySQL не реализовал это, и вы должны использовать LIMIT согласно вашему собственному предложению.

...