powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выборка уникальных значений из хронологической таблицы
25 сообщений из 59, страница 2 из 3
Выборка уникальных значений из хронологической таблицы
    #33101766
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicВсегда найдутся пути ( например ) разрешения подобной проблемы без ущерба правильности результата .

Они хорошие, эти пути. Медленно работают, а так хорошие.

ElicДаже тысячи успешных экспериментов не смогут превратить "лженаучную" () гипотезу в теорию.

Наука, гипотезы и теории здесь не причём.

Мы разговариваем про программное обеспечение СУБД Oracle, написанное определённым образом.

Оно написано таким образом, что мой запрос работает быстро (и правильно), а твой — медленно.

Причём тут наука?

ElicТы уже сделал свой выбор. Бог с тобой. Неси свой крест сам.
Но не надо пытаться привлекать за собой в эту странную религию другие неокрепшие умы.

Можно, я сам решу, что мне делать?

Спасибо.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33101770
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY
Well, problem is it is difficult (at least for me) to determine what constitutes a full set of hints for a specific SQL statement. In terms of STORED OUTLINES, CBO should use same plan, however, in general, it might require certain INIT.ORA parameters be set same way (for example, QUERY_REWRITE_ENABLED, STAR_TRANSFORMATION_ENABLED, OPTIMIZER_FEATURES_ENABLE).


We are getting more and more clear :)

So, once again:

Question 1 : if I set up database with all the parameters needed for the STORED OUTLINES to work (according to specification), make a STORED OUTLINE to use INDEX RANGE SCAN DESCENDING , and the indexes in question are present and functional, will it be considered a bug if the CBO chooses another access method?

Question 2 : if CBO does use INDEX RANGE SCAN DESCENDING and returns rows not in descending order of their indexed values (as said in specification), will it be considered a bug?

Thanks in advance for answering.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33101773
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY КваснойQuestion: if I do specify full set of hints (with a STORED OUTLINE, for instance, or with hints as such), all tables and indexes do exist and are is usable state, then do I ensure the execution plan?

Well, problem is it is difficult (at least for me) to determine what constitutes a full set of hints for a specific SQL statement. In terms of STORED OUTLINES, CBO should use same plan, however, in general, it might require certain INIT.ORA parameters be set same way (for example, QUERY_REWRITE_ENABLED, STAR_TRANSFORMATION_ENABLED, OPTIMIZER_FEATURES_ENABLE).

КваснойQuestion: if CBO does use INDEX RANGE SCAN DESCENDING and returns rows not in descending order of indexed values (as said in specification), will it be considered a bug?

No. For a simple reason you heard "several hundred times before". Besides, if you are joining tables, CBO might use index in desc order but then use hash join or some sort of conversion to bitmap which will affect resultset row order or simply whoever wrote CBO code felt like it. All INDEX_DESC hint tells CBO is how to access the table - it does not tell it to return it in desc or any other, for that matter, order.

SY.

Sorry for repeating, but:

Oracle9i Database Performance Tuning Guide and ReferenceAn index range scan descending is identical to an index range scan , except that the data is returned in descending order. Indexes, by default, are stored in ascending order. Usually, this scan is used when ordering data in a descending order to return the most recent data first , or when seeking a value less than a specified value.

