Как мы оптимизируем базу данных Oracle? - PullRequest
2 голосов
/ 21 октября 2010

У нас есть база данных Oracle 9i с 7 таблицами, каждая из которых содержит более 15 миллионов записей. Между таблицей нет связи, то есть нет внешних ключей.

Вот пример одной из таблиц

CREATE TABLE GSS.SHOWPD
(
  INSERVID          VARCHAR2(7 CHAR)            NOT NULL,
  CAGEPOS           VARCHAR2(8 CHAR)            DEFAULT NULL,
  DETAILEDSTATE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  FAILEDMB          NUMBER                      DEFAULT NULL,
  FREECHUNK         NUMBER                      DEFAULT NULL,
  FREEMB            NUMBER                      DEFAULT NULL,
  FWREV             VARCHAR2(100 CHAR)          DEFAULT NULL,
  FWSTATUS          VARCHAR2(100 CHAR)          DEFAULT NULL,
  AID               NUMBER                      DEFAULT NULL,
  LDA               VARCHAR2(100 CHAR)          DEFAULT NULL,
  MANUF             VARCHAR2(100 CHAR)          DEFAULT NULL,
  AMODEL            VARCHAR2(4000 CHAR)         DEFAULT NULL,
  NODEWWN           VARCHAR2(64 CHAR)           DEFAULT NULL,
  NRMUNUSEDFAIL     VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUNUSEDFREE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUNUSEDUNAVAIL  VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUSEDFAIL       VARCHAR2(100 CHAR)          DEFAULT NULL,
  NRMUSEDOK         VARCHAR2(100 CHAR)          DEFAULT NULL,
  AORDER            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHA0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHA1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHB0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PATHB1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTA0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTA1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTB0            VARCHAR2(100 CHAR)          DEFAULT NULL,
  PORTB1            VARCHAR2(100 CHAR)          DEFAULT NULL,
  RDCERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  REUERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  SERIAL            VARCHAR2(100 CHAR)          DEFAULT NULL,
  SIZEMB            NUMBER                      DEFAULT NULL,
  SPARECHUNK        VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPAREMB           NUMBER                      DEFAULT NULL,
  SPEEDKRPM         VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDFAIL     VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDFREE     VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDUNINIT   VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUSEDFAIL       VARCHAR2(100 CHAR)          DEFAULT NULL,
  SPRUNUSEDOK       VARCHAR2(100 CHAR)          DEFAULT NULL,
  STATE             VARCHAR2(100 CHAR)          DEFAULT NULL,
  TEMPDEGC          NUMBER                      DEFAULT NULL,
  TOTALCHUNK        VARCHAR2(100 CHAR)          DEFAULT NULL,
  ATYPE             VARCHAR2(100 CHAR)          DEFAULT NULL,
  UNAVAILABLEMB     NUMBER                      DEFAULT NULL,
  VOLUMEMB          NUMBER                      DEFAULT NULL,
  WRCERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  WRUERR            VARCHAR2(100 CHAR)          DEFAULT NULL,
  COMMANDTIMESTAMP  TIMESTAMP(6)                DEFAULT NULL  NOT NULL,
  FETCHTIMESTAMP    TIMESTAMP(6)                DEFAULT NULL  NOT NULL
)

Обратите внимание, что INSERVID может быть одним из 1400 типов. Таким образом, можно сказать, 1400 таблиц, каждая из которых посвящена одному inserv. Это было бы безумием? Интересно.

Мы перебираем количество инсервов и выполняем все наши запросы к ним. Прямо сейчас мы очищаем данные, поэтому не ожидаем, что они превысят 15 миллионов записей.

1) Мы различаем запросы, поэтому требуется полное сканирование таблицы. План выполнения Oracle показывает, что мы выполняем довольно полное сканирование таблицы.

select distinct(inservid),commandtimestamp from statpd order by commandtimestamp desc;

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |   665 | 13300 | 79488 |
|   1 |  SORT UNIQUE         |             |   665 | 13300 | 69088 |
|   2 |   TABLE ACCESS FULL  | STATPD      |  4128K|    78M| 19406 |
--------------------------------------------------------------------
Note: cpu costing is off
10 rows selected.

2) Каждая таблица имеет индекс по идентификатору inserv. Это помогло снизить стоимость запросов, что мы можем сделать дальше? Какие-нибудь подсказки / уловки, чтобы сделать вещи быстрее?

3) Имеет ли смысл, если мы создадим наши sql-запросы, которые запускаются для каждой таблицы как параллельные сценарии, работающие для каждой таблицы. Приведет ли это к более быстрому завершению?

4) У нас достаточно ОЗУ для загрузки всей БД в память. Возможно ли это сделать с помощью ORACLE.

Заранее спасибо

Ответы [ 4 ]

5 голосов
/ 21 октября 2010

1-2) Наличие индекса на (inservid,commandtimestamp) заменит FULL TABLE SCAN на (FAST) FULL INDEX SCAN, так как один из двух столбцов НЕ равен NULL (следовательно, БД может использовать индекс вместо таблицы),Это должно быть быстрее, чем полное сканирование таблицы, но будут прочитаны все записи индекса более 15 миллионов строк.

Вы можете получить более быстрое время отклика с предварительно вычисленной таблицей (например, с быстрым обновлением материализованного представления), в этом случае вы, вероятно, нанесете удар по производительности при выполнении операций DML на таблице (вставка / обновление / удаление приведетбудьте медленнее)

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

4) загрузка в ОЗУ в основном выполняется автоматически в Oracle: т.е. в большинстве случаев Oracle хорошо справляется с размещением часто используемых данныхв памяти.

2 голосов
/ 21 октября 2010

Часть 4, обычно это не обязательно. В 9i вы можете настроить специальный буферный пул «keep», чтобы попытаться сохранить ваши индексы в памяти. (но из-за отсутствия поддержки от Oracle сейчас, возможно, сейчас не время начинать экспериментировать с функциями, которые вы до сих пор не использовали)

Находятся ли ваши клиенты на локальном компьютере, если не клиент может воспользоваться преимуществом клиентского кэша 11g (боковой "кэш результатов), чтобы минимизировать количество обращений к серверу базы данных.

Выдержка из руководства по настройке производительности баз данных Oracle® 11g, выпуск 2 (11.2), номер детали E16638-03

7.6.2.1 Как работает клиентский кэш результатов Кэш результатов клиента хранит результаты самого внешнего запроса, которые являются столбцами, определенными приложением OCI. Подзапросы и блоки запросов не кэшируются.

На рисунке 7-4 показан клиентский процесс с сеансом входа в базу данных. Этот клиентский процесс имеет один клиентский кэш результатов, общий для нескольких сеансов приложений, запущенных в клиентском процессе. Если первый сеанс приложения выполняет запрос, он извлекает строки из базы данных и кэширует их в кэше результатов клиента. Если другие сеансы приложения выполняют тот же запрос, они также получают строки из кэша результатов клиента.

alt text

1 голос
/ 21 октября 2010

на 1), 4) я согласен с Винсентом.

на 2) у вас длинные ряды - так что может быть неплохо иметь больший размер db_block_size - 16 КБ или 32 КБ, и, возможно, стоит попробоватьсжать на вашем столе.также проверьте ваш db_file_multiblock_read_count.возможно, это разделение - распределите его на столько дисков, сколько у вас есть.

3) вы можете играть с параллельной подсказкой, чтобы посмотреть, как это будет.

0 голосов
/ 24 октября 2010

Ваша модель данных повреждена. Можете ли вы предоставить более подробную информацию о выполняемых вами запросах? Добавление индексов поможет вам только до определенной точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...