Лучший способ «материализовать взгляд» - PullRequest
4 голосов
/ 02 августа 2009

(PostreSQL 8.2, работает на WindowsXP)

У меня есть множество сложных запросов, на выполнение которых уходит несколько секунд. На самом деле они не являются «взглядами», но могут рассматриваться как таковые.

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

Я могу гарантировать отсутствие изменений данных после расчета таблиц "aux".

Давайте рассмотрим один пример:

Предположим, у меня есть запрос "X", поэтому я сохраняю его результаты в "Table_X". Набор записей примерно такой:

PERSON*     FIELD_A*     FIELD_ B         FIELD_C
=======================================================
1           10           Value1           Value2
1           20           Value3           Value4
1           30           Value5           Value6
------------------------------------------------------
2           10           Value1           Value2
2           20           Value3           Value4
------------------------------------------------------
3           20           Value3           Value4
3           30           Value5           Value6
------------------------------------------------------
etc..

(*)Primary key is: person, field_a

Как видите, у каждого "человека" есть подмножество записей в этой таблице.

Итак, я могу быстро получить его записи только с "select * from table_x where person = <person>".

Я всегда получаю ТОЛЬКО <person>, и все мои запросы имеют одно и то же "лицо": "ЛИЦО" + Some_Fields.

ВАЖНО: Все «вспомогательные» таблицы могут быть прочитаны (очевидно, со «старыми» данными, пока я не выполню фиксацию) другими транзакциями, пока я их «переполняю». Но я могу гарантировать, что эти транзакции никогда не обновляются.

Мой текущий процесс:

- START TRANSACTION;
  - DO A LOTS OF OPERATIONS ON DATABASE. INSERT / UPDATE / DELETE ON SEVERAL TABLES.
  - AFTER THAT, I WILL CALCULATE "AUX" TABLES
  - LOOP THROUGH ALL MY "QUERIES": (WHERE HERE WE CAN CALL AS "X")
    - LOOP TROUGHT ALL "PERSON": (WHERE HERE WE CAN CALL AS <person>)
      - DELETE FROM <TABLE_X> WHERE PERSON = <person>; 
      - INSERT INTO <TABLE_X> (PERSON, FIELD_A, FIELD_B, FIELD_C)
                              (SELECT <person>, 
                                      FIELDS...
                                 FROM "LOTS OF TABLES" 
                                 JOIN "COMPLEX SQL"...
                                WHERE SOME_FIELD = <person>
                              );
    - END LOOP "PERSON"
  - END LOOP "QUERIES"
- COMMIT;

Вопросы:

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

Поскольку удаление и «повторная вставка» вызывает слишком много «дискового ввода-вывода» (это так очевидно), и мне нужно «обновить» только несколько записей, я пытаюсь найти эффективный способ сделать это .

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

Есть предложения?

Ответы [ 2 ]

5 голосов
/ 03 августа 2009

Две стандартные ссылки для создания ваших собственных материализованных представлений с использованием PostgreSQL: PostgreSQL / Материализованные представления и Материализованные представления, которые действительно работают

2 голосов
/ 02 августа 2009

Прежде чем сделать это, запустили ли план объяснения для вашего сложного запроса и добавили индексы для его улучшения?

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

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