Again, there are no table joins in the query in question.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33101778
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почитай пожалуйста указанную мной ссылку на одну из нитей обсуждения этой ситуации -- фраза "[ но в целом , "without an order_by_clause, no guarantee exists that the same query executed more than once will retrieve rows in the same order".] Я думаю этого достаточно, чтобы понять, что тех. поддержка тебя вышлет, если ты будешь им рассказывать о своей жизненной позиции по поводу использования индекса." -- это один из примеров когда запрос может возвращать вовсе не то что ожидается (там другой план выполнения, но по рукам будут бить не потому что у Oracle план поменялся, а потому что приложение что-то посчитало неправильно). Вообщем и целом такой подход менее foolproof, чем подход с явным использованием ORDER BY или другой функциональности, где бы всё было сделано с учётом изменений схемы, сообственно, об этом и говорилось. Также, опыт показывает что число проблем (bugs) связанных с использованием подсказки INDEX_DESC было несколько больше чем с использованием ORDER BY. И если вдруг такая проблема возникнет, то в тех местах где ты используешь INDEX_DESC тебе придётся менять функциональность или ждать исправлений. Вот тут и скажут тебе о заветном "workaround": USE ORDER BY! Поэтому здесь замечание "Тебя научит жизнь." справедливо. Несколько выше ты пытался доказать что появление проблемы подобного плана при использовании ORDER BY равновероятна появлению проблемы при использовании INDEX_DESC, должен отметить что это несколько не так. Их появление неравновероятно.

<OFFTOPIC>Да, и не нужно неумело вырывать фразы из контекста.</OFFTOPIC>

КваснойВопрос: будет ли считаться багом ситуация, когда хинт указывает метод доступа INDEX RANGE SCAN DESCENDING по существующему индексу, конструкция запроса позволяет использовать этот метод, а CBO, вопреки тому, что написано в документации, этот метод не использует?CBO обязан подчиниться подсказке, если нет синтаксических и семантических проблем с её применением. Основная проблема -- понимание семантики выполнения.

КваснойВ данном случае мы будем предполагать, что индекс с заданным названием существует.В каком "данном"? Если ты говоришь только о том примере, который ты привёл в своём самом первом сообщении, то да, индекс будет использоваться. Здесь нет никаких противоречий и возражений. Более того как говорил Станислав, здесь перефразировано, "как же так? примерчик-то был" :-)
Квасной 2. Если используется метод доступа INDEX RANGE SCAN DESCENDING , то значения возвращаются отсортированными по убыванию величины индексированных полей.
Грубо: при INDEX RANGE SCAN DESCENDING значения будут "появлятся" в rowsource, по мере чтения блоков индекса. Поскольку они хранятся отсортированными, то да, они будут попадать в rowsource отсортированными. Как они будут возвращаться из запроса, зависит от того что происходит дальше, используется ли, скажем, PQO, joins и т.д.
Квасной Вопрос: будет ли считаться багом ситуация, в которой Oracle при использовании данного метода доступа возвращает строки не в порядке убывания величины индексированных полей, а в каком-то ином порядке, не соответствующем тому, что написано в документации?Я уже писал об этом, если поведение Oracle RDBMS не соответствует тому о чём написано в документации -- нужно открывать TAR и разговаривать с тех. поддержкой.

http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:9843506698920#9896083461138

Я не могу сказать что здесь я на 100% согласен с Томасом Кайтом (я оставляю 1%, именно потому что пару раз мне пришлось решать проблему, котороая вынуждала использовать такой подход. Дело было на 7.3 и 8.0.x да и то только потому что были какие-то старнные баги, разбираться было некогда), но за всеми теми красноречивыми высказываниями есть рациональное зерно... Даже твой код выше, в котором ты обругал абстрактного администратора БД абсолютно не foolproof -- ошибки ищи сам. :-)

Ради любопытства, я хотел бы увидеть raw tracefiles твоего запроса и того что ниже. Пожалуйста, если нужно, сделай соответсвующий корректировки для своей системы. Проверь три варианта:

1. Твой оригинальный запрос.
2. Тот что ниже.
3. Тот что ниже с подсказкой /*+ INDEX_DESC (r ux_rate_currency_date) */

и выложи сюда zipped raw trace files.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
DEFINE numb_mask = 'FM9999999999.99999'
DEFINE date_mask = 'YYYYMMDD'
DEFINE date_mast_l1 =  9 

SELECT TO_NUMBER(
         SUBSTR(
           (
           SELECT MAX(TO_CHAR(r.rdate, '&&date_mask') || TO_CHAR(r.rrate, '&&numb_mask', 'NLS_NUMERIC_CHARACTERS=".,"')) l
             FROM rates r
            WHERE r.rdate <= x.xdate
              AND r.rcurrency = x.xcurrency
            GROUP BY
                  r.rcurrency
           )
         , &&date_mast_l1
         )
       , '&&numb_mask'
       , 'NLS_NUMERIC_CHARACTERS=".,"'
       ) rate
  FROM transactions x
