LINUX.ORG.RU

Баллада о двух стульях: выборка из SQL БД

 


0

2

Допустим, имеем классический блог: статьи, комментарии.

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

Открываем статью, необходимо сделать выборку и статьи, и комментариев к ней.

Вариант первый, — сделать один запрос чтобы достать статью, затем второй запрос, чтобы достать все комментарии к ней.

Вариант второй, — один запрос, в котором мы достаём статью и тут-же JOIN'им таблицу с комментариями к ней, затем, при выводе данных на страницу, уже должен скрипт сам в цикле пройтись по результату, и отобразить статью один раз, а оставшиеся комментарии в остатке.

Как лучше? Два SQL-запроса против одного с JOIN.

Добавим к этому ещё одну таблицу загруженных картинок к постам и комментариям. При открытии статьи уже придётся делать либо три запроса, либо один запрос с JOIN'ом двух таблиц.

Таблица с загруженными картинкам относится к комментариям тоже, представьте, обсуждение на 1000 комментариев: не делать же на каждый комментарий целый SQL-запрос, чтобы выбрать все картинки к нему, ага? То есть, вариант остаётся только один: JOIN'ить все три таблицы, затем одним циклом распределять все данные между тремя различными массивами (статья, комментарии, картинки), и уже затем только выводить данные из этих циклов, после обработки.

Имеются ли ещё какие-то варианты?

Стоит ли беспокоиться о расходуемой скриптом памяти? Статья, 1000 комментариев, по 10 картинок к каждому. Вместо того, чтобы плавно обращаться к БД и тут-же выводить данные, все эти данные будут предварительно записаны в массивы, пусть и на короткое время, но всё же памяти они съедят прилично, не так ли?

Вот и не знаю как поступить.

В любом случае, запросов к БД необходимо делать как можно меньше, а вся работа должна ложиться на скрипт, в котором первым циклом мы только достаём данные из БД и разносим их по разным массивам, и только потом выводим, уже из этих массов. Так?

★★★★★

google://преждевременная оптимизация

Когда у тебя начнёт тормозить из-за двух запросов, тогда и думай.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)

Смотри. Если у тебя название и комменты выводятся сразу на одной странице (допустим, на странице сайта), то имеет смысл не лезть два раза в одну БД - дерни одним запросом, потому что каждый запрос будет содержать в себе время на подключение к БД.

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

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

В любом случае, помни, что для запроса нужно еще время подключение к СУБД.

bvn13 ★★★★★
()

2 запроса. Комменты запрашивать пачками из бд, если их много.

pi11 ★★★★★
()
Последнее исправление: pi11 (всего исправлений: 1)

Скул всегда был вот таким вот стейтлесс говном, когда нельзя часть прошлой выборки оставить как ресурс. По идее надо выбрать посты, оставив их айдишники там, потом выбрать комменты этих постов, оставив айдишники их картинок там, потом выбрать картинки. А не выкачивать джойны повторяющихся данных или пустых полей в случае аутера (или вообще по-идиотски гонять части выборок туда-обратно, что тебе тут и предложат в общем случае). /рант

arturpub ★★
()

а зачем коменты и статьи лежат в разных таблицах ? по идее сущность одна и та-же - просто разные позиции в древовидном представлении.

и зачем сразу дёргать картинки к статьям и коментам ? броузер всё-одно отдельно за ними потянется и будет запрос.

Статья, 1000 комментариев, по 10 картинок к каждому.

статья - 100к html, и ещё 1к коментов по 1к в среднем и 10 url << 2 мега. тут думать надо не о том как из sql выдернуть; а как быстро нарисовать на клиенте, чтоб он статью увидел сразу, а на подгрузку картинок/коментов не обращал внимания.

MKuznetsov ★★★★★
()

Как лучше? Два SQL-запроса против одного с JOIN.

Научись пользоваться связями и индексами, в частности, внешними ключами, чтобы у тебя больше не возникало этих вопросов. После этого научись пользоваться эксплейном или что там в твоей БД, и сравни результаты сам. И тогда ты

Вот и не знаю как поступить.

Узнаешь как поступить.

znenyegvkby
()

т.к. текст статьи скорее всего меняется редко то есть вариант хранить его в кэше

exception13 ★★★★★
()
Ответ на: комментарий от arturpub

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

Взоржал.

cnupm
()

Спуф, не позорься.

Сначала терминология:

Есть скулевый запрос, а есть запрос клиентский к серверу.

