LINUX.ORG.RU

Оптимизация запросов к БД. Чисто вопрос проектирования и «всего такого»


0

0

Пишу небольшой аналог АИБ(Анонимной Имидж Борды). Чисто для опыта, не более.
На сколько все знают, в режиме просмотра раздела видны по 3 сообщения для каждого треда:
1) оп-пост
2,3) последние посты
Проблема проста как 2 пальца:
Если не использовать пререндер страниц(как сделано в вакабе и других АИБ), то получается что при маппинге с Foreign Key Message -> Thread нужно на один рендер использовать 1+N запросов, а то и 1+N*2(N - количество тредов на странице).
1) запрос информации по тредам
N) запросы на сообщения для каждого треда
/
N1) запросы на оп-посты
N2) запросы на последние сообщения треда

Вот сижу и думаю как делают это человеки. Кешинг понятно, но на таком уровне нужно ведь делать оптимизацию? Или кешинга хватит?
Через ab прошёлся и увидел что разница количества запросов(скорости) аж в 2!!! раза.

Какая мысль:
Завести в таблице тредов ещё 3 набора полей для оп-поста и для последних 2х сообщений, но мне кажется это быдло-метод.

Что посоветуете?


Если что-то рассказал запутанно, то могу проще.

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

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

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

В таком случае попробуй попроще :)

bibi
()

memcached спасёт отца русских имиджборд

pained
()

Ничё не понял, что ты написал, но скажу, что «преждевременная оптимизация - корень всех бед». Так-то!

anonymous
()

>Завести в таблице тредов ещё 3 набора полей для оп-поста и для последних 2х сообщений, но мне кажется это быдло-метод.

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

Наверное стоит делать не в таблице тредов, а в отдельной, чтобы просто изменить таблицу при изменении числа выводимых тредов.

anonymous
()

Заранее реши сколько запросов в секунду должно держать приложения и уже от этого отталкивайся.

Даже если разница в скорости в два раза это не повод нервничать если всё равно тачка способна выполнять тысячи таких запросов в секунду.

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

true_admin ★★★★★
()

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

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

Проблема в том что я хочу максимально оптимизировать приложение. Я слышал о всяких 4chan'ах, которые держат огромное количество клиентов. Я понимаю что если у меня будет как сейчас, т.е. 1+N запросов, то меня даже ферма не спасёт.

memcached спасёт отца русских имиджборд

Это конечно хорошо, но хочется иметь оптимизацию на уровне логики.

Ничё не понял, что ты написал, но скажу, что «преждевременная оптимизация - корень всех бед».

Да, но здесь оптимизация скорее запоздалая ибо я сначала не обращал внимания на количество запросов в данном приложении. Надеялся что ORM быстро со всем справится. Но нет.
Как я испугался когда для одного рендера было больше сотни запросов...

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

Вот спасибо за такие комменты. Хоть это тоже своеобразный кеш, но всё-же так легче.

Наверное стоит делать не в таблице тредов, а в отдельной, чтобы просто изменить таблицу при изменении числа выводимых тредов.

Да, я тогда думаю сделать одну таблицу тредов, в которой будет первое сообщение и таблицу для последних двух сообщений. При этом, при каждом создании сообщения обновлять таблицу последних сообщений.
Хотя сейчас задумался над использованием memcached для последних двух сообщений. При этом придётся обновлять объект при каждом новом сообщении.

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

А зачем ваять? Юзай ab и всякие онлайновые тесты вроде лоад импакт. В большинстве случаев этого хватает.

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

в задачу не совсем въехал, но:

может попробовать использовать конструкцию union

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

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

Не катит. Тестовых утилит может быть чертова куча, но 99% из них работает по принципу «больше пользователей - больше нагрузка». А потом приложение падает на 3х пользователях, потому что в каком-то месте слишком много данных оказалось допустим в сгенеренной таблице.

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

Если у тебя на рендеринг уходит больше 100 запросов в бд то стопудов надо что-то менять...