/
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33101891
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
SQL> SELECT * FROM v$version WHERE ROWNUM =  1 ;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release  10 . 1 . 0 . 4 . 0  - Prod

SQL> CREATE TABLE transactions (xid NUMBER, xsum FLOAT, xdate DATE, xcurrency NUMBER);

Таблица создана.

SQL> CREATE TABLE rates (rcurrency NUMBER, rdate DATE, rrate FLOAT);

Таблица создана.

SQL> CREATE UNIQUE INDEX ux_rate_currency_date ON rates (rcurrency, rdate);

Индекс создан.

SQL> BEGIN
   2     dbms_stats.gather_table_stats(ownname => USER, tabname => 'RATES', CASCADE => TRUE);
   3     dbms_stats.gather_table_stats(ownname => USER, tabname => 'TRANSACTIONS');
   4   END;
   5   /

Процедура PL/SQL успешно завершена.

SQL> INSERT INTO transactions VALUES( 1 ,  1 , TRUNC(SYSDATE),  1 );

 1  строка создана.

SQL> INSERT INTO transactions VALUES( 1 ,  2 , TRUNC(SYSDATE),  2 );

 1  строка создана.

SQL> INSERT INTO transactions VALUES( 1 ,  2 , TRUNC(SYSDATE) -  1 ,  2 );

 1  строка создана.

SQL> INSERT INTO rates VALUES( 1 , TRUNC(SYSDATE) -  1 ,  1 . 2 );

 1  строка создана.

SQL> INSERT INTO rates VALUES( 1 , TRUNC(SYSDATE) -  2 ,  1 . 1 );

 1  строка создана.

SQL> INSERT INTO rates VALUES( 2 , TRUNC(SYSDATE) -  0 ,  1 . 0 );

 1  строка создана.

SQL> INSERT INTO rates VALUES( 2 , TRUNC(SYSDATE) -  1 ,  1 . 1 );

 1  строка создана.

SQL> INSERT INTO rates VALUES( 2 , TRUNC(SYSDATE) -  2 ,  1 . 2 );

 1  строка создана.

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

  EFF_RATE
----------
        1 , 2 
          1 
        1 , 1 


План выполнения
----------------------------------------------------------
    0       SELECT STATEMENT Optimizer=ALL_ROWS (Cost= 2  Card= 1  Bytes= 22 )
    1      0    COUNT (STOPKEY)
    2      1      TABLE ACCESS (BY INDEX ROWID) OF 'RATES' (TABLE)
    3      2        INDEX (RANGE SCAN DESCENDING) OF 'UX_RATE_CURRENCY_DATE' (INDEX (UNIQUE))
    4      0    TABLE ACCESS (FULL) OF 'TRANSACTIONS' (TABLE) (Cost= 2  Card= 1  Bytes= 22 )



SQL> ALTER SESSION SET -
> "_optimizer_ignore_hints"=TRUE
   2   /

Сеанс изменен.

SQL> SELECT  (
   2   	     SELECT  /*+ INDEX_DESC (r ux_rate_currency_date) */
   3   		     rrate
   4   	     FROM    rates r
   5   	     WHERE   r.rcurrency = x.xcurrency
   6   		     AND r.rdate <= x.xdate
   7   		     AND rownum =  1 
   8   	     ) AS eff_rate
   9   FROM    transactions x
  10   /

  EFF_RATE
----------
        1 , 1 
        1 , 2 
        1 , 2 


