Мой запрос выполняется быстрее во второй раз, как мне это прекратить?

Я запускаю запрос в oracle 10 select A from B where C = D B имеет миллионы записей и нет индекса на C

При первом запуске он занимает около 30 секунд, во второй раз, когда я запускаю запрос, он занимает около 1 секунды.

Очевидно, что он кэширует что-то, и я хочу, чтобы он прекратил это, каждый раз, когда я запускаю запрос, я хочу, чтобы он занял 30 секунд - так же, как он запускался в первый раз.

  • Я слишком упрощаю вопрос, который у меня есть, чтобы сделать вопрос понятным.

Спасибо

Ответ 1

Очистка кэшей для измерения производительности возможна, но очень громоздка.

Очень хорошая мера для отслеживания достигнутых результатов работы по настройке - подсчет количества блоков чтения во время выполнения запроса. Один из самых простых способов сделать это - использовать sqlplus с autotrace, например:

set autotrace traceonly
<your query>

выходы

...
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        363  bytes sent via SQL*Net to client
        364  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Число прочитанных блоков, будь то из кеша или с диска, равно consistent gets.

Другим способом является выполнение запроса с увеличенной статистикой, то есть с подсказкой gather_plan_statistics, а затем просмотр плана запроса из кеша курсора:

auto autotrace off
set serveroutput off
<your query with hint gather_plan_statistics>
select * from table(dbms_xplan.display_cursor(null,null,'typical allstats'));

Число прочитанных блоков выводится в столбце buffers.

---------------------------------------------------------------------------------------------------------------------
| Id  | Operation        | Name           | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                |      3 |        |     1 (100)|          |      3 |00:00:00.01 |       3 |
|   1 |  SORT AGGREGATE  |                |      3 |      1 |            |          |      3 |00:00:00.01 |       3 |
|   2 |   INDEX FULL SCAN| ABCDEF         |      3 |    176 |     1   (0)| 00:00:01 |    528 |00:00:00.01 |       3 |
---------------------------------------------------------------------------------------------------------------------

Ответ 2

Смотрите question...

Он показывает, как очищать кеши для данных и планов выполнения, но также расширяется, является ли это хорошей идеей или нет.

Ответ 3

Очевидным ответом является то, что каждый тестовый пример запускает запрос несколько раз и выдает первый результат.

Нелегко полностью реплицировать условия первого запуска запроса из-за различных используемых кэшей: некоторые из них - кеши Oracle (курсор, буфер и т.д.); некоторые из них - OS (дисковый кэш, в зависимости от конфигурации Oracle); некоторые из них являются аппаратными (SAN, RAID, диск).

Перезагрузка сервера базы данных перед каждым испытанием, вероятно, будет близка к согласованным условиям.