Вставки медленнее в 4 раза, если в таблице много записей (400 КБ), если она пуста - PullRequest
2 голосов
/ 26 февраля 2009

(база данных: Oracle 10G R2)

Вставка 100 000 записей в таблицу занимает 1 минуту. Но если таблица уже содержит несколько записей (400 КБ), то это занимает 4 минуты и 12 секунд; также увеличивается ожидание CPU, и «ожидания свободного буфера» становятся действительно высокими (из dbconsole).

Вы знаете, что здесь происходит? Это из-за частых экстентов таблицы? Размер экстента для этих таблиц составляет 1 048 576 байт. У меня ощущение, что БД пытается расширить таблицу хранения.

Я действительно смущен этим. Так что любая помощь будет отличной!


Это оператор вставки:

begin
  for i in 1 .. 100000 loop
    insert into customer
                (id, business_name, address1,
                 address2, city,
                 zip, state, country, fax,
                 phone, email
                )
         values (customer_seq.nextval, dbms_random.string ('A', 20), dbms_random.string ('A', 20),
                 dbms_random.string ('A', 20), dbms_random.string ('A', 20),
                 trunc (dbms_random.value (10000, 99999)), 'CA', 'US', '798-779-7987',
                 '798-779-7987', 'asdfasf@asfasf.com'
                );
  end loop;
end;

Здесь dstat выход (CPU, IO, MEMORY, NET) для:

  1. Пустые таблицы вставок: http://pastebin.com/f40f50dbb
  2. Таблица с 400K записями: http://pastebin.com/f48d8ebc7

Вывод из v$buffer_pool_statistics


ID:                       3
NAME:                     DEFAULT
BLOCK_SIZE:               8192
SET_MSIZE:                4446
CNUM_REPL:                4446
CNUM_WRITE:               0
CNUM_SET:                 4446
BUF_GOT:                  1407656
SUM_WRITE:                1244533
SUM_SCAN:                 0
FREE_BUFFER_WAIT:         93314
WRITE_COMPLETE_WAIT:      832
BUFFER_BUSY_WAIT:         788
FREE_BUFFER_INSPECTED:    2141883
DIRTY_BUFFERS_INSPECTED:  1030570
DB_BLOCK_CHANGE:          44445969
DB_BLOCK_GETS:            44866836
CONSISTENT_GETS:          8195371
PHYSICAL_READS:           930646
PHYSICAL_WRITES:          1244533


UPDATE

Я удалил индексы из этой таблицы, и производительность значительно улучшилась даже при вставке 100K в таблицу записей 600K (на это ушло 47 секунд без ожидания процессора - см. Вывод dstat http://pastebin.com/fbaccb10).

Ответы [ 7 ]

5 голосов
/ 26 февраля 2009

Не уверен, что это одинаково в Oracle, но в SQL Server первым делом я проверю, сколько индексов у вас в таблице. Если это много, БД должна проделать большую работу по переиндексации таблицы при вставке записей. Переиндексировать 500 тыс. Строк труднее, чем 100 тыс.

1 голос
/ 01 марта 2009

Еще один прием для повышения производительности - включить или установить кэш выше в вашей последовательности (customer_seq). Это позволит оракулу размещать последовательность в памяти вместо того, чтобы поразить объект для каждой вставки.

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

Больше информации здесь: Oracle / PLSQL: последовательности (Autonumber)

1 голос
/ 26 февраля 2009

Даже с индексами, 4 минуты для вставки 100 000 записей кажутся мне проблемой.

Если в этой базе данных есть проблемы с вводом / выводом, вы их не исправили, и они появятся снова. Я бы порекомендовал вам определить основную причину.

Если вы разместите индекс DDL, я опишу его для сравнения.


Я добавил индексы для id и business_name. При выполнении 10 итераций в цикле среднее время на 100 000 строк составляло 25 секунд. Это было на моем домашнем ПК / сервере, все работали на одном диске.

1 голос
/ 26 февраля 2009

Индексы представляют собой некоторую форму дерева, что означает, что время для вставки записи будет O (log n), где n - размер дерева (≈ количество строк для стандартного уникального индекса).

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

0 голосов
/ 28 февраля 2009

Вы не говорите, какие столбцы индексируются. Если бы у вас были индексы по факсу, телефону или электронной почте, у вас было бы МНОГО дубликатов (т.е. каждая строка). Oracle «притворяется» иметь неуникальные индексы. В действительности каждая запись индекса уникальна, и решающим фактором является rowid фактической строки таблицы. Rowid состоит из файла / блока / записи.

Возможно, что после того, как вы нажмете определенное количество записей, новые получат rowids, а это значит, что их нужно было вписать в середину существующих индексов с продолжительной перепиской индекса.

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

0 голосов
/ 26 февраля 2009

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

0 голосов
/ 26 февраля 2009

Сортированные вставки всегда занимают больше времени, чем больше записей в таблице.

...