План выполнения
----------------------------------------------------------
    0       SELECT STATEMENT Optimizer=ALL_ROWS (Cost= 2  Card= 1  Bytes= 22 )
    1      0    COUNT (STOPKEY)
    2      1      TABLE ACCESS (BY INDEX ROWID) OF 'RATES' (TABLE)
    3      2        INDEX (RANGE SCAN) OF 'UX_RATE_CURRENCY_DATE' (INDEX (UNIQUE))
    4      0    TABLE ACCESS (FULL) OF 'TRANSACTIONS' (TABLE) (Cost= 2  Card= 1  Bytes= 22 )



SQL> DROP TABLE rates;

Таблица удалена.

SQL> DROP TABLE transactions;

Таблица удалена.

SQL> EXEC EXECUTE IMMEDIATE 'purge recyclebin';

Процедура PL/SQL успешно завершена.

SQL> SPOOL OFF
Срочно беги за валидолом :-)
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33102113
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир Бегун
Код: plaintext
1.
SQL> ALTER SESSION SET "_optimizer_ignore_hints"=TRUE
   2   /

Сеанс изменен.

Интересно: а почему, например, не DROP TABLE , или не SHUTDOWN ABORT ?

К чему такие полумеры? :)

У нас, например, такие вещи никто не делает, тем более на боевых серверах, потому как запрещено монаршей властию.

Хочешь поменять что-то в базе — проконсультируйся с заинтересоваными лицами.

Владимир БегунСрочно беги за валидолом :-)

Да я уж как-нибудь так, аскорбинкой :)

P.S. Трейсы вечерком выложу, ОК?
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103261
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КваснойSorry for repeating, but:


Oracle9i Database Performance Tuning Guide and Reference An index range scan descending is identical to an index range scan, except that the data is returned in descending order. Indexes, by default, are stored in ascending order. Usually, this scan is used when ordering data in a descending order to return the most recent data first, or when seeking a value less than a specified value.

Again, there are no table joins in the query in question.


Well, Владимир Бегун already answered it - PQO. Phrase "the data is returned in descending order" you are referring to applies not to a session executing SQL statement, but rather to individual processes/threads/slaves session is executing. So in case of PQO, each slave will return data in descending order. However, when results are merged, there is no guarantee such order will be preserved.

SY.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103287
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну-с, вот обещанные трейсы.

В таблице 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 сек.

Результатов работы остальных запросов я, понятное дело, ждать не стал, время из работы, по прогнозам, составило бы от 250 до 750—800 секунд. Желающие могут проверить сами.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103307
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SYWell, Владимир Бегун already answered it - PQO. Phrase "the data is returned in descending order" you are referring to applies not to a session executing SQL statement, but rather to individual processes/threads/slaves session is executing. So in case of PQO, each slave will return data in descending order. However, when results are merged, there is no guarantee such order will be preserved.

SY.

That's true, PQO may affect data order. I use Standard Edition with no PQO , so that's not a problem for me, but it may be a problem for Enterprise Edition users.

So what if we disable PQO for that query with /*+ NOPARALLEL_INDEX (r ux_rates_currency_date) */ ?

There will be no parallel scans and no table joins.

What else can violate the data order returned by INDEX RANGE SCAN DESCENDING ?
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103459
Oleg Perekhrest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КваснойНу-с, вот обещанные трейсы.

В таблице 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 сек.

Результатов работы остальных запросов я, понятное дело, ждать не стал, время из работы, по прогнозам, составило бы от 250 до 750—800 секунд. Желающие могут проверить сами.


Для запроса Бегуна, надо было ф-ый индекс создавать
по выражению TO_CHAR(r.rdate, \'&&date_mask\') || TO_CHAR(r.rrate, \'&&numb_mask\', \'NLS_NUMERIC_CHARACTERS=".,"\')

Скиньте еще результаты с другим индексом
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103512
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg PerekhrestДля запроса Бегуна, надо было ф-ый индекс создавать
Ты "поторопился" с советом :-) а мне нужно что-то делать с cut&paste...
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103513
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Oleg Perekhrest
Для запроса Бегуна, надо было ф-ый индекс создавать
по выражению TO_CHAR(r.rdate, '&&date_mask') || TO_CHAR(r.rrate, '&&numb_mask', 'NLS_NUMERIC_CHARACTERS=".,"')

