Есть таблица в ней поля с датой и временем.
Есть индекс дата, время, ...
Цель: найти max(дата, время).
Вопрос каким запросом искать?
Select first 1 t_trdt, t_trtm From ttdsls051354 Order By t_trdt desc,
t_trtm desc
Select t_trdt, t_trtm From ttdsls051354
Where t_trdt = (Select Max(t_trdt) From ttdsls051354) and
t_trtm = (Select Max(t_trtm) From ttdsls051354
Where t_trdt =(Select Max(t_trdt) From ttdsls051354))
Индекс используется в обоих случаях, но стоимость показывает совершенно
разную (может из-за first 1?). План одинаковый при First_Rows и ALL_Rows.
Таблицу менять нельзя (даже индексы).
Планы:
QUERY: (FIRST_ROWS OPTIMIZATION)
------
Select {+Explain} first 1 t_trdt, t_trtm From ttdsls051354 Order By t_trdt
desc, t_trtm desc
DIRECTIVES FOLLOWED:
EXPLAIN
DIRECTIVES NOT FOLLOWED:
Estimated Cost: 9676
Estimated # of Rows Returned: 253742
1) baan.ttdsls051354: INDEX PATH
(1) Index Keys: t_trdt t_trtm t_ckor t_orno t_pono t_sern (Key-Only)
(Serial, fragments: ALL)
QUERY: (FIRST_ROWS OPTIMIZATION)
------
Select {+Explain} t_trdt, t_trtm From ttdsls051354
Where t_trdt = (Select Max(t_trdt) From ttdsls051354) and
t_trtm = (Select Max(t_trtm) From ttdsls051354 Where t_trdt =(
Select Max(t_trdt) From ttdsls051354))
DIRECTIVES FOLLOWED:
EXPLAIN
DIRECTIVES NOT FOLLOWED:
Estimated Cost: 10
Estimated # of Rows Returned: 1
1) baan.ttdsls051354: INDEX PATH
(1) Index Keys: t_trdt t_trtm t_ckor t_orno t_pono t_sern (Key-Only)
(Serial, fragments: ALL)
Lower Index Filter: (baan.ttdsls051354.t_trtm = <subquery> AND
baan.ttdsls051354.t_trdt = <subquery> )
Subquery:
---------
Estimated Cost: 3
Estimated # of Rows Returned: 1
1) baan.ttdsls051354: INDEX PATH
(1) Index Keys: t_trdt t_trtm t_ckor t_orno t_pono t_sern
(Key-Only) (Aggregate) (Serial, fragments: ALL)
Subquery:
---------
Estimated Cost: 6
Estimated # of Rows Returned: 1
1) baan.ttdsls051354: INDEX PATH
(1) Index Keys: t_trdt t_trtm t_ckor t_orno t_pono t_sern
(Key-Only) (Aggregate) (Serial, fragments: ALL)
Lower Index Filter: baan.ttdsls051354.t_trdt = <subquery>
Subquery:
---------
Estimated Cost: 3
Estimated # of Rows Returned: 1
1) baan.ttdsls051354: INDEX PATH
(1) Index Keys: t_trdt t_trtm t_ckor t_orno t_pono t_sern
(Key-Only) (Aggregate) (Serial, fragments: ALL)
--
Журавлев Денис.
Сорри тут должно быть Select distinct t_trdt, t_trtm
--
Журавлев Денис.
А еще первый вариант лучше второго исходя из плана, т.к. во втором есть
Lower Index Filter, на который тоже нужно время ведь.
А еще в первый вариант можно легко добавить условие на дату / время.
И скорость не сильно изменится. А если такое же условие добавить во второй
вариант - то время поменяется более существенно. А все обратно-таки из-за
подзапросов.
Трудно миллисекунды там, надо табличку побольше наколбасить. Но тогда надо
сотни миллиардов записей наверно, ведь скорость поиска по индексу наверно
выглядит как x = log(n), причем log с основанием неслабым (тысячи?).
>
> А еще первый вариант лучше второго исходя из плана, т.к. во втором есть
> Lower Index Filter, на который тоже нужно время ведь.
Наверно.
Уроды сделали два поля вместо одного, теперь извращаюсь:
Select Distinct t_orno
From ttdsls051354
Where (t_trdt > ? or ( t_trdt = ? and t_trtm > ?)) and (t_trdt < ? or
t_trdt = ? and t_trtm <= ?))
Журавлев Денис.
Хватило 1 миллиона записей.
Вердикт: первый вариант быстрее на 50%
--
Журавлев Денис.
:-) Вообще такие задачи надо наверное в FAQ добавлять.
Под названием, например, поиск значения курса для некоторого мн-ва валют, по
определенным (весьма хитрым) условиям. Подзапросы тут просто не годятся.
Обычные FOREACH оказываются эффективнее.