Вывожу через View статьи (постраничный вывод, на одной странице 20 статей). При малом количестве статей все нормально, но решил проверить как отразится на производительности большое количество статей.
Для эксперимента забил через скрипт в базу 1КК статей и попробовал отобразить первую страницу.... Как же долго я ждал
Я конечно понимаю, что ему нужно выполнить SELECT COUNT(*) FROM QUERY для того, чтобы показать общее количество статей и построить правильную ссылку на последнюю страницу. Но мне не нужна ссылка на 15267 страницу.
Простой выход из данной ситуации я увидел в том, что можно просто вывести 20 статей на странице(не подсчитывая COUNT(*)) и показать ссылку на следующие 20. Вроде в настройках view это можно настроить (Mini Pager), вот только эффекта от этого нет (видимо он все равно подсчитывает COUNT(*)).
Если показывать первые 20 записей без pager'a - то все работает моментально.
Поэтому вопрос - как можно быстро показать первые 20,50,100 записей (не подсчитывая общее количество), но показать ссылки на следующие/предыдущие страницы?
Или придется писать самому с помощью модуля?
ЗЫ:
СУБД - PostgreSQL 9.0
Drupal 7 dev
Комментарии
А зачем нужен вот такой индекс(друпаловцы зачем то создали)???
ON node
USING btree
(title, substr(TYPE::text, 1, 4));
Зачем обрезать тип?
Разве используются такие запросы -
SELECT * FROM node WHERE title = 'blablabla' AND substr(TYPE, 1, 4) = 'обре'
?И почему нет такого индекса:
ON node
USING btree
(title varchar_pattern_ops);
Неужели никто не пользуется запросами вида
SELECT * FROM node WHERE title LIKE 'blablabla%'
?Или нужно сразу переходить на Sphinx или аналогичное(в этой области не силен, пока только краем уха слышал)?
Не факт, что тормозит именно эта операция. Если выполнить в консоли, тоже долго ждать?
Для поиска используются отдельные модули со своими таблицами, ибо поиск LIKE '%text%' очень неэффективен и может положить любой сервер.
Это я - mutuz.
Именно она. А что еще может тормозить? Я конечно всех внутренностей друпала не знаю, но из-за чего тогда могут возникнуть тормоза при выводе нумерации страниц, как не из-за подсчета COUNT(*)?.
Речь шла о запросе вида
LIKE 'foo%'
, c '%foo%' понятно - индексы тут не помогут.А теперь по поводу тормозов.
View сгенерировал следующий запрос:
SELECT ... FROM ... WHERE (( (node.type IN ('content_type')) )) LIMIT 10 OFFSET 0
Результаты:
Query build time 2.88 ms
Query execute time 3090.98 ms
View render time 87.07 ms
Результат выполнения сгенерированного запроса(скопировал и выполнил сам):
'Total runtime: 0.678 ms'
Как-то не увязывается с Query execute time 3090.98 ms.
Результат выполнения запроса
SELECT COUNT(*) FROM (SELECT ... FROM ... WHERE node.type = 'content_type') AS foo
:3188 ms. - А вот это видимо оно.
И еще заметил неприятную особенность View - при пустых полях фильтра, View генерирует запросы вида
filter_field ILIKE %% ESCAPE '\\'
.Ну зачем так? Почему нельзя просто выкинуть это поле из запроса, раз оно не заполнено. Можно это исправить?
Или лучше для больших наборов данных view не использовать и писать все самому?
Установи devel и просмотри все запросы, которые выполняет друпал.
Devel уже установлен. COUNT(*) вычисляется 100%. Или Вы знаете другой способ вычисления количества страниц?
Только вопрос был - можно ли стандартными средствами view вывести данные без вычисления COUNT(*)?
Как меня devel спасет? Мне нужно вывести первые 10/20/50 записей и стрелочки (<, >) для перехода на следующие или предыдущие 10/20/50 записей.
Или так нельзя и нужно самому писать?
Посмотри hook_views_query_alter($view,$query) -- http://views.doc.logrus.com/group__views__hooks.html
В этом хуке можно изменить сформированные запросы. Вот только не помню есть ли там запрос на количество.