powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка уникальных значений из хронологической таблицы
9 сообщений из 59, страница 3 из 3
Выборка уникальных значений из хронологической таблицы
    #33122985
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я открыл баг (снаружи он не виден) относительно проблемной конструкции. Есть
подозрения кое-какие и надеюсь что они верны и вскорости наступит всеобщее
счастье.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Выборка уникальных значений из хронологической таблицы
    #36426872
Владимир БегунЯ открыл баг (снаружи он не виден) относительно проблемной конструкции. Есть
подозрения кое-какие и надеюсь что они верны и вскорости наступит всеобщее
счастье.

Столкнулся с такой же проблемой на этой неделе на 10.2.0.4.
Счастье не наступило.

Радует что баг так и остался невидим снаружи :)
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #36426980
Inline view
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Квасной
К сожалению, Oracle версии 9i не позволяет передавать в FIELD SUBQUERY поля из внешнего запроса, если глубина вложения FIELD SUBQUERY больше 1. То есть такой, казалось бы, естественный запрос:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT	(
	SELECT	rrate
	FROM	(
		SELECT	rate
		FROM	rates r
		WHERE	r.rcurrency = x.xcurrency
			AND r.rdate <= x.xdate
		ORDER BY
			r.rdate DESC
		)
	WHERE	rownum =  1 
FROM	transactions x

приведёт к ошибке ORA-00904: недопустимый идентификатор .
Inline view не может быть корелированным, и не только в 9-ке, а и в более поздних версиях. Правда, в 10.2.0.1 это разрешалось, что похоже на баг.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #36427263
Inline viewКвасной
К сожалению, Oracle версии 9i не позволяет передавать в FIELD SUBQUERY поля из внешнего запроса, если глубина вложения FIELD SUBQUERY больше 1. То есть такой, казалось бы, естественный запрос:

Код: plaintext
\nSELECT\t(\n\tSELECT\trrate\n\tFROM\t(\n\t\tSELECT\trate\n\t\tFROM\trates r\n\t\tWHERE\tr.rcurrency = x.xcurrency\n\t\t\tAND r.rdate <= x.xdate\n\t\tORDER BY\n\t\t\tr.rdate DESC\n\t\t)\n\tWHERE\trownum =  1 \nFROM\ttransactions x\n

приведёт к ошибке ORA-00904: недопустимый идентификатор .
Inline view не может быть корелированным, и не только в 9-ке, а и в более поздних версиях. Правда, в 10.2.0.1 это разрешалось, что похоже на баг.

Констатация известных фактов.
(демонстрация потенциальной конструкции [не работающей в Oracle] которая могла бы решить проблему)

А проблема в следующем:

КваснойНу-с, вот обещанные трейсы.

В таблице transactions около 1 600 000 строк;

В таблице rates около 25 000 строк;

Селективность индекса ux_rates_currency_date по полю currency — около 8% , т. е. около 2 000 строк по каждой валюте.

В целях ускорения запроса выборка велась по первым 9 999 строкам из transactions . Результаты агрегировались и по ним считалась сумма.

Мой запрос работал 0,40 сек.
Запрос, предложенный тов. "Splain", работал 10,64 сек.
Запрос тов. "Владимира Бегуна" работал 34,53 сек.
Запрос тов. "Владимира Бегуна" с хинтом работал 34,04 сек.

Общую сумму по всей таблице transactions ( 1 600 000 строк) мой запрос считает около 25 сек.


НО САМЫЙ БЫСТРЫЙ ВАРИАНТ

Код: plaintext
SQL> SET AUTOTRACE ON EXPL\nSQL> SELECT  (\n   2   \t     SELECT  /*+ INDEX_DESC (r ux_rate_currency_date) */\n   3   \t\t     rrate\n   4   \t     FROM    rates r\n   5   \t     WHERE   r.rcurrency = x.xcurrency\n   6   \t\t     AND r.rdate <= x.xdate\n   7   \t\t     AND rownum =  1 \n   8   \t     ) AS eff_rate\n   9   FROM    transactions x\n  10   /

ТОЖЕ С БАГОМ - без order by НЕТ гарантии что возьмётся нужная строка.

ИТОГО: нормального решения для такого запроса нет до сих пор.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #36427917
Быдло__кодер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
select t.rrate from
  (SELECT  r.rrate, row_number() over (partition by x.rowid order by r.rdate desc) rn
    FROM  rates r, transactions x
    WHERE  r.rcurrency = x.xcurrency
      AND r.rdate <= x.xdate ) t
where t.rn= 1       
Не катит?
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #36430237
AAAx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Какова скорость варианта в пред. посте?
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #36432531
kepka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, в случае если использовать функцию и в ней запрос с order by, то Oracle делает RANGE SCAN DESCENDING:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
SQL> select rrate
   2       /* into Result */
   3       from (select rt.rrate
   4               from rates rt
   5              where rt.rdate <= :p
   6                and rt.rcurrency = :cr
   7              order by rt.rdate desc
   8              )
   9      where rownum <=  1 ;

no rows selected


Execution Plan
----------------------------------------------------------                      
    0       SELECT STATEMENT Optimizer=CHOOSE (Cost= 4  Card= 1  Bytes= 13 )            
    1      0    COUNT (STOPKEY)                                                     
    2      1      VIEW (Cost= 4  Card= 100  Bytes= 1300 )                                 
    3      2        TABLE ACCESS (BY INDEX ROWID) OF 'RATES' (Cost= 4  Card=          
           100  Bytes= 3000 )                                                       
                                                                                
    4      3          INDEX (RANGE SCAN DESCENDING) OF 'UX_RATE_CURRENCY_D          
          ATE' (UNIQUE) (Cost= 2  Card= 18 )                                        
                                                                                

и явно запретить использование индекса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> select rrate
   2       /* into Result */
   3       from (select /*+ no_index(rt) */ rt.rrate
   4               from rates rt
   5              where rt.rdate <= :p
   6                and rt.rcurrency = :cr
   7              order by rt.rdate desc
   8              )
   9      where rownum <=  1 ;

Execution Plan
----------------------------------------------------------                      
    0       SELECT STATEMENT Optimizer=CHOOSE (Cost= 21  Card= 1  Bytes= 13 )           
    1      0    COUNT (STOPKEY)                                                     
    2      1      VIEW (Cost= 21  Card= 100  Bytes= 1300 )                                
    3      2        SORT (ORDER BY STOPKEY) (Cost= 21  Card= 100  Bytes= 3000 )           
    4      3          TABLE ACCESS (FULL) OF 'RATES' (Cost= 19  Card= 100  Byt          
          es= 3000 )        

В первом варианте, сортировка происходит только с участием индекса.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Выборка уникальных значений из хронологической таблицы
    #37210436
Аффтар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У вас дырко в безопансоти?
ХАКККККККККККККККККККК
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Выборка уникальных значений из хронологической таблицы
    #39445552
Andrews222000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Столкнулся с такой же проблемой.

Пробуем к хинту index добавить first_rows(1)

/*+ INDEX_DESC (r ux_rate_currency_date) FIRST_ROWS(1) */

как ни странно, результат выборки у меня поменялся (версия oracle 11.2.0.4.0)
...
Рейтинг: 0 / 0
9 сообщений из 59, страница 3 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка уникальных значений из хронологической таблицы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]