2014-11-05 5 views
0

Я после некоторых совет пожалуйста.Оператор PostgreSQL CASE требует индексов?

Я написал инструкцию CASE для заполнения нового поля. Для таблицы базы данных, содержащей более 300 миллионов записей, это заняло около 12 часов.

UPDATE line 
    SET code = (CASE 
     WHEN (group ='{Building}' and term = '{Outline}') then 1 
     WHEN (group ='{Building}' and term = '{Division}') then 2 
     WHEN (group ='{Building}' and term = '{Partial}') then 3 
    ELSE 99   
    END) 
    WHERE code is null; 

Что я могу сделать, чтобы увеличить производительность?

Должен ли я добавить индекс в столбец кода перед запуском оператора case, чтобы он быстрее мог найти записи, которые имеют значение кода NULL.

Или я должен создавать индексы для групп столбцов и «термин», чтобы ускорить его.

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

Спасибо за любые советы

EDIT Дополнительной информацией

Am с использованием PostgreSQL 9.2 64Bit на Windows 2008 Server Я использовал вика PostgreSQL Tuning и оптимизировал файл postgresql.conf я сделал ВАКУУМЫ И АНАЛИЗЫ на столе

+1

http://wiki.postgresql.org/wiki/SlowQueryQuestions Но индекс на 'code' поможет.Если имеется относительно немного строк, где код является нулевым, то, возможно, даже неполный индекс с условием 'where code is null ' –

+0

Вы можете использовать отдельные запросы: UPDATE line SET code = 1 где group =' {Building} 'и term = '{Outline}', а код - null; UPDATE line SET code = 2 где group = '{Building}' и term = '{Division}', а код - null; UPDATE line SET code = 3 где group = '{Building}' и term = '{Partial}', а код - null; UPDATE line SET code = 99, где код равен NULL; Можете ли вы предоставить результаты EXPLAIN для каждого запроса? –

+0

@VitaliyPro «Обновление по строке (стоимость = 0,00..48847898,66 строк = 41740 ширина = 996)» »-> Seq Сканирование в строке (стоимость = 0,00..48847898,66 строк = 41740 ширина = 996)« »Фильтр: ((код IS NULL) AND (group = '{Building}' :: character variableing []) AND (term = '{Outline}' :: character variableing []))) " – tjmgis

ответ

3

Индекс на code не поможет в заявлении case, но это поможет where. На самом деле существует «отдача и принятие», поскольку индекс необходимо обновить, а также исходные данные. Итак, если все значения code, где NULL, индекс не будет быстрее.

Индекс по group и termпоможет, если вы разделить это на отдельные обновления:

UPDATE line 
    SET code = 1 
    WHERE code is null and group = '{Building}' and term = '{Outline}'; 

На самом деле, индекс, который вы хотите, line(code, group, term) для них.

0

, если у вас есть большое количество строк, попробуйте:

Редактировать postgresql.conf и увеличить checkpoint_segments до 10 или более (> = пространство 300Mio записей вашей таблицы) увеличения wal_buffers к 16MB (или больше)

вы также можете получить более высокую производительность при переключении
FSYNC от , но у вас есть риск потерять данные!

Индекс по коду ускорит обновление (см. Документ): «Кроме того, условие IS NULL или IS NOT NULL для столбца индекса может использоваться с индексом B-дерева».

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