Скиньте еще результаты с другим индексом

Он его не цепляет. То есть цепляет, конечно, но делает так:

Код: plaintext
1.
2.
CREATE INDEX ux_rates_function
ON rates (rcurrency, TO_CHAR(rdate, 'YYYYMMDD') ||
TO_CHAR(rrate, 'FM9999999999.99999', 'NLS_NUMERIC_CHARACTERS=".,"'))

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
EXPLAIN PLAN FOR
SELECT	/*+ INDEX (r ux_rates_function) */
	MAX(TO_CHAR(rdate, 'YYYYMMDD') ||
	TO_CHAR(rrate, 'FM9999999999.99999', 'NLS_NUMERIC_CHARACTERS=".,"'))
FROM	rates r
WHERE	rcurrency = :cur
	AND (TO_CHAR(rdate, 'YYYYMMDD') ||
	TO_CHAR(rrate, 'FM9999999999.99999', 'NLS_NUMERIC_CHARACTERS=".,"')) <= :xdate
GROUP BY
	rcurrency

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
| Id  | Operation                    |  Name              | Rows  | Bytes | Cost
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                    |     8 |   216 |
|   1 |  SORT GROUP BY NOSORT        |                    |     8 |   216 |
|*  2 |   TABLE ACCESS BY INDEX ROWID| RATES              |     8 |   216 |
|*  3 |    INDEX RANGE SCAN          | UX_RATES_FUNCTION  |    61 |       |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(TO_CHAR("R"."RDATE",'YYYYMMDD')||TO_CHAR("R"."RRATE",'FM9999999999
              .9999','nls_numeric_characters=''".''')<=:Z)
   3 - access("R"."RCURRENCY"=:Z)
Note: cpu costing is off

Производительность, понятно, ещё меньше.

Почему-то при использовании функциональных индексов CBO не делает INDEX RANGE SCAN / FIRST ROW (MIN/MAX) .

Я когда-то пытался с этим экспериментировать, но результаты абсолютно невоспроизводимы (в отличие от использования INDEX_DESC по обычному индексу)
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103528
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажи результаты такого же теста, но с FBI, также охота посмотреть на waits.

Честно говоря, удивлён, что ты делаешь NL на таких объёмах -- если это действительно рабочий запрос на таком количестве данных.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103538
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Квасной...
Note: cpu costing is off
...
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103542
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир БегунПокажи результаты такого же теста, но с FBI, также охота посмотреть на waits.

Завтра вечером, ОК?

Владимир БегунЧестно говоря, удивлён, что ты делаешь NL на таких объёмах -- если это действительно рабочий запрос на таком количестве данных.

Ну, по всем проводкам он практически никогда не бывает. Обычно отфильтровываются пятьдесят-сто-двести тысяч строк, реже пятьсот, реже миллион, по ним считаются суммы в базовой валюте (как раз таким вот способом), и делаются всякие агрегаты. На боевом сервере это доли секунд-секунды. Но всё равно нет предела совершенству :)

А как быстрее сделать джойн по условию минимакса, я не знаю. Если подскажешь способ — с меня стакан кориандровой.

Мне ведь этот самопал с хинтами тоже не особо нравится :) Я его предлагаю только потому, что он работает и более-менее документирован.

А так я ночи не сплю, думаю, как бы ORDER BY половчее прикрутить :)
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103547
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КваснойТо есть цепляет, конечно, но делает так:
Нет, это ты так руками написал, делает он так:
Код: 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 * FROM TABLE(dbms_xplan.display());

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value:  204164600 

