Отправляет email-рассылки с помощью сервиса Sendsay

Открыто о СУБД Oracle на русском

  Все выпуски  

Открыто о СУБД Oracle на русском : сброс буферного кэша и другие распространенные заблуждения


Информационный Канал Subscribe.Ru

Выпуск 28

Сброс буферного кэша и распространенные заблуждения

Уважаемые подписчики! Хочу обратить ваше внимание на еще один свой проект, Хроника бегства от безопасности". Очередной блог, но, вдруг кому-то интересно, чем я занимаюсь каждый день...

А этот выпуск посвящен сбросу содержимого буферного кэша и типичным заблуждениям, связанным с настройкой производительности приложений Oracle. Последний раз Том Кайт вернулся к этому вопросу 21 января 2003 года.

Как сбросить буферный кэш

Том!

Оператор ALTER SYSTEM FLUSH SHARED_POOL позволяет сбросить содержимое разделяемого пула. А нет ли способа сбросить все блоки из буферного кэша? Это необходимо при настройке, когда последовательно применяются различные методы настройки и хотелось бы уменьшить влияние наличия необходимых блоков в буферном кэше, не прибегая к перезапуску экземпляра.

Ответ Тома Кайта

На самом деле, при настройке этого делать как раз НЕ НАДО...

Надо запустить тест, проигнорировать результаты, запустить его еще два или три раза, и записать средние результаты (показатели производительности).

В реальном мире буферный кэш никогда не будет пуст.

При настройке надо заботиться о сокращении количества операций логического ввода-вывода -- о физическом вводе-выводе позаботится сам сервер.

Сброс разделяемого пула и буферного кэша создает более "искусственные" условия, чем выполнение последовательности тестов БЕЗ сброса.

В любом случае, поскольку этого совера все равно никто не слушает  -- подозреваю, потому, что он противоречит распространенному заблуждению  -- я расскажу вам, как это сделать. Просто отключите (offline) и снова включите (online) соответствующее табличное пространство (Но это будет искусственное, надуманное действие!!! Да и вообще неверное.)

Позвольте продемонстрировать, как это сделать, и ПОЧЕМУ это бессмыссленно. У меня есть небольшая C-программа flushcache, выделяющая всю память на ноутбуке и проверяющая ее, а затем сбрасывающая кэш ОС и выполняющая ряд весьма деструктивных действий:

 
big_table@ORA920> select count(data_object_id) from big_table; 
 
1 row selected. 
 
Elapsed: 00:00:01.10 
 
Execution Plan 
---------------------------------------------------------- 
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1329 Card=1 Bytes=2) 
   1    0   SORT (AGGREGATE) 
   2    1     TABLE ACCESS (FULL) OF 'BIG_TABLE' (Cost=1329 Card=1000000 Bytes=2000000) 
 
Statistics 
---------------------------------------------------------- 
          0  recursive calls 
          0  db block gets 
      13656  consistent gets 
      13646  physical reads 
          0  redo size 
        394  bytes sent via SQL*Net to client 
        499  bytes received via SQL*Net from client 
          2  SQL*Net roundtrips to/from client 
          0  sorts (memory) 
          0  sorts (disk) 
          1  rows processed 
 
big_table@ORA920> alter tablespace users offline; 
 
Tablespace altered. 
 
Elapsed: 00:00:00.05 
big_table@ORA920> alter tablespace users online; 
 
Tablespace altered. 
 
Elapsed: 00:00:00.03 
big_table@ORA920> !flushcache; 
allocated 512m of ram 0x4212F008 
touching it all.................done... 
 
big_table@ORA920> select count(data_object_id) from big_table; 
 
1 row selected. 
 
Elapsed: 00:00:12.03 
 
Execution Plan 
---------------------------------------------------------- 
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1329 Card=1 Bytes=2) 
   1    0   SORT (AGGREGATE) 
   2    1     TABLE ACCESS (FULL) OF 'BIG_TABLE' (Cost=1329 Card=1000000 Bytes=2000000) 
 
Statistics 
---------------------------------------------------------- 
          0  recursive calls 
          0  db block gets 
      13656  consistent gets 
      13646  physical reads 
          0  redo size 
        394  bytes sent via SQL*Net to client 
        499  bytes received via SQL*Net from client 
          2  SQL*Net roundtrips to/from client 
          0  sorts (memory) 
          0  sorts (disk) 
          1  rows processed 
 
big_table@ORA920> select count(data_object_id) from big_table; 
 
1 row selected. 
 
Elapsed: 00:00:01.10 
 
Execution Plan 
---------------------------------------------------------- 
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1329 Card=1 Bytes=2) 
   1    0   SORT (AGGREGATE) 
   2    1     TABLE ACCESS (FULL) OF 'BIG_TABLE' (Cost=1329 Card=1000000 Bytes=2000000) 
 
