У нас есть база данных 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.
Заранее спасибо