Mysql 1 долгий запрос VS нескольких быстрых

tolstys

Новичок
подскажите, что лучше:
1 запрос, который выполняется 0.12 секунды или разбиение его на 3 запроса, каждый из которых выполняется не более чем за 0.002 секунды?
 

С.

Продвинутый новичок
Нее... Тут без калькулятора сразу не сказжешь...
 

С.

Продвинутый новичок
лучше не значит быстрее :)
Правильно! Теперь тогда определяем понятие "лучше", и глядишь, ответ на вопрос сам собой найдется.

не сильно ли нагрузит сервер большее количество запросов?
Один запрос грузит сервер на 0.12 секунды. Три запроса грузят на 0.006. В каком случае сервер загружен больше?
 

Фанат

oncle terrible
Команда форума
нет, три запроса не загрузят сервер.
другое дело что можно попытаться оптимизировать тот который один
 

tolstys

Новичок
нет, три запроса не загрузят сервер.
другое дело что можно попытаться оптимизировать тот который один
3 запроса вместо 1... то есть, грубо говоря, выбор между 300 и 100 запросами в секунду

в запросе идет сортировка по двум столбцам в разных направлениях (составной индекс не работает), у меня не получилось его оптимизировать... может, подскажете)
работает долго только при большом количестве строк в таблице...
PHP:
SELECT  `id`
FROM `USERS`
ORDER BY `score` DESC, `id` ASC
LIMIT 0, 100
разбил его на 3 запроса:
1. считает количество записей в таблице
2. получаем количество очков у последнего из ТОП... если в таблице меньше записей, чем размер ТОП, то считаем последнюю запись (для этого и был нужен первый запрос)
PHP:
SELECT `score`
    FROM `USERS`
    ORDER BY `score` DESC
    LIMIT ' . ($count - 1) . ', 1
3.
PHP:
SELECT @n:=@n+1 AS `place`, `id`, `score`
            FROM (
                SELECT `id`, `score`
                FROM `USERS`
                WHERE `score` >= ' . $score . '
                ORDER BY `score` DESC
                LIMIT ' . $limit . '
            ) as z2, 
                (SELECT @n:=0) AS z1 
            ORDER BY `score` DESC, `id` ASC
в последнем запросе перебирается меньше строк за счет индексов, потому и скорость выше
 

Adelf

Administrator
Команда форума
лучше один запрос, правильно закешированный.
 

Фанат

oncle terrible
Команда форума
лучше один запрос, правильно закешированный.
категорически не согласен.
кэш, как и любая денормализация, прибавляет головной боли. и является средством последнедней надежды, когда больше ничего не помогает.
 

Фанат

oncle terrible
Команда форума
tolstys
в твоем случае поможет небольшой хак. не знаю, насколько он приемлем, но всё же:
если хранить score в отрицательном виде, то и сортировка будет мгновенной, и составной индекс заработает
 

Breeze

goshogun
Команда форума
Партнер клуба
3 запроса вместо 1... то есть, грубо говоря, выбор между 300 и 100 запросами в секунду
нет, в твоем случае, грубо говоря, это выбор между 8 и 166 запросами в секунду.
т.е. выигрыш в скорости около 690%
 

MiksIr

miksir@home:~$
Mysql все еще не научился создавать индексы с указанием направления? o.o
 

WMix

герр M:)ller
Партнер клуба
tolstys
я вот смотрю твои запросы, читаю, но никак не догоняю, о чем это?
пол задачи понял, узнать количество очков у последнего из ТОП. и сдается впечатление, что это один запрос!
PHP:
SELECT  `score`
FROM `USERS`
ORDER BY `score` DESC, `id` ASC
LIMIT 99, 1
а что дальше, непойму переменная @n что это?, зачем так сложно!

попробуй сказать что ты ищешь
 

tolstys

Новичок
tolstys
я вот смотрю твои запросы, читаю, но никак не догоняю, о чем это?
пол задачи понял, узнать количество очков у последнего из ТОП. и сдается впечатление, что это один запрос!
PHP:
SELECT  `score`
FROM `USERS`
ORDER BY `score` DESC, `id` ASC
LIMIT 99, 1
а что дальше, непойму переменная @n что это?, зачем так сложно!

попробуй сказать что ты ищешь
на самом деле можно обойтись и двумя запросами, но часть расчетов придется сделать, например, на php... то есть выбрать записей с 1 по 100, вогнать в массив и выбрать последний элемент (он не обязательно будет сотым)
предложенный тобой запрос не подходит, так как если в таблице меньше 100 записей, он ничего не вернет
@n - переменная, для нумерации места в рейтинге... почему то из первого запроса я ее убрал так как ее присутствие/отсутствие неважно в рамках данного вопроса, а из другого забыл)

мне нужно получить выборку, отсортированную по двум столбцам в разных направлениях из большой таблицы
логика с одним запросом вроде понятна... с другим вариантом - такая: нужно получить количество очков у последнего места из ТОП, отсортированного только по очкам (но не факт, что это будет реально последний человек в ТОПе, так как у кого-то может быть столько же очков, но id меньше, а в ТОП при данной выборке он не попал) затем в подзапросе делаем выборку на все записи, у которых score >= найденного нами значения и по этой небольшой выборке уже делаем сортировку в двух направлениях и отсекаем нужный нам ТОП

вариант с отрицательным значением очков очень интересный :)
 

Фанат

oncle terrible
Команда форума
в принципе. я не вижу большой проблемы в отрицательном счёте.
да, придётся переформатировать на выводе. но это вполне штатная ситуация. datetime мы тоже переформатируем на выводе, потому что храним в формате, удобном для сортировки.
 

WMix

герр M:)ller
Партнер клуба
первое что приходит на ум,

PHP:
CREATE TABLE IF NOT EXISTS `score` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `score` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `score` (`score`)
) ENGINE=MyISAM;

INSERT INTO `test`.`score` (`id`, `score`) VALUES 
(NULL, CAST(rand() * 1000 as unsigned)), 
(NULL, CAST(rand() * 1000 as unsigned)), 
(NULL, CAST(rand() * 1000 as unsigned)), 
(NULL, CAST(rand() * 1000 as unsigned)),
...
;


/* выбираем из топ 100 */
select min(id) as id, min(score) as score 
from (
/* выбираем топ 100 */
   select id, score
   from score
   order by score desc, id asc
   limit 100

) as top100

group by score
limit 1
 
Сверху