Statistics 
---------------------------------------------------------- 
          0  recursive calls 
          0  db block gets 
      13656  consistent gets 
      13645  physical reads 
          0  redo size 
        394  bytes sent via SQL*Net to client 
        499  bytes received via SQL*Net from client 
          2  SQL*Net roundtrips to/from client 
          0  sorts (memory) 
          0  sorts (disk) 
          1  rows processed 

Ну, и как это может быть? Так 1 секунду или 12 секунд надо для выполнения 13656 операций физического ввода-вывода?

На самом деле, это зависит от...

Вы готовы перегружать сервер после каждого запроса? Вероятно, нет. Но сброс буферного кэша будет действием не менее искусственным.

Делать надо так:

Выполняем тест один раз.
Выполняем его снова, многократно, записывая время выполнения каждой попытки.

Как в старой поговорке: "Копейка рубль бережет" -- если сократить количество операций логического ввода-вывода, о физическом вводе-выводе позаботится сам сервер.

Комментарий читателя от 20 января 2003 года

Я согласен, что логический ввод-вывод важнее, и именно за его объемом и надо следить для получения максимально достоверных результатов. Мне просто надо было доказать руководству глупость идей по технологии настройки производительности, которые я считал глупыми. Но, это уже другая проблема...

Мне непонятно, почему количество операций физического ввода-вывода одинаково в обоих операторах select count(object_id) from big_table. При первом вызове, после выполнения программы flushcache, я понимаю, что физический ввод-вывод нужен. Однако, при следующем вызове, не доложны ли блоки браться из буферного кэша? Почему опять выполняется физический ввод-вывод?

Ответ Тома Кайта

На моем ноутбуке буферного кэша не хватает, чтобы вместить все блоки. 13K блоков его полностью сбросили.

Комментарий читателя от 21 января 2003 года

Том, в ответе на предыдущий комментарий ты упомянул, что один и тот же объем физического ввода-вывода пришлось выполнять потому, что буферный кэш на 13K блоков меньше, чем таблица. Мне казалось, что при полном просмотре не кэшированной таблицы сервер Oracle читает блоки в наиболее недавно использованную (LRU) часть буферного кэша порциями по DB_MULTI_BLOCK_READ_COUNT + 1 блок. Поэтому, в данном случае, ПРИ КАЖДОМ повторном запросе count, серверу и приходится выполнять один и тот же объем физического ввода-вывода для получения результата.

Может ли различие времени выполнения быть связано с загрузкой блокой в кэш диска?

Ответ Тома Кайта

13K - это количество блоков. Буфер не на 13K меньше, просто прочитать надо 13000 блоков.

Читая 13000 блоков, я полностью прокручиваю их через буферный кэш, и снова переписывааю его. К моменту прочтения последнего блока таблицы, первого блока в буферном кэше уже нет. Вот что я имел ввиду.

Да, при каждом выполнении оператора каждый блок придется читать физической операцией ввода-вывода.

Различие по времени (как я пытался показать) было связано именно с этим. Я сбросил буферный кэш ОС, выделив и изменив каждый байт ОЗУ на диске. Я пытался продемонстрировать, что в большинстве систем, простой сброс буферного кэша -- действие из серии "да, ну и что". Оно никак не помогает в настройке -- это сбивает с толку и попросту бессмыссленно.

Хороший совет по настройке!

Я всегда считал такой метод настройки лучшим! Спасибо, что подсказал и доказал обратное!

Ответ Тома Кайта

Другие распространенные заблуждения (на 100% ошибочные представления):

  • Использование индексов означает быстрое выполнение запросов. Если оптимизатор их не использует, значит, это ошибка оптимизатора.
  • Индексы надо часто, лучше - регулярно пересоздавать.
  • После пересоздания индексы получаются быстрее, меньше по размеру и лучше.
  • В сегментах должно быть как можно меньше экстентов -- десятки экстентов существенно снижают производительность.
  • Все курсоры в PL/SQL-коде должны быть явными. Неявные курсоры работают медленно и плохо.
  • Оператор select count(1) лучше, чем select count(*).
  • Процедурный код работает быстрее, чем соответствующий SQL-оператор.
  • Добавление процессоров ускоряет работу систем.
  • Конструкция nologging прекращает генерацию всех данных повторного выполнения для соответствующего сегмента.
  • Наиболее избирательные столбцы надо указывать в индексе первыми.
  • Транзакции надо фиксировать часто - это экономит ресурсы и время.
  • Холодное резервное копирование лучше теплого.

Оригинал обсуждения этого вопроса можно найти здесь.


Copyright © 2003 Oracle Corporation


В следующем выпуске

Скорее всего, перевод второй статьи из серии публикаций Джонатана Льюиса, посвященных индексам на основе битовых карт. Или перевод очередного блестящего ответа Тома Кайта... Следите за новостями на сайте проекта Open Oracle.

С наилучшими пожеланиями,

  В.К.



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное