Задать вопрос

Тормозящий Prepared statement на Oracle

Коллеги,

Есть следующий sql запрос, который выбирает 20 записей отсортированных по дате и транзакции:

select rd from (
    select /*+ INDEX(OUT_SMS OUT_SMS_CREATE_TS_TRX_ID_IX) */ rowid rd
    from OUT_SMS     
    where  TRX_ID between 34621422135410688 and 72339069014638591       
         and CREATE_TS between to_timestamp('2013-02-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') 
                 and to_timestamp('2013-03-06 08:57:00', 'yyyy-mm-dd hh24:mi:ss')       
    order by CREATE_TS DESC, TRX_ID DESC
) where rownum <= 20


Oracle сгенерировал такой план ge.tt/3uUd44b/v/0?c
Работает замечательно. Отмечу, что OUT_SMS секционированная таблица по TRX_ID полю, а OUT_SMS_CREATE_TS_TRX_ID_IX секционированный индекс по CREATE_TS DESC, TRX_ID DESC.

Но если я сделаю из этого запроса prepared statement:

select rd from (
    select /*+ INDEX(OUT_SMS OUT_SMS_CREATE_TS_TRX_ID_IX) */ rowid rd
    from OUT_SMS     
    where  TRX_ID between ? and ?       
         and CREATE_TS between ? and ?       
    order by CREATE_TS DESC, TRX_ID DESC
) where rownum <= 20


из плана ( ge.tt/3uUd44b/v/1?c ) пропадает COUNT STOPKEY после анализа индекса и oracle сортирует все данные во всех секциях, а надо, чтобы как в первом плане он выбирал по 20 из каждой и затем только сортировал.

Помогите разобраться с проблемой, уже 3 дня никак не могу побороть.

Спасибо.
  • Вопрос задан
  • 3592 просмотра
Подписаться 3 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
iscsi
@iscsi
Посмотрите тут, например.
Ответ написан
agathis
@agathis
Непонятно, кстати, откуда в первом плане эстимейт в 312 миллионов строк, если партиций всего 48 и из каждой по 20 строк.

А вообще это не новость, что план с литеральными переменными обычно чуть (или даже не чуть) производительнее, чем с bind variables.

Вам тут смотреть в сторону фиксации плана, наверное.
Ответ написан
agathis
@agathis
Ну так план же не самоцель (и Oracle CBO вовсе не такой глупый, например :)).
Я предлагаю посмотреть статистику реального выполнения по buffer gets, и если там все хорошо, расслабиться и получать удовольствие.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы