
Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
28.04.2010, 19:10
|
|||
|---|---|---|---|
|
|||
сложности в, казалось бы, простой задаче |
|||
|
#18+
Долго пытаюсь нормально решить задачу. Задача следующая. Есть рубрики. Есть новости. У каждой новости есть одна рубрика. Требуется наиболее быстро и правильно получить максимум по N новостей из каждой рубрики, отсортированных по названию рубрики по возрастанию и по дате создания новости по убыванию. Как думаете, это вообще возможно сделать базовыми средствами SQL, не прибегая к созданию функций и прочему подобному? Пока что решил задачу двумя запросами (выборка по 2 новости) с промежуточной и последующей обработками на стороне клиента БД: 1) SELECT `news`.`rubric_id` as `rubric_id`, LEFT(GROUP_CONCAT(LPAD(`news`.`id`,3,'0') ORDER BY `news`.`created` desc),7) AS `id` FROM `news` LEFT JOIN `rubrics` ON `rubrics`.`id` = `news`.`rubric_id` GROUP BY `news`.`rubric_id` ORDER BY `rubrics`.`title` asc; 2) Разбираю ответ, подставляю полученные значения id во второй запрос. 3) SELECT * FROM `news` WHERE `id` IN (id1,id2,id3,...); 4) Сортирую результат второго запроса на стороне клиента БД в соответствии с порядком, полученным в ходе разбора первого запроса. Самое удивительное, что этот ужас работает. Если у кого-то возник вопрос "а почему не выбирать отдельными запросами из каждой рубрики?", прошу представить, что будет происходить в реальности, если рубрик становится несколько десятков, а сервер БД, например, расположен на другом континенте и, следовательно, накладные расходы на каждый запрос к базе данных становятся достаточно большими. Дамп базы (MySQL): CREATE TABLE `news` ( `id` int(10) unsigned NOT NULL auto_increment, `rubric_id` int(10) unsigned default NULL, `title` varchar(255) default NULL, `created` date default NULL, PRIMARY KEY (`id`) ); CREATE TABLE `rubrics` ( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) default NULL, PRIMARY KEY (`id`) ); insert into `news`(`id`,`rubric_id`,`title`,`created`) values (3,1,'Из-за наводнения в Сибири перекрыли федеральную трассу','2010-04-28'),(2,1,'Из-за штормового ветра во Владивостоке перестали ходить паромы','2010-04-27'),(1,1,'На севере Москвы при взрыве газа погиб человек','2010-04-26'),(5,2,'Совет Федерации ратифицировал соглашение по Черноморскому флоту','2010-04-28'),(4,2,'Чавес обвинил Колумбию в причастности к разведоперациям США','2010-04-27'),(6,3,'Россия не сможет сократить дефицит бюджета за счет роста цен на нефть','2010-04-27'); insert into `rubrics`(`id`,`title`) values (1,'происшествия'),(2,'политика'),(3,'экономика'); PS. На самом деле, база гораздо сложнее, но я специально упростил постановку задачи, чтобы узнать существует ли нормальный способ решения такого класса задач. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
28.04.2010, 19:39
|
|||
|---|---|---|---|
сложности в, казалось бы, простой задаче |
|||
|
#18+
itronТребуется наиболее быстро и правильно получить максимум по N новостей из каждой рубрики, отсортированных по названию рубрики по возрастанию и по дате создания новости по убыванию. Как думаете, это вообще возможно сделать базовыми средствами SQL, не прибегая к созданию функций и прочему подобному?Если бы вы писали топик в нужном подфоруме, то могли бы обнаружить, что там это даже в FAQ-е прописано. тынц1 и тынц2 . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
28.04.2010, 20:53
|
|||
|---|---|---|---|
|
|||
сложности в, казалось бы, простой задаче |
|||
|
#18+
Насколько я понимаю, решение задачи через номера строк результата имеет серьезное ограничение - такой подход будет весьма неэффективен при большом числе записей и полей в таблице. Мой вопрос - возможно ли решить упомянутую задачу базовыми средствами SQL наиболее быстро и правильно? Или применимы только разные не оптимальные методы? И задача не зависит от используемой конкретно СУБД. Заданный вопрос не относится к конкретике MySQL. Считаю, что под-форум выбрал правильно, а за ссылки спасибо, хотя этот метод тоже в свое время рассматривал и он не понравился именно упомянутым выше недостатком. Приведенный в первом сообщении метод и решение через нумерацию строк - это единственные способы решения задачи или есть более оптимальный вариант? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
29.04.2010, 09:38
|
|||
|---|---|---|---|
сложности в, казалось бы, простой задаче |
|||
|
#18+
itronНасколько я понимаю, решение задачи через номера строк результата имеет серьезное ограничение - такой подход будет весьма неэффективен при большом числе записей и полей в таблице.Эффективнее можно, но это будет уже не один запрос, а много.itronМой вопрос - возможно ли решить упомянутую задачу базовыми средствами SQL наиболее быстро и правильно? Или применимы только разные не оптимальные методы?По моим ощущениям - базовыми средствами SQL решить это можно, но придется писать отдельный запрос для каждого N и работать это будет очень медленно. Более-менее оптимально, имхо, можно решить только СУБД-специфичными методами.itronЗаданный вопрос не относится к конкретике MySQL.Тем не менее, представленный запрос является именно MySQL-специфичным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=32&tablet=1&tid=1542735]: |
0ms |
get settings: |
7ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
42ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
29ms |
get tp. blocked users: |
1ms |
| others: | 248ms |
| total: | 350ms |

| 0 / 0 |
