Oracle очистить кэш запросов
А этот выпуск посвящен сбросу содержимого буферного кэша и типичным заблуждениям, связанным с настройкой производительности приложений Oracle. Последний раз Том Кайт вернулся к этому вопросу 21 января 2003 года.
Ответ Тома Кайта
На самом деле, при настройке этого делать как раз НЕ НАДО.
Надо запустить тест, проигнорировать результаты, запустить его еще два или три раза, и записать средние результаты (показатели производительности).
В реальном мире буферный кэш никогда не будет пуст.
При настройке надо заботиться о сокращении количества операций логического ввода-вывода -- о физическом вводе-выводе позаботится сам сервер.
Сброс разделяемого пула и буферного кэша создает более "искусственные" условия, чем выполнение последовательности тестов БЕЗ сброса.
В любом случае, поскольку этого совера все равно никто не слушает -- подозреваю, потому, что он противоречит распространенному заблуждению -- я расскажу вам, как это сделать. Просто отключите (offline) и снова включите (online) соответствующее табличное пространство (Но это будет искусственное, надуманное действие. Да и вообще неверное .)
Позвольте продемонстрировать, как это сделать, и ПОЧЕМУ это бессмыссленно . У меня есть небольшая C-программа flushcache , выделяющая всю память на ноутбуке и проверяющая ее, а затем сбрасывающая кэш ОС и выполняющая ряд весьма деструктивных действий:
Ну, и как это может быть? Так 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.
On oracle 10gr2, I have several sql queries that I am comparing performance. But after their first run, the v$sql table has the execution plan stored for caching, so for one of the queries I go from 28 seconds on first run to .5 seconds after.
ALTER SYSTEM FLUSH BUFFER_CACHE;
After running this, the query consistently runs at 5 seconds, which I do not believe is accurate.
Thought maybe deleting the line item itself from the cache:
delete from v$sql where sql_text like 'select * from.
but I get an error about not being able to delete from view.
восемь различных способов очистки кэша плана
3. Очистите специальный и подготовленный кэш плана для всего экземпляра
6. Удаляет все элементы из кэша планов для одной базы данных (не работает в SQL Azure)
2 Answers 2
EDIT: See this thread on asktom, which describes how and why not to do this.
If you are in a test environment, you can put your tablespace offline and online again:
but again only on test environment.
When you test on your "real" system, the times you get after first call (those using cached data) might be more interesting, as you will have cached data. Call the procedure twice, and only consider the performance results you get in subsequent executions.
flushing before the call I got some interesting results like: 1370,354,391,375,352,511,390,375,326,335,435,334,334,328,337,314,417,377,384,367,393. I'll study more about it tomorrow and I'll say my results. Thanks!
Hello @Peter Lang, my tables are at system tablespace, so I can't put offline. However I not understand why I should do this? Do you can explain or suggest a good lecture? Thanks.
Probably my Oracle 10g is making a inappropriate caching.
Actually it seems like Oracle is doing some entirely appropriate caching. If these tables are going to be used a lot then you would hope to have them in cache most of the time.
edit
In a comment on Peter's response Luis said
flushing before the call I got some interesting results like: 1370,354,391,375,352,511,390,375,326,335,435,334,334,328,337,314,417,377,384,367,393.
These findings are "interesting" because the flush means the calls take a bit longer than when the rows are in the DB cache but not as long as the first call. This is almost certainly because the server has stored the physical records in its physical cache. The only way to avoid that, to truely run against an empty cache is to reboot the server before every test.
Alternatively learn to tune queries properly. Understanding how the database works is a good start. And EXPLAIN PLAN is a better tuning aid than the wall-clock. Find out more.
первый раз, когда я выполняю запрос, может занять > 15 secs . Последующие выполнения возвращаются в < 1 sec .
как заставить SQL Server 2005 не использовать кэшированные результаты? Я пробовал бежать
но это, похоже, не влияет на скорость запроса (все еще < 1 sec ).
вот некоторые хорошие объяснения. зацени.
из связанной статьи:
Если все тестирование производительности проводится в SQL Server, лучшим подходом может быть выдача контрольной точки, а затем команда DBCC DROPCLEANBUFFERS. Хотя процесс контрольных точек является автоматическим внутренним системным процессом в SQL Server и происходит регулярно, важно, чтобы эту команду писать все "грязные" страницы в текущей базе данных на диск и очистки буферов. Затем можно выполнить команду DBCC DROPCLEANBUFFERS для удаления всех буферов из пула буферов.
хотя вопрос немного устарел, это все равно может помочь. Я сталкиваюсь с подобными проблемами, и использование опции ниже помогло мне. Не уверен, что это постоянное решение, но пока оно исправляет его.
тогда ваш запрос будет выглядеть следующим образом
какое значение вы указываете для памяти сервера, не важно, если оно отличается от текущего.
кстати, то, что вызывает ускорение, - это не кэш запросов, а кэш данных.
5. Очистите весь кэш плана для одного пула ресурсов
1. Удалите все элементы из кэша плана для всего экземпляра
используйте это, чтобы очистить кэш плана тщательно. Освобождение кэша плана приводит, например, к перекомпиляции хранимой процедуры вместо повторного использования из кэша. Это может привести к внезапному временному снижению производительности запросов.
3 Answers 3
Peter gave you the answer to the question you asked.
That is the statement you would use to "delete prepared statements from the cache".
(Prepared statements aren't the only objects flushed from the shared pool, the statement does more than that.)
As I indicated in my earlier comment (on your question), v$sql is not a table. It's a dynamic performance view, a convenient table-like representation of Oracle's internal memory structures. You only have SELECT privilege on the dynamic performance views, you can't delete rows from them.
flush the shared pool and buffer cache?
The following doesn't answer your question directly. Instead, it answers a fundamentally different (and maybe more important) question:
Should we normally flush the shared pool and/or the buffer cache to measure the performance of a query?
In short, the answer is no.
I think Tom Kyte addresses this pretty well:
Actually, it is important that a tuning tool not do that. It is important to run the test, ignore the results, and then run it two or three times and average out those results. In the real world, the buffer cache will never be devoid of results. Never. When you tune, your goal is to reduce the logical I/O (LIO), because then the physical I/O (PIO) will take care of itself.
Consider this: Flushing the shared pool and buffer cache is even more artificial than not flushing them. Most people seem skeptical of this, I suspect, because it flies in the face of conventional wisdom. I'll show you how to do this, but not so you can use it for testing. Rather, I'll use it to demonstrate why it is an exercise in futility and totally artificial (and therefore leads to wrong assumptions). I've just started my PC, and I've run this query against a big table. I "flush" the buffer cache and run it again:
I think Tom Kyte is exactly right. In terms of addressing the performance issue, I don't think that "clearing the oracle execution plan cache" is normally a step for reliable benchmarking.
Let's address the concern about performance.
You tell us that you've observed that the first execution of a query takes significantly longer (~28 seconds) compared to subsequent executions (~5 seconds), even when flushing (all of the index and data blocks from) the buffer cache.
To me, that suggests that the hard parse is doing some heavy lifting. It's either a lot of work, or its encountering a lot of waits. This can be investigated and tuned.
I'm wondering if perhaps statistics are non-existent, and the optimizer is spending a lot of time gathering statistics before it prepares a query plan. That's one of the first things I would check, that statistics are collected on all of the referenced tables, indexes and indexed columns.
If your query joins a large number of tables, the CBO may be considering a huge number of permutations for join order.
A discussion of Oracle tracing is beyond the scope of this answer, but it's the next step.
I'm thinking you are probably going to want to trace events 10053 and 10046.
Here's a link to an "event 10053" discussion by Tom Kyte you may find useful:
A few years back, I did see one query that had elapsed times in terms of MINUTES on first execution, subsequent executions in terms of seconds. What we found was that vast majority of the time for the first execution time was spent on the hard parse.
This problem query was written by a CrystalReports developer who innocently (naively?) joined two humongous reporting views.
One of the views was a join of 62 tables, the other view was a join of 42 tables.
The query used Cost Based Optimizer. Tracing revealed that it wasn't wait time, it was all CPU time spent evaluating possible join paths.
Each of the vendor supplied "reporting" views wasn't too bad by itself, but when two of them were joined, it was agonizingly slow. I believe the problem was the vast number of join permutations that the optimizer was considering. There is an instance parameter that limits the number of permutations considered by the optimizer, but our fix was to re-write the query. The improved query only joined the dozen or so tables that were actually needed by the query.
(The initial immediate short-term "band aid" fix was to schedule a run of the query earlier in the morning, before report generation task ran. That made the report generation "faster", because the report generation run made use of the already prepared statement in the shared pool, avoiding the hard parse.
The band aid fix wasn't a real solution, it just moved the problem to a preliminary execution of the query, when the long execution time wasn't noticed.
Our next step would have probably been to implement a "stored outline" for the query, to get a stable query plan.
Of course, statement reuse (avoiding the hard parse, using bind variables) is the normative pattern in Oracle. It mproves performance, scalability, yada, yada, yada.
This anecdotal incident may be entirely different than the problem you are observing.
I'm trying to test the utility of a new summary table for my data.
I got something like this: 1199,84,81,81,81,81,82,80,80,81,81,80,81,91,80,80,81,80
Probably my Oracle 10g is making an inappropriate caching.
How I can solve this?
8. Удалить один план запроса из кэша
обратите внимание, что ни DBCC DROPCLEANBUFFERS; , ни DBCC FREEPROCCACHE; поддерживается в хранилище данных SQL Azure / SQL.
однако, если вам нужно сбросить кэш плана в SQL Azure, вы можете изменить одну из таблиц в запросе (например, просто добавьте, а затем удалите столбец), это будет иметь побочный эффект удаления плана из кэша.
Я лично делаю это как способ тестирования производительности запросов без необходимости иметь дело с кэшированных планов.
иногда я запускаю запрос Postgres, это занимает 30 секунд. Затем я сразу же запускаю тот же запрос, и это занимает 2 секунды. Похоже, что Postgres имеет какое-то кэширование. Могу я как-нибудь увидеть, что в этом тайнике? Могу ли я принудительно очистить все кэши для целей настройки?
Примечание: я в основном ищу версию postgres следующей команды SQL Server:
но я также хотел бы знать, как можно увидеть, что на самом деле содержится в этом буфер.
Спасибо за любую помощь.
вы можете увидеть, что находится в буферном кэше PostgreSQL, используя модуль pg_buffercache. Я сделал презентацию под названием "внутри буферного кэша PostgreSQL
Я не видел никаких команд для очистки кэшей в PostgreSQL. То, что вы видите, скорее всего, просто обычный индекс и кэш данных, считываемые с диска и хранящиеся в памяти. как postgresql, так и кэши в ОС. Чтобы избавиться от всего этого, единственный способ я знаю:
Что вы должны сделать, это:
- завершение работы сервера баз данных (pg_ctl, sudo service postgresql stop, так далее.)
- echo 3 > /proc/sys/vm / drop_caches Это очистит файл/блок ОС Кэш - очень важно, хотя я не знаю, как это сделать на других ОС.
- запустите сервер баз данных
Я использую эту команду в своем окне linux:
Он полностью избавляется от кэша.
ответ Грега Смита о drop_caches был очень полезен. Я счел необходимым остановить и запустить службу postgresql, в дополнение к удалению кэшей. Вот скрипт, который делает трюк. (Моя среда-Ubuntu 14.04 и PostgreSQL 9.3.)
Я тестировал с запросом, который занял 19 секунд в первый раз и менее 2 секунд при последующих попытках. После запуска этого скрипта запрос снова занял 19 секунд.
да, postgresql, безусловно, имеет кэширование. Размер контролируется параметром shared_buffers. Кроме того, как упоминалось в предыдущем ответе, также используется кэш файлов ОС.
Если вы хотите посмотреть, что находится в кэше, есть модуль contrib под названием pg_buffercache доступно (в contrib/ в дереве источника, в contrib RPM или где угодно, где это подходит для того, как вы его установили). Как его использовать, указано в стандарте Документации PostgreSQL.
нет никаких способов очистить кэш буфера, кроме как перезапустить сервер. Вы можете удалить кэш ОС с помощью команды, упомянутой в другом ответе, при условии, что ваша ОС - Linux.
У меня была эта ошибка.
psql:/cygdrive/e / test_insertion.sql: 9: ошибка: тип параметра 53 (t_stat_gardien) не соответствует этому при подготовке плана (t_stat_avant)
Я искал промывку текущего плана и нашел это:
У меня было это между моими вставками, и это решает мою проблему.
здесь pg_buffercache модуль для просмотра shared_buffers кэш. И в какой-то момент мне нужно было удалить кэш, чтобы сделать некоторые тесты производительности на "холодный" кэш, поэтому я написал pg_dropcache расширение, которое делает именно это. Пожалуйста, проверьте это.
да, можно очистить оба общих буфера postgres cache и кэш ОС. Решение bellow для Windows. другие уже дали решение linux.
Как уже говорили многие, чтобы очистить общие буферы, вы можете просто перезапустить Postgres (нет необходимости перезагружать сервер). Но просто это не очистит кэш ОС.
чтобы очистить кэш ОС, используемый Postgres, после остановки службы используйте excelent RamMap (https://technet.microsoft.com/en-us/sysinternals/rammap), из превосходной сюиты Sysinternals. После выполнения RamMap просто нажмите "пустой" - > "пустой список ожидания" в главном меню.
перезапустите Postgres, и вы увидите, что ваш следующий запрос будет медленным из-за отсутствия кэша вообще.
вы также можете выполнить RamMap без закрытия Postgres и, вероятно, будете иметь результаты "без кэша", которые вы хотите, так как, как уже говорили люди, общие буферы обычно дают небольшое влияние по сравнению с кэшем ОС. Но для надежного теста я бы предпочел остановить postgres, как и все, прежде чем очищать кэш ОС, чтобы убедиться.
Примечание: AFAIK, я не рекомендую очищать другие вещи, кроме "списка ожидания" при использовании RamMap, потому что другие данные каким-то образом используются, и вы можете потенциально вызвать проблемы/потерять данные, если вы это сделаете. Помните, что вы очищаете память не только для файлов postgres, но и для любых других приложений и ОС также.
Как сбросить буферный кэш
Оператор ALTER SYSTEM FLUSH SHARED_POOL позволяет сбросить содержимое разделяемого пула. А нет ли способа сбросить все блоки из буферного кэша? Это необходимо при настройке, когда последовательно применяются различные методы настройки и хотелось бы уменьшить влияние наличия необходимых блоков в буферном кэше, не прибегая к перезапуску экземпляра.
7. Очистить кэш плана для текущей базы данных
4. Очистите специальный и подготовленный кэш плана для одного пула ресурсов
Читайте также: