Подсчёт уникальных элементов sql vs php

12
nocomments
На сайте с 12.11.2009
Offline
189
2171

Считаю количество уникальных элементов в столбце, таблица - несколько сот тысяч строк.

Попробовал 2 варианта:

1) SELECT * FROM.., потом вынимаем поштучно, добавляем то что нужно посчитать в строку, сравниваем через strstr, если в строке нет - увеличваем счётчик.

2) SELECT DISTINCT `столбец` FROM.., и получаем значение через mysql_num_rows

Вроде бы второй вариант красивее, но первый обходится почти в три раза быстрее, результат одинаковый.

Возможно чтото делаю не так. Чтото с логикой не так. Подскажите почему плз.

Это счастливая рефка: {жать сюда} (http://bit.ly/WbMR4O) тому, кто по ней разместит больше всего статей, будет сопутствовать счастье всю его оставшуюся, длинную, обеспеченную жизнь.
X
На сайте с 01.10.2009
Offline
13
#1

Можно сделать так


SELECT
COUNT(*) as `C`
FROM
(
SELECT
COUNT(*)
FROM
`message`
GROUP BY
`from`
) as `Cnt`

message - ваша таблица, from - уникальные элементы.

7port.com (http://7port.com) - сайт для работы с базой данных
Master812
На сайте с 23.12.2007
Offline
168
#2

nocomments, это вы для чего подсчет используете? У вас какой скрипт: блог, форум, авторизация на сайте? В таких случаях лучше всего счетчик использовать в виде обычного текстовго файла, в котором будет записано кол-во данных в таблице, чтобы каждый раз при обращении к скприту их не пришлось подсчитывать заново.

ИМХО

raspberry pi сайт ( https://4raspberrypi.ru/ ) и orange pi сайт ( https://orangepi.su/ ) и новостной движок ( https://generalscript.ru/ )
nocomments
На сайте с 12.11.2009
Offline
189
#3

Это рейтинги посещаемости, подсчёт уникальных ip, от текстовых файлов для этого уже ушёл, в данном случае база предоставляет высокий уровень экономии.

Xoce, спасибо, результат получается тот верный, но это ещё дольше, ваш вариант 0.2240 сек., DISTINCT/num_rows 0.0007 сек. Вопрос в том, почему php эту операцию обрабатывает в три раза быстрее чем DISTINCT.

X
На сайте с 01.10.2009
Offline
13
#4

я не в курсе как там скуэл работает внутри конкретно вашей бд. Но могу послветовать добавить индекс на целевое поле, ну и мой запрос можно избавить от лишнего count()


SELECT
COUNT(*) as `C`
FROM
(
SELECT
`from`
FROM
`message`
GROUP BY
`from`
) as `Cnt`
T.R.O.N
На сайте с 18.05.2004
Offline
314
#5
nocomments:
Это рейтинги посещаемости, подсчёт уникальных ip, от текстовых файлов для этого уже ушёл, в данном случае база предоставляет высокий уровень экономии.

ну это дело вкуса конечно. Но, для самой задачи, я-бы использовал иное решение:

1. IP стоит хранить в естественном виде (это всего 4 байта) - поиск идет значительно быстрее.

2. Для расчета удобней иметь просто лог-файл/бд, куда данные записываются просто последовательно.

3. Каждые Х минут/часов лог обрабатывается и заносится в основную базу в обработанном виде. Результат счетчика, соответственно, корректируется.

В любом случае - уходите от текстового поиска и разделите (во времени) сложную задачу на несколько мелки и быстрых.

От воздержания пока никто не умер. Хотя никто и не родился! Prototype.js был написан теми, кто не знает JavaScript, для тех, кто не знает JavaScript (Richard Cornford)
nocomments
На сайте с 12.11.2009
Offline
189
#6
T.R.O.N:
IP стоит хранить в естественном виде (это всего 4 байта)

вот это даже не подумал. нужно покопать в этом направлении. спасибо!

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

nocomments добавил 30.11.2010 в 20:19

T.R.O.N:
Каждые Х минут/часов лог обрабатывается и заносится в основную базу в обработанном виде

Вот это как раз такая обработка, просто исходные данные сразу в базе удобнее

Dreammaker
На сайте с 20.04.2006
Offline
569
#7

nocomments, то есть, вам нужна, так сказать, точная точность до уника?

Вообще-то, T.R.O.N, правильный подход описал - пересчитывать накопившиеся данные.

nocomments
На сайте с 12.11.2009
Offline
189
#8

Dreammaker, об этом пересчёте и идёт речь. При количестве урлов около 20 000 и количестве записей 150 000 обработка через выбоку SELECT DISTINCT идёт 10 минут. Простым перебором всех 150 тысяч - 3-4 минуты.

LEOnidUKG
На сайте с 25.11.2006
Offline
1774
#9
nocomments:
Dreammaker, об этом пересчёте и идёт речь. При количестве урлов около 20 000 и количестве записей 150 000 обработка через выбоку SELECT DISTINCT идёт 10 минут. Простым перебором всех 150 тысяч - 3-4 минуты.

Ну значит оставляйте первый вариант :)

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
Dreammaker
На сайте с 20.04.2006
Offline
569
#10

nocomments, где-то значит, что-то не так с индексами. Скиньте мне в личку структуру таблицы и что нужно посчитать - я прикину, что можно улучшить.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий