Вопрос по оптимальности

Привет всем! У нас в коллективе разразился спор... И нужно мнение знающих и компетентных людей.
Что будет быстрее и оптимальнее (Задача вывести последнюю дату):
select date_reg from view_reg where id=1 order by datecreate desc limit 1;

или

select max(date_reg) from view_reg where id=1;

Зы. Был бы признателен, если подскажите.

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

По идее

По идее последнее должно быть быстрее, потому что не используется order by.
А вообще-то никто не мешает вам провести эксперимент.
Включите в настройках PostgreSQL выдачу статистики и посмотрите сколько времени займёт та и другая операция.

Ещё одним аргументом может послужить ANALYSE на оба запроса и изучения плана их выполнения.

max

Вариант с max -- быстрее. У меня, без индекса, при обработке 10 миллионов записей разница ~400-450ms, а с индексом вообще разницы не замечаю -- оба запроса выдают мгновенный результат.

Для того, чтобы

Для того, чтобы внести ясность:
Провел тест, таблица в 670330 записей, делаю поиск по самому максимальному значению поля code:

1. Без создания индекса на это поле:
Метод с order by и limit 1: 7,620.665 мсек
Метод с max(): 2,134.000 мсек

2. С индексом на это поле:
Метод с order by и limit 1: 24.581 мсек
Метод с max(): 1.789 мсек

Зы. получается, что с max быстрее. =(

Я практически

Я практически не сомневался, что с max быстрее, но почему у вас, fearuth, это вызывает огорчение?
Вполне логично предположить, что функцию max не зря придумали :)

Я просто

Я просто переживаю, что в следующем релизе, возможно функция max не будет уже работать с типом данных date и прийдется кучу функций тогда переписывать.

А почему она

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

эти два запроса

эти два запроса не эквивалентны, например, при отсуствии строк с id=1 или при наличии строки с (id,date_reg)=(1,null). кроме того date_reg=datecreate?

create table t1 ( type integer, name text );

select max(name) from t1 where type=1; -- null
select name from t1 where type=1 order by name desc limit 1; -- нет строки

insert into t1 values ( 1, 'foo' ), ( 1, 'bar' ), ( 1, null );

select max(name) from t1 where type=1; -- 'foo'
select name from t1 where type=1 order by name desc limit 1; -- null

create index i1 on t1 ( type, name );

explain analyze
select max(name) from t1 where type=1;

explain analyze
select name from t1 where type=1 order by name desc limit 1;

drop table t1;

оптимальные планы для этих двух запросов при наличии индекса по (id,date_reg) будут почти одинаковыми. запросы будут выполняться почти одинаковое время, быстро.

nalbat=> explain analyze
nalbat-> select max(name) from t1 where type=1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Result (cost=8.27..8.28 rows=1 width=0) (actual time=0.034..0.036 rows=1 loops=1)
InitPlan
-> Limit (cost=0.00..8.27 rows=1 width=32) (actual time=0.022..0.025 rows=1 loops=1)
-> Index Scan Backward using i1 on t1 (cost=0.00..8.27 rows=1 width=32) (actual time=0.017..0.017 rows=1 loops=1)
Index Cond: (type = 1)
Filter: (name IS NOT NULL)
Total runtime: 0.086 ms
(7 rows)

nalbat=>
nalbat=> explain analyze
nalbat-> select name from t1 where type=1 order by name desc limit 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..8.27 rows=1 width=32) (actual time=0.017..0.019 rows=1 loops=1)
-> Index Scan Backward using i1 on t1 (cost=0.00..8.27 rows=1 width=32) (actual time=0.013..0.013 rows=1 loops=1)
Index Cond: (type = 1)
Total runtime: 0.052 ms
(4 rows)

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023