--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|    0  | SELECT STATEMENT             |                   |      3  |     66  |      3    ( 0 )|  00 : 00 : 01  |
|    1  |  SORT GROUP BY NOSORT        |                   |      1  |     35  |      2    ( 0 )|  00 : 00 : 01  |
|*   2  |   TABLE ACCESS BY INDEX ROWID| RATES             |      1  |     35  |      2    ( 0 )|  00 : 00 : 01  |
|*   3  |    INDEX RANGE SCAN          | UX_RATES_FUNCTION |      1  |       |      1    ( 0 )|  00 : 00 : 01  |
|    4  |    TABLE ACCESS FULL         | TRANSACTIONS      |      3  |     66  |      3    ( 0 )|  00 : 00 : 01  |
--------------------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

    2  - filter("R"."RDATE"<=:B1)
    3  - access("R"."RCURRENCY"=:B1)
Но дело даже не в этом. "Проблема" у запроса это -- NL, и на больших объёмах в системах с большим числом одновременно работающих пользователей это приведёт к общему падению производительности системы -- CPU будет NL "работать". Поэтому, "меня терзают смутные сомнения" что ты действительно используешь именно этот запрос (именно так как ты его написал без дополнтельных фильтров) в более чем 30(?) местах.

Проверять с FBI большого смысла нет. Отменяю запрос.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103557
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир Бегун
Нет, это ты так руками написал, делает он так:


Ну что я, совсем, что ли, шакал позорный — руками что-то подписывать?

В точности так он делает, как я в посте написал.

Я план делал для FIELD SUBQUERY , а не для всего запроса.

Для всего запроса вот, пожалуйста:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
| Id  | Operation                    |  Name              | Rows  | Bytes | Cost
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                    |   637K|    16M|  118
|   1 |  SORT GROUP BY NOSORT        |                    |     8 |   216 |
|   2 |   TABLE ACCESS BY INDEX ROWID| RATES              |     8 |   216 |
|*  3 |    INDEX RANGE SCAN          | UX_RATES_FUNCTION  |     3 |       |
|   4 |  TABLE ACCESS FULL           | TRANSACTIONS       |   637K|    16M|  118
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("RATES"."RCURRENCY"=:B1)
       filter(TO_CHAR("RATES"."RDATE",'YYYYMMDD')||TO_CHAR("RATES"."RRATE",'FM99
              99999999.99999','nls_numeric_characters=''".''')<=:B1)
Note: cpu costing is off

Владимир Бегун
Но дело даже не в этом. "Проблема" у запроса это -- NL, и на больших объёмах в системах с большим числом одновременно работающих пользователей это приведёт к общему падению производительности системы -- CPU будет NL "работать". Поэтому, "меня терзают смутные сомнения" что ты действительно используешь именно этот запрос (именно так как ты его написал без дополнтельных фильтров) в более чем 30(?) местах.

Проверять с FBI большого смысла нет. Отменяю запрос.

Одновременно работающих пользователей там как раз мало.

Да к тому же я уже говорил: фильтры используются, запрос работает секунды, как сделать джойн по минимаксу быстрее — не знаю.

И всё таки, вернёмся к нашим хинтам.

Итак, на текущий момент имеем следующий вопрос : если дополнительным хинтом отключить PARALLEL ACCESS в INDEX RANGE SCAN DESCENDING , и не использовать в запросе джойнов, должна ли правильность порядка возвращаемых данных определяться правильностью хранения их в индексе?

Согласно документации — да, должна.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103559
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квасной Владимир Бегун
Нет, это ты так руками написал, делает он так:

Ну что я, совсем, что ли, шакал позорный — руками что-то подписывать?

Ты сам себя так назвал, вот этот запрос, это не тот запрос, который я просил тебя проверять, ок?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT	/*+ INDEX (r ux_rates_function) */
	MAX(TO_CHAR(rdate, 'YYYYMMDD') ||
	TO_CHAR(rrate, 'FM9999999999.99999', 'NLS_NUMERIC_CHARACTERS=".,"'))
FROM	rates r
WHERE	rcurrency = :cur
	AND (TO_CHAR(rdate, 'YYYYMMDD') ||
	TO_CHAR(rrate, 'FM9999999999.99999', 'NLS_NUMERIC_CHARACTERS=".,"')) <= :xdate
GROUP BY
	rcurrency
:-) Тише едешь, дальше будешь...
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103566
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КваснойА так я ночи не сплю, думаю, как бы ORDER BY половчее прикрутить :)