А так смотрел я смотрел бенчи вот сдесь: http://django-treebeard.googlecode.com/svn/docs/index.html#tbbench-lies-damn-...

Вполне нормальный перфоманс даже с many-to-many :).

true_admin ★★★★★
()

А если попробывать сделать функции в самой БД.
Допустим есть таблица со списком тем и есть таблица со список сообщений этой темы. Описываем в самой БД функцию которая при запросе темы возвразает еще от 0 до 2 строк из таблицы с соббщениями.

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

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

Кратко говоря:
Есть таблица Threads. Есть таблица Messages.
На одной странице нужно вывести список из 30 тредов с их последними 2мя сообщениями.
В результате получается что мы должны отправить 31 запрос:
- 1 запрос на треды
- 30 запросов - по 1му запросу на тред для получения сообщений из таблицы сообщений

Получается не очень хорошо. В том и проблема. Как лучше и куда лучше отправлять сообщения для кешинга? БД ключ-значение или дополнительные поля в таблице тредов?

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

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

Если у тебя на рендеринг уходит больше 100 запросов в бд то стопудов надо что-то менять...

Именно для этих целей и создал тред.

Не катит. Тестовых утилит может быть чертова куча, но 99% из них работает по принципу «больше пользователей - больше нагрузка». А потом приложение падает на 3х пользователях, потому что в каком-то месте слишком много данных оказалось допустим в сгенеренной таблице.


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

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

Я бы попробовал так и посмотрел производительность:

В messages дополнительно поле LastPost. При добавлении нового поста у всех остальных это поле нужно установить в 0, у двух последних в 1 (это примерно +2 запроса)

При просмотре тогда нужен всего 1 запрос:

SELECT ... FROM threads
LEFT JOIN messages ON (threads.IdThread = messages.IdThread AND messages.LastPost = 1)
WHERE ...
ORDER BY threads.IdThread,...
LIMIT 60

Не забудь составной индекс (IdTread, LastPost) в messages

Минусы:
- больше нагрузка на БД при добавлении поста
- нужна фильтрация выборки результатов запроса в коде, потому что, например, если в каком-то треде 0 постов, в выборку попадет 31-ый тред с одним сообщением

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

Спасибо за совет. С таким полем оно будет работать суммарно быстрее чем без него, конечно. Но прирост производительности не будет столь велик как хотелось бы.
Уже прикрутил PyTyrande(на Tokyo Cabinet) и вроде оно работает. Пока не дописал, но как допишу - проверю через тот-же ab.
Скорее всего сделаю проще:
В треде сделаю 1 набор полей для ОП-поста(чтобы не дёргать кеш и бд если потребуется только первое сообщение) + 2 поля для индекса последних двух сообщений(чтобы и при перезаписи кеша всё работало быстро).

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

Я спрашиваю как сделать определённую вещь.
Если бы я спросил «как поставить свои имиджборду с блек-джеком и шлюхами», то данный ответ можно было бы использовать. И то этой был бы троллинг.
На сколько я помню, в вакабе используется полный пререндер страниц. Оно не нужно ибо является своеобразной заменой системы кеша.
Могу ли я сделать из этого вывод что вы советуете мне использовать систему кеша или полный пререндер? Иначе мне не понятно что вы тем хотели сказать.

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

Я советую ровно то, что написано. Почитать сорцы и посмотреть как там сделана выборка.

и кстати

в режиме просмотра раздела видны по 3 сообщения для каждого треда

это не так

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

>это не так
Следовало бы поправить а не просто говорить что я не прав.
Да, на 4чане их 6. А я хочу 3.

Почитать сорцы и посмотреть как там сделана выборка.

Там, если не ошибаюсь, пределывается страница. Тупо. В любом случае - гляну. Но я ожидал что будет более подробный совет.

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

>Следовало бы поправить а не просто говорить что я не прав.

Да, на 4чане их 6. А я хочу 3.

ок. поправляю. там это настраивается.

iSage ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.