Оптимизация запросов для следующего и предыдущего элемента - PullRequest
28 голосов
/ 22 февраля 2010

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

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

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

alt text
(источник: pekkagaiser.com )

Очевидно, что кнопка «Далее» для «Помидоров, класс I» должна быть «Яблоки, класс 1» в первом примере, «Груши, класс I» во втором и ни одной в третьем.

Задача в подробном представлении - , чтобы определить следующий и предыдущий элементы без выполнения запроса каждый раз , с порядком сортировки списка в качестве единственной доступной информации (скажем, мы получаем это через Получите параметр ?sort=offeroftheweek_price и проигнорируйте последствия для безопасности).

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

Мой текущий подход в моей CMS использует то, что я назвал «сортировочный кеш». Когда список загружен, я сохраняю позиции элементов в записях в таблице с именем sortingcache.

name (VARCHAR)             items (TEXT)

offeroftheweek_unsorted    Lettuce; Tomatoes; Apples I; Apples II; Pears
offeroftheweek_price       Tomatoes;Pears;Apples I; Apples II; Lettuce
offeroftheweek_class_asc   Apples II;Lettuce;Apples;Pears;Tomatoes

очевидно, столбец items действительно заполнен числовыми идентификаторами.

На странице сведений я теперь получаю доступ к соответствующей записи sortingcache, извлекаю столбец items, анализирую его, ищу идентификатор текущего элемента и возвращаю предыдущего и следующего соседа.

array("current"   => "Tomatoes",
      "next"      => "Pears",
      "previous"  => null
      );

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

Мои вопросы:

  • Как вы думаете, является ли хорошей практикой поиск соседних записей для различных порядков запросов?

  • Знаете ли вы лучшие практики с точки зрения производительности и простоты? Знаете ли вы что-то, что делает это полностью устаревшим?

  • В теории программирования есть имя для этой проблемы?

  • Подходит ли и понятно ли название "Кэш сортировки" для этой техники?

  • Существуют ли какие-либо общепринятые модели для решения этой проблемы? Как они называются?

Примечание: Мой вопрос не о построении списка и не о том, как отобразить подробный вид. Это всего лишь примеры. Мой вопрос - базовая функциональность определения соседей записи, когда повторный запрос невозможен, и самый быстрый и дешевый способ туда добраться.

Если что-то неясно, пожалуйста, оставьте комментарий, и я уточню.

Начало награды - может быть, есть еще какая-то информация об этом там.

Ответы [ 11 ]

0 голосов
/ 22 февраля 2010

Итак, у вас есть две задачи:

  1. создать отсортированный список элементов (ВЫБЕРИТЕ с разными ORDER BY)
  2. показать детали о каждом элементе (ВЫБРАТЬ детали из базы данных с возможным кэшированием).

В чем проблема?

PS: если упорядоченный список может быть слишком большим, вам просто нужно реализовать функциональность PAGER. Могут быть разные реализации, например Вы можете добавить «LIMIT 5» в запрос и предоставить кнопку «Показать следующие 5». Когда эта кнопка нажата, добавляется условие типа «ГДЕ цена <0.89 LIMIT 5». </p>

...