LINUX.ORG.RU

Два стула: процессорное время или потребление памяти?

 ,


1

1

Назрел ещё один насущный вопрос. Не знаю как у других реализаций SQL, но при использовании SQLite3 в качестве БД для сайта на PHP, мы имеем весьма скудное API, которое не позоволяет перемещаться по результатам выборки из базы, выдёргивать любые данные из любого места, да даже нельзя узнать количество строк (rows) в результате $try = $dbh->query(); выполнения запроса SQLite3! Только если выполнить отдельный COUNT(*), но это уже будет второй запрос.

Всё, что можно, это лишь вывести результат запроса. <?php while ($row = $try->fetchArray()): extract($row); unset($row); ?><?php endwhile; ?>.

Возвращаясь к выбору между нагрузкой на процессор и потребляемой php-скриптом памятью.

Самое простое, нам нужно узнать сколько «строк» (rows) мы имеем в результате выборки из базы.

Вариант 1) сделать $lines++; в цикле при выводе (но тогда нельзя будет сразу сделать постраничную навигацию, потому что количество строк требуется знать заранее).

Вариант 2) предварительно сохранить весь результат выборки в массив, таким образом php-скрипт отожрёт приличное количество памяти.

Едем дальше. Нам нужно вывести данные с учётом других таблиц, допустим вывести все статьи и комментарии к каждой статье, и здесь дилемма: как лучше, сделать один раз JOIN чтобы подключить комментарии к статьям, либо сделать цикл внутри цикла: один SELECT, чтобы вывести все статьи, а потом ещё в каждой статье делать SELECT чтобы отдельно вывести все комментарии к статье?

Много SELECT'ов мне кажется ламерским способом выводить данные на сайт. И тогда мы возвращаемся к нашему JOIN таблиц статей и комментариев.

Как вы знаете, результатом JOIN будет повторение данных в некоторых случаях:

статья 1 | комментарий 1
статья 2 | комментарий 1
статья 2 | комментарий 2

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

Что лучше, предварительно считать всё в массив на php, и это отожрёт много памяти на один запрос, либо, выполнять SELECT с JOIN'ами в цикле, но уже в самом цикле выполнять проверки которые излишне нагрузят процессор?

Кратко: много SELECT'ов внутри многих циклов ИЛИ один SELECT с JOIN'ами и одним циклом для вывода всего?

★★★★★

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

А зачем ты SQLite собственно используешь? Чем MySQL не подходит?

Только если выполнить отдельный COUNT(*), но это уже будет второй запрос.

Ну вот его и выполняй

Как вы знаете, результатом JOIN будет повторение данных в некоторых случаях:

не обязательно, смотря как запрос составишь

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

Четырёх-пяти летней давности LXF припоминается, там про эти «выборки» было всё в свете медиатек (в смысле файловых) разложено чётко.

anonymous
()

Я читал что доступ к оперативной памяти занимает около 200 тактов ЦП. Лучше, думаю её лишний раз не дергать.

Ну и конечно поставить под сомнение использование SQLite.

shooter93 ★★
()

PostgreSQL или статический сайт со сторонними комментариями.

Deleted
()

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

Hertz ★★★★★
()

массивы становятся довольно медленными когда модифицируются между вызовами

Используй для небольших наборов, а для больших: arrayobject когда есть модификация между вызовами.

Минимизируй обращения к БД и циклы - это порядочные тормоза.

Вычисления в циклах тоже еще те тормоза - оптимизируй.

Джойны тормоз, длинные поля тормоз, индексы по varchar тоже не сахар.

Недостаток памяти это глобальные переменные и модификация массивов между вызовами.

Смотри тему xdebug memory trace если осилишь конечно.

anonymous
()

Что же вы за сайт пишете, что вывод комментариев любым из этих способов стал узким местом? Мегапортал с огромной посещаемостью? Или из любви к искусству?

Кратко: много SELECT'ов внутри многих циклов ИЛИ один SELECT с JOIN'ами и одним циклом для вывода всего?

Если кратко, то из этих двух вариантов лучше второй. Каждый SELECT - это установка соединения с БД и его разрыв по завершению = накладные расходы. Кроме того, в плане скорости фильтраций и выборок SQL намного быстрее PHP, поскольку заточена на это. Не знаю, относится ли это к SQLite, но к MySQL/Maria/PG относится точно.

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

Или из любви к искусству?

хорошо, спасибо за совет, буду заниматься фильтрацией на стороне sql.

Spoofing ★★★★★
() автор топика

ITT люди, незнающие, что spoofing ебанутый.

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

Каждый SELECT - это установка соединения с БД и его разрыв по завершению = накладные расходы.

Что пул соединений для народа не доступен?

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

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

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

это можно написать руками

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

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

готового наверное нет ничего такого

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

в принципе React есть, но это усложнение

anonymous
()

А зачем тебе выводить все статьи с комментариями?

Выбирай статьи отдельным запросом. Далее наверное нужно указать и количество коментариев к статье. Для этого делай commentary_count в статье и при добавлении/удалении комментария меняй счетчик для статьи.
Когда уже юзер зашел в статью - отдельным запросом выбираешь статью, отдельным все каменты к ней

kiotoze ★★★★
()

Как вы знаете, результатом JOIN будет повторение данных в некоторых случаях:

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

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