При переносе большой системы, разработанной под одну СУБД, на другую неизбежно возникают различные "нюансы". То, что эффективно работало в одной СУБД, уже не так эффективно (или совсем неэффективно) работает в другой.

В частности, SQL, разработанный под Oracle, при всей синтаксической схожести может работать совсем не так в PostgreSQL. Однако, это не значит, что ничего нельзя сделать. Зачастую, если переписать код, используя особенности новой СУБД, вы можете получить ту же эффективность выполнения.

Сегодня я хочу рассмотреть один частный случай, связанный с обработкой аналитических(оконных) функций оптимизаторами Postgres и Oracle.

Итак, рассмотрим ситуацию на синтетическом примере, к словку, который довольно похож на реальный. Создаём табличку t_rownum_stop c составным первичным ключом: obj_id - селективное, но не уникальное поле, key_1 и cat_id малоселективные поля.

CREATE TABLE t_rownum_stop
( cat_id           NUMBER(19) not null,
  key_1            NUMBER(5) not null,
  obj_id           NUMBER(10) not null,
  someurl          VARCHAR2(1024) not null,
  constraint t_rownum_stop_pk primary key (obj_id, key_1, cat_id)
  );

insert into t_rownum_stop
select mod(rownum,99) as cat_id, mod(rownum,19) as key_1, mod(rownum,511) as obj_id, rpad('aa'||rownum, 30, 'cds') as someurl    from dual connect by level<1e4
order by dbms_random.random();

begin       
 dbms_stats.gather_table_stats(ownname => USER,tabname=> upper('t_rownum_stop'));
end; 
/

Выполним наш запрос и посмотрим реальную статистику выполнения

ALTER SESSION SET statistics_level=all;

select * from (
select  row_number() over (order by obj_id) as rn,
       cat_id, key_1,       obj_id
       from t_rownum_stop t
       where obj_id between 100 and 200
       )  where rn=1;
       
select * from TABLE(dbms_xplan.display_cursor(null,null, '+allstats'));

Комментарии (1)


  1. unfilled
    31.07.2026 10:42

    Вместо того, чтобы сохранить в черновики, случайно опубликовали?