Intereting Posts
Форма Symfony2 – от многих до многих, поскольку текст вызывает ошибки используя preg_replace для замены <br /> Успех jQuery $ .ajax выполняется только один раз Фильтрация сообщений по тегу на странице Tumblr? PHP Перемещение файла сопоставления конфигурации в XML, но как создать динамический XPATH PHP: отдельное значение в массиве в соответствии с порядком алфавита PHP pthread не кажется многопоточным Проверка множественной загрузки файлов Laravel Пользовательские проверки номеров телефонов в Laravel 4.2 Оптимизация запросов для следующего и предыдущего элементов Результат разбиения на страницы Yii с использованием CSqlDataProvider Почему этот вызов PHP для json_encode бесшумно терпит неудачу – неспособность обрабатывать одиночные кавычки? Как реализовать Redis в CodeIgniter? Способ определения ширины браузера в PHP без javascript? PHP 7 RC3: Как установить отсутствующий MySQL PDO

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

В моем приложении PHP у меня есть таблица статей mysql, которая имеет следующие столбцы:

article_id articletext category_id score 

Каждая статья имеет оценку, которая рассчитывается на основе того, насколько она популярна и относится к определенной категории (доступно около 10 категорий)

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

 article_id articletext category_id score ----------------------------------------------------- 142 <.....> 5 100 153 <.....> 3 97 119 <.....> 5 99 169 <.....> 2 93 121 <.....> 7 89 197 <.....> 2 92 . . . 

Первое (наивное) решение, которое приходит в голову, выполняет 10 выборок (по 1 для каждой категории), упорядочивая их по убыванию, а затем, на уровне PHP, чередуя каждый возвращаемый набор данных, одновременно получая один результат и объединяя их вместе в новом массиве.

Есть ли более эффективный способ достичь этого? Если возможно, на уровне MySQL

Пойдите, получите верхнюю 20. Если они не удовлетворяют требованиям, сделайте дополнительный запрос, чтобы получить недостающие части. Вы должны иметь возможность найти некоторый баланс между количеством запросов и количеством строк, которые возвращаются.

Я получил 100 лучших, которые могли удовлетворить требования в 90% случаев и были бы дешевле и быстрее, чем 10 отдельных запросов.

Если бы это был SQL Server, я мог бы помочь больше …

На самом деле, у меня есть другая идея. Запускайте процесс каждые 5 минут, который вычисляет список и кэширует его в таблице. Сделать DML против связанных таблиц недействительными кэш-память, поэтому он не используется до повторного заполнения (возможно, статья была удалена). Если кеш недействителен, вы можете вернуться к его вычислению на лету … И может использовать это, чтобы повторно кэшировать кеш.

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

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

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

 select * from ( (select @r:=@r+1 as rownum,article_id,articletext,category_id,score from articles,(select @r:=0) as r where category_id = 1 order by score desc limit 100000000) union all (select @r1:=@r1+1,article_id,articletext,category_id,score from articles,(select @r1:=0) as r where category_id = 2 order by score desc limit 100000000) union all (select @r2:=@r2+1,article_id,articletext,category_id,score from articles,(select @r2:=0) as r where category_id = 3 order by score desc limit 100000000) ) as t order by rownum,score desc 

Ваше наивное решение – именно то, что я буду делать.