The way I see it, core of the issue is "wrong tool" for the job. Task is to select MIN/MAX value, or generalizing, to select value (or row producing that value) based on its rank. ORDER BY is wrong (in terms of efficiency) tool for the job if value is indexed, assuming corresponding column or columns are NOT NULL or NULLS need to be excluded from ranking process. However and unfortunately, ORDER BY is the only guaranteed tool for the job. Frankly, I am surprised Oracle does not offer any functions based on indexes, so you do not have to sort every time. Something like:

Код: plaintext
INDEX_BASED_RANK(column,index-name,rank,ranking-method,ranking-direction)

where ranking-method is either DENSE or SPARSE and ranking-direction is either ASC or DESC. In any case, I agree with Квасной, indexes are quite underutilized. It is a classic "видит око...".

SY.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103571
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квасной
Итак, на текущий момент имеем следующий вопрос : если дополнительным хинтом отключить PARALLEL ACCESS в INDEX RANGE SCAN DESCENDING , и не использовать в запросе джойнов, должна ли правильность порядка возвращаемых данных определяться правильностью хранения их в индексе?
Да. Если в системе ничего не происходит:

- изменений схемы
- параметров
- всё жёстко "прошито"

то да, работает так как просили. Твой вопрос абсолютно правомерный -- как при прочих равных добиться быстрой скорости работы "официально разрешенных" конструкций, не жертвуя при этом скоростью. В общем случая, я бы пожертвовал скоростью, но вводная такова что ничего не меняется... :-) ("поймаете" вы что нибудь... жизнь штука жестокая).
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103575
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимир Бегун
Ты сам себя так назвал, вот этот запрос, это не тот запрос, который я просил тебя проверять, ок?

А я от твоего запроса планов и не постил :) Только трейсы и время исполнения.

То, про что ты говоришь — это план от запроса с ипользованием индекса, предложенного тов. "Oleg Perekhrest", это я ему отвечал. :)

Но твой запрос тоже не быстрит: он не может сделать INDEX RANGE SCAN / FIRST ROW (MIN/MAX) по функции, т. к. она не проиндексирована. Поэтому приходится делать INDEX RANGE SCAN по всей подходящей области, и сортировать по значению функции.

Но даже если функция проиндексирована — то CBO один хрен не делает INDEX RANGE SCAN / FIRST ROW (MIN/MAX) , непонятно, почему.

Кстати, если сделать MAX(rdate) с использованием INDEX RANGE SCAN / FIRST ROW (MIN/MAX) , а потом сджойниться с таблицей rates ещё раз, то всё работает достаточно бодренько. Медленнее, конечно, чем с INDEX RANGE SCAN DESCENDING , но быстрее, чем со всем вышеизложенным.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103581
Владимир Бегун
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Квасной Владимир Бегун
Ты сам себя так назвал, вот этот запрос, это не тот запрос, который я просил тебя проверять, ок?
То, про что ты говоришь — это план от запроса с ипользованием индекса, предложенного тов. "Oleg Perekhrest", это я ему отвечал. :)
Я повторю то, что уже сказал:
Ты "делал для FIELD SUBQUERY, а не для всего запроса." -- и сделал ты это неверно. Вот и всё. :-) Проехали.
КваснойНо твой запрос тоже не быстрит:
Было написано "ради любопытства..."...
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103583
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SYThe way I see it, core of the issue is "wrong tool" for the job. Task is to select MIN/MAX value, or generalizing, to select value (or row producing that value) based on its rank. ORDER BY is wrong (in terms of efficiency) tool for the job if value is indexed, assuming corresponding column or columns are NOT NULL or NULLS need to be excluded from ranking process. However and unfortunately, ORDER BY is the only guaranteed tool for the job. Frankly, I am surprised Oracle does not offer any functions based on indexes, so you do not have to sort every time. Something like:

