2009-02-26 4 views
1

(База данных: Oracle 10G R2)Вставки 4x медленнее, если таблица имеет много записей (400K) в сравнении, если он пустой

занимает 1 минуту, чтобы вставить 100000 записей в таблицу. Но если таблица уже содержит некоторые записи (400K), то это занимает 4 минуты и 12 секунд; также CPU-wait вскакивает вверх и «Free Buffer Waits» становится очень высоким (с dbconsole).

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

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


Это вставка заявление:

 
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', '[email protected]' 
       ); 
    end loop; 
end; 

Здесь dstat выход (ЦП, ввода-вывода, память, нетто):

  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).

ответ

4

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

+0

Вы правы. Я проверил эту теорию, сбросив индексы, и теперь я не вижу CPU Wait. Посмотрите мое последнее обновление в описании, которое содержит более подробную информацию. –

0

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

-1

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

1

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

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

1

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

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

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


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

+0

Спасибо, что попробовали. По крайней мере, проблема ввода-вывода должна была быть последовательной для вставки первых 100K и Last 100K, но это не так, и именно поэтому я был в замешательстве. Хотя я все еще не понял причину. Я не понимаю, почему I/O станет настолько проблематичным для последнего случая. –

0

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

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

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

1

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

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

Более подробная информация здесь: Oracle/PLSQL: Sequences (Autonumber)

+0

Спасибо Мэтт. Это верно, что кеширование последовательности улучшает производительность. Фактически, в одной из более ранних оптимизаций мы смогли добиться 30% -ного улучшения производительности путем кэширования последовательности, что стало настоящим сюрпризом. –

 Смежные вопросы

  • Нет связанных вопросов^_^