При переносе большой системы, разработанной под одну СУБД, на другую неизбежно возникают различные "нюансы". То, что эффективно работало в одной СУБД, уже не так эффективно (или совсем неэффективно) работает в другой.
В частности, 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'));
unfilled
Вместо того, чтобы сохранить в черновики, случайно опубликовали?