Код: plaintext
INDEX_BASED_RANK(column,index-name,rank,ranking-method,ranking-direction)

where ranking-method is either DENSE or SPARSE and ranking-direction is either ASC or DESC. In any case, I agree with Квасной, indexes are quite underutilized. It is a classic "видит око...".

SY.

You're absolutely right.

The problem is that such an outstanding software as Oracle has some piece of code in it called CBO . In fact, one should persuade it to use certain access paths, join methods etc., and it may either agree to use the way of work chosen, or silently ignore it and work in its own way.

I think it's quite rotten, ill and wrong situation.

I don't care whether a delivery boy uses subway or bus, but I do care about major things like profit renvestment etc.

The same with CBO . I don't care how CBO selects a row from a table that has 5 rows, but I do care how does it executes queries like described above, as they are quite important for the business logics.

So I think CBO should have an option to use strict hints of something like that. The query with such hints should either run with access paths and join methods offered; or generate an error, if they are unavailable.

Unfortunately, I can show no key for a limo large enough to criticize Oracle, that's why I'm just trying to work with what they sell us :)
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103637
Oleg Perekhrest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем что тут сказать...
Я например вот занимаюсь DWH под Oracle, у нас тоже имеются исторические таблицы. Вначале в 98 году начиналось все с табличек вида
CREATE TABLE transactions (bdate DATE, ....);
везде делался поиск по max но без ограничения по rownum, так как случай обычно другой был, надо было достать не одно поле, а все поля - а это значило что надо найти было эффективную дату действия, и связаться с табличкой trasnaction еще раз, чтобы достать все поля - т.е. условия связки были в теле where а не в вычислимых полях.
Потом через годик когда база подросла, пришлось добавить еще одно поле
CREATE TABLE transactions (bdate DATE, edate DATA....);
таким образом избавились от поиска max и перешли на between

Теперь же обычно используем смешанный способ:
1) или банальный between если надо достать строки на указанную дату. или edate='01.01.4000' для доставания действующей строки - так технологически заложено
2) или используем хранимую функцию вида:
обявляем курсор с order by
открываем курсор
берем поле - эффективную дату
закрываем курсор
возвращаем его в запрос где он используется
3) иногда пользуемся вариантом substr(max(поле_даты||поле_данных), x, y)

на больших объемах данных, где надо обрабатывать не одну, а множество строк, эффективнее всего оказались способ 1) или 2). но у нас же вариант достать обычно все поля из исторической таблицы, а не одно.
...
Рейтинг: 0 / 0
Выборка уникальных значений из хронологической таблицы
    #33103654
Квасной
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Oleg PerekhrestВ общем что тут сказать...
Я например вот занимаюсь DWH под Oracle, у нас тоже имеются исторические таблицы. Вначале в 98 году начиналось все с табличек вида
CREATE TABLE transactions (bdate DATE, ....);
везде делался поиск по max но без ограничения по rownum, так как случай обычно другой был, надо было достать не одно поле, а все поля - а это значило что надо найти было эффективную дату действия, и связаться с табличкой trasnaction еще раз, чтобы достать все поля - т.е. условия связки были в теле where а не в вычислимых полях.
Потом через годик когда база подросла, пришлось добавить еще одно поле
CREATE TABLE transactions (bdate DATE, edate DATA....);
таким образом избавились от поиска max и перешли на between

Теперь же обычно используем смешанный способ:
1) или банальный between если надо достать строки на указанную дату. или edate='01.01.4000' для доставания действующей строки - так технологически заложено
2) или используем хранимую функцию вида:
обявляем курсор с order by
открываем курсор
берем поле - эффективную дату
закрываем курсор
возвращаем его в запрос где он используется
3) иногда пользуемся вариантом substr(max(поле_даты||поле_данных), x, y)

на больших объемах данных, где надо обрабатывать не одну, а множество строк, эффективнее всего оказались способ 1) или 2). но у нас же вариант достать обычно все поля из исторической таблицы, а не одно.

Мы тоже раньше делали через функции.

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


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