Я пытаюсь получить последние 20 строк по времени для пользователей с более чем 100K строк в таблице с более чем 1 миллионом записей. Производительность запроса прекрасна (в мс), когда пользователь имеет небольшое количество записей. Но для получения 20 записей для пользователей с записями 10K-100K требуется более 2 минут.Oracle 11g - top Порядок N медленный
Вот запрос:
select * from (select * from TABLE1
where USER_ID= 41063660 and
COL1=0 and COL2 = 0
order by LAST_EVENT_DATE desc) where rownum <= 20 ;
Существует индекс (I_LASTEVENTDT) на (USER_ID, COL1, COL2, LAST_EVENT_DATE DESC)
Вот объяснить план:
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 38960 | | 66959 (1)| 00:13:24 |
|* 1 | COUNT STOPKEY | | | | | | |
| 2 | VIEW | | 65500 | 121M| | 66959 (1)| 00:13:24 |
|* 3 | SORT ORDER BY STOPKEY | | 65500 | 96M| 102M| 66959 (1)| 00:13:24 |
| 4 | TABLE ACCESS BY INDEX ROWID| TABLE1 | 65500 | 96M| | 47280 (1)| 00:09:28 |
|* 5 | INDEX RANGE SCAN | I_LASTEVENTDT | 65500 | | | 309 (0)| 00:00:04 |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=20)
3 - filter(ROWNUM<=20)
5 - access("USER_ID"=41063660 AND "COL1"=0 AND
"COL2"=0)
Я попытался следовать примеру, указанному на http://use-the-index-luke.com/sql/sorting-grouping/indexed-order-by
Я пробовал создавая отдельный индекс (USER_ID, COL1, COL2) и (LAST_EVENT_DT DESC), а также попытался индексировать (USER_ID, LAST_EVENT_DT DESC). Производительность была хуже для обоих, хотя для последнего индекса он избавился от порядка сортировки.
Как получить лучшую производительность по этому запросу?
Заранее спасибо.
В плане объяснения говорится, что запрос занял всего 15 секунд для строк 65K (надеюсь, я не ошибаюсь). Почему вы говорите, что требуется 2 минуты? Вы делаете больше обработки до и после запроса? – sstan
План показывает 13 минут, а не 15 секунд и является лишь приблизительной оценкой. Он занимает 2 минуты + в зависимости от количества выбранных строк, когда я запускаю его из своего приложения. – user2755442
К сожалению. Спасибо, что разъяснил это. Только для целей исследования вы попробовали добавить подсказку 'FIRST_ROWS' к вашему запросу? Изменяет ли он план объяснений? – sstan