
lost
17.07.2017
11:55:10
не пишите в мускуле кореллированные подзапросы, если в этом нет острой необходимости

Ринат
17.07.2017
11:55:13
ну ты сам написал

lost
17.07.2017
11:55:19
почти все можно через join сделать

Ринат
17.07.2017
11:55:20
сджойнить

Google

Fike
17.07.2017
11:57:16
ну и вот получаются твои посты
после группировки получается нематериализованная сущность "посты с количеством ссылок"

Ринат
17.07.2017
11:58:53
SELECT count(l.id) as cnt, p.name FROM post p
INNER JOIN link l ON p.post_id = l.post_id AND p.author_id = l.author_id
WHERE p.forum_number = 36
GROUP BY p.name
HAVING cnt > 10
ORDER BY p.updated_at DESC
LIMIT 80;
как то так?

Fike
17.07.2017
12:01:15
я думаю, группировать стоит все-таки по айдишнику

Ринат
17.07.2017
12:02:18
а ну да, точно
ну а так - в целом это имелось ввиду?

Alexey
17.07.2017
13:57:07
но вопросы про правильность запроса лучше начинать с вывода EXPLAIN. сам не скажешь — тут же никто и не спросит ;)

Ринат
17.07.2017
14:00:50
тоесть не только один p.name
но и l.url
первый

Google

Alexey
17.07.2017
14:05:47
нет, ну если внезапно нужна ещё и первая ссылка из другой таблицы, то да, таки join. ты ж нигде до этого не говорил

Ринат
17.07.2017
14:07:40
ну джоин то есть
один чёрт придётся в select писать select ?

lost
17.07.2017
14:11:17
просто в свой запрос добавь substring_index(group_concat(l.url SEPARATOR '|'), '|', 1)
что-то типа такого
если тебе первый урл нужен из всего списка

Ринат
17.07.2017
14:12:38
ну первый урл у каждого поста

lost
17.07.2017
14:13:00
а первый по какому критерию? по дате?

Ринат
17.07.2017
14:13:24
там в таблице link есть поле, start_post
тоесть по этому маркеру
вполне

lost
17.07.2017
14:13:53
тогда добавить внутрь group_concat order by

Ринат
17.07.2017
14:14:44
или для оптимизации?
есть пост
к нему есть куча ссылок

lost
17.07.2017
14:15:16
скорее asc

Ринат
17.07.2017
14:15:21
и только одна там со start_post = 1

lost
17.07.2017
14:15:43
тогда можно упростить

Google

lost
17.07.2017
14:15:52
если у тебя всегда одна запись с флагом 1

Ринат
17.07.2017
14:15:54
да всегда
хотя
блин-всё же есть что не всегда.

lost
17.07.2017
14:16:53
тогда тот вариант тебе подходит

Ринат
17.07.2017
14:16:54
лучше оставить как есть? с group_concat

Fike
17.07.2017
14:17:35
а оно так не имеет права вытащить запись с любым start_post?

Ринат
17.07.2017
14:18:23
тоесть как то ограничить чтобы из start_post ов в случае если больше одного-брал первый?

lost
17.07.2017
14:18:47
substring_index для этого там и стоит

Fike
17.07.2017
14:19:29
он же при простом джойне имеет право в любом порядке их вывести

Ринат
17.07.2017
14:19:51
хм

lost
17.07.2017
14:19:57
на момент когда я написал ему кусок кода я не знал по какмоу принципу ему нужен первый урл
не вводи человека в заблуждение

Ринат
17.07.2017
14:20:17
SUBSTRING_INDEX(group_concat(l.url SEPARATOR '|'), '|', 1)
где тут правильно добавить тогда чтобы из start_post первый брал?
если вдруг больше одного будет

lost
17.07.2017
14:20:59
SUBSTRING_INDEX(group_concat(l.url SEPARATOR '|' ORDER BY start_post DESC), '|', 1)
он в любом случае возьмет один урл, посмотри в документации что делают функции

Ринат
17.07.2017
14:22:00
первая знаю что

Google

Ринат
17.07.2017
14:22:14
ты уже как то мне кидал её, я с помощью неё там лог разспарсивать начал

lost
17.07.2017
14:22:59
на что ругается? я могу перепутать местами separator и order by, не помню так на вскидку их порядок следования

Fike
17.07.2017
14:24:05

Ринат
17.07.2017
14:24:33

lost
17.07.2017
14:25:27
внутри group_concat... скинь целиком запрос

Fike
17.07.2017
14:25:50
попробуй указать separator после выражения с order by

lost
17.07.2017
14:26:11
и должно взлететь

Ринат
17.07.2017
14:27:35
SELECT count(l.id) as cnt, p.name, SUBSTRING_INDEX(group_concat(l.url SEPARATOR '|' ORDER BY l.start_post DESC), '|', 1) FROM post p
INNER JOIN link l ON p.post_id = l.post_id AND p.author_id = l.author_id
WHERE p.forum_number = 36
GROUP BY p.id
HAVING cnt > 10
ORDER BY p.updated_at DESC
LIMIT 80;

lost
17.07.2017
14:28:06
махни местами separator и order by

Ринат
17.07.2017
14:28:53
ORDER BY l.start_post DESC '|' l.url SEPARATOR
так?
делал, то же самое

Fike
17.07.2017
14:30:15
group_concat(l.url ORDER BY l.start_post DESC SEPARATOR '|' )
https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function%5Fgroup-concat

Ринат
17.07.2017
14:31:00
Спасибо
а вот все эти фунции
они на быстродействии сильно отражаются?

Google

Ринат
17.07.2017
14:32:27
например грубо говоря-у поста будет 500 ссылок

lost
17.07.2017
14:32:29

Ринат
17.07.2017
14:32:32
хотя start_post отсекает

lost
17.07.2017
14:32:42

Ринат
17.07.2017
14:32:45
и там больше 10-20 не будет, и то редко

lost
17.07.2017
14:34:22
мы кстати вроде как даже эту хрень обсуждали уже

Fike
17.07.2017
14:34:30
они на быстродействии сильно отражаются?
Тебя в первую очередь должно волновать количество джойнов и сложность группировок. Но это все будет шустро работать, пока ты проставляешь в БД необходимые для этого индексы. Дальше уже с эксплейном работать.

lost
17.07.2017
14:34:31
но это не точно

Ринат
17.07.2017
14:34:55
сейчас проверяю выборку

Fike
17.07.2017
14:35:10
Когда тебя это начнет серьезно напрягать, ты просто можешь сделать еще два поля для постов, в котором держать количество ссылок и необходимую ссылку - вуаля, никаких джойнов и группировок

Ринат
17.07.2017
14:35:19
чото есть накладки, посмотрю пока

Fike
17.07.2017
14:35:38
Но это все денормализация и туда лучше не лезть, пока нет необходимости и все бегает на индексах.

lost
17.07.2017
14:36:28
там есть много всяких нюансов вроде порядка объединения таблиц, используемых индексов при объединении и так далее

Ринат
17.07.2017
14:39:12
кое что денормализовал заранее
как писать автора поста и автора ссылки
или к какой категории они относятся
чтобы иной раз просто не делать join и не лезть лишний раз

Evgeny
18.07.2017
09:43:35
Господа, в продакшене база работает раза в 2 медленее чем стейдж под той же нагрузкой, подскажите как лучше помониторить