Есть транзакция ака любое кол-во клиентских (не скулевых, а клиентских) запросов в серверу бд, где ты делаешь ей бегин и коммит/роллбек.

Есть транзакция ака несколько скулевых запросов в одном клиентском запросе к серверу бд.

Т.е. внутри одного клиентского запроса может быть один и более скулевых запросов. Результаты выборок придут в ответ для всех отправленных скулевых запросов.

Некоторые клиенты или драйверы или либы для работы с той или иной базой не умеют множественные скулевые запросы. А если умеют, то у них есть соответствующие методы для перехода к сл выборке, а затем фетча результатов из неё. Иди читай доки к этим либам.

Теперь про джойны:

То что ты предлагаешь, это писец. Если у тебя статья размером с войну и мир, эта война и мир приджойнится к каждому комментарию. И, ты упрешься в максимальный размер тела ответа указанного в конфиге сервера бд. Да даже если и не упрешься — яичницу ты пожаришь знатно.

deep-purple ★★★★★
()

Очередная спецолимпиада, наконец-то.

Deleted
()

С такой нагрузкой, как у твоего блога, можешь хоть сто запросов делать.

Ghostwolf ★★★★★
()
Ответ на: комментарий от deep-purple

Может ему вообще подумывать о документных бд? Ну статья, ну коменты. Каждая статья суть набор текста статьи и коментов. Получается один уникальный документ с вложениями.

bookman900 ★★★★★
()

Боги, не надо никаких join, тащи в рамках одной транзакции и всё

OldWiseCat ★★
()
Ответ на: комментарий от dk-

Он тебе со своим скиллом-то понапишет, сто лет не разгребешь. Ему б джуном в команду толковую, да поучиться

OldWiseCat ★★
()
Ответ на: комментарий от MKuznetsov

а зачем коменты и статьи лежат в разных таблицах ? по идее сущность одна и та-же

Плюсанул. Статьи - посты без родителя. Комменты - посты с родителями. Можно хоть по дате сортировать, хоть в виде дерева рисовать (можно с фильтром по глубине). Заодно можно извлечь ветку обсуждения (и, например, показать ее отдельно).

anonymous
()
Ответ на: комментарий от anonymous

а мне казалось, что такие вещи называются «семантикой» и должны быть разделены.. и не суть важно, что суть одно и тоже.

ладно, буду делать всё вместе.

Spoofing ★★★★★
() автор топика
Ответ на: комментарий от Spoofing

Разделить лучше. С точки зрения оптимизации (ведь это тебя интересует): статьи я предполагаю у тебя в среднем длиннее комментов. Значит эффективнее их хранить в отдельной таблице с соответствующими столбцами (например статьи с text, комменты с varchar(500)).

На счет 3-х запросов - Выборка статьи по уникальному ключу - это очень быстрая операция. Выборка комментов - тоже относительно быстрая операция, но если эта же таблица будет еще содержать и статьи - скорость будет ниже, и тем ниже чем больше статей и больше их размер.

pi11 ★★★★★
()
Ответ на: комментарий от Spoofing

«семантикой» и должны быть разделены
суть одно и тоже

/0

должны быть разделены

Зависит. Часто на комментарии накладываются ограничения, которых нет у статей (ну или у статей должно быть больше возможностей). Например, давать тэги комментариям скорее всего не нужно. Но в твоем случае не вижу причин их разделять. Вообще, то говно, что ты пилишь, хорошо ложится на документные БД, но в твоем случае оно такое примитивное, что лучше юзать стандартный SQL, с которого соскочить на документную БД проще, чем обратно.

anonymous
()
Ответ на: комментарий от pi11

статьи я предполагаю у тебя в среднем длиннее комментов

Ты пишешь это человеку, у которого на хабре комментарии к его статье были полезнее самой статьи Пусть делает наоборот, статья varchar(500), комментарий text.

anonymous
()
Ответ на: комментарий от pi11

Вот зачем

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

anonymous
()

Борду что-ли пилишь? Ну сделай одну таблицу: Id(long), message(text), image_url(text), op-post (bool), id_op (int) Выборку делаешь с лимитом (если надо). Индексы в mysql будут работать всяко побыстрее твоего говноскрипта на php, даже если ты будешь связывать несколько таблиц. Ты не правильно думаешь, что пых работает быстрее mysql. Если против, давай, тащи тестовый код, который доказывает, что это так.

crutch_master ★★★★★
()

Давай, пили тестовый блог, заливай на github. Забъём 100к рандомных записей, да будем мериться у кого быстрее код. Веселуха будет.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.