PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Излишни данни в изявленията за актуализиране

Поради PostgreSQL MVCC, UPDATE е ефективно много като DELETE плюс INSERT . С забележителното изключение на препечените стойности - вижте:

  • Postgres пренаписва ли целия ред при актуализиране?

(И незначителни разлики за кортежи само за купчина - DELETE + INSERT стартира нова HOT верига - но това няма отношение към случая.)

За да бъдем точни, редът "изтрит" е просто невидим за всяка транзакция, започваща след извършване на изтриването, и е изчистен по-късно. Следователно от страна на базата данни, включително манипулирането на индекса, на практика няма разлика между двете твърдения. (Важни са изключения, продължете да четете.) Увеличава малко мрежовия трафик (в зависимост от вашите данни) и се нуждае от малко анализ.

Проучих HOT актуализации още малко след въвеждането на @araqnid и проведох някои тестове. Актуализациите на колони, които действително не променят стойността, не правят разлика каквото и да е, що се отнася до ГОРЕЩИТЕ актуализации. Моят отговор е валиден. Вижте подробности по-долу.

Това важи и за препечени атрибути, тъй като те също не се докосват, освен ако стойностите действително не се променят .

Въпреки това , ако използвате задействания за колона (въведено с pg 9.0), това може да има нежелани странични ефекти!

Цитирам ръководството за тригери:

... команда като UPDATE ... SET x = x ... ще задейства тригер в колона x , въпреки че стойността на колоната не се е променила .

Удебелен акцент мой.

Абстракционните слоеве са за удобство. Те са полезни за SQL-неграмотни разработчици или ако приложението трябва да бъде преносимо между различни RDBMS. От друга страна, те могат да унищожат представянето и да въведат допълнителни точки на провал. Избягвам ги навсякъде, където е възможно.

ГОРЕЩИ актуализации (кортежи само за купчина)

Кортежите само за купчина бяха въведени с Postgres 8.3, с важни подобрения в 8.3.4 и 8.4.9.
Бележки към версията за Postgres 8.3:

UPDATE s и DELETE s оставят мъртви кортежи зад себе си, както и неуспешният INSERT s. Преди това само VACUUM може да възвърне място, заето от мъртви кортежи. WithHOT пространството за мъртви кортежи може да бъде автоматично възстановено в момента наINSERT или UPDATE ако не се правят промени в индексираните колони . Това позволява по-последователно изпълнение. Също така, HOT избягва добавянето на дублиращи се индексни записи.

Акцент мой. И „без промени“ включва случаите, когато колоните се актуализират със същата стойност, каквато вече съдържат. Азвсъщност тествах , тъй като не бях сигурен.

В крайна сметка обширният README.HOT в изходния код го потвърждава.

Препечените колони също не пречат на ГОРЕЩИТЕ актуализации. HOT-актуализираният кортеж просто се свързва със същия, непроменен кортеж(и) в тост разклонението на връзката. ГОРЕЩИТЕ актуализации работят дори с препечени стойности в целевия списък (действително променени или не). Ако препечените стойности са променени, това очевидно води до записване към разклонението на връзката тост. Тествах и всичко това.

Не ми вярвайте на думата, вижте сами. Postgres предоставя няколко функции за проверка на статистиката. Изпълнете вашия UPDATE със и без всички колони и проверете дали има някаква разлика.

-- Number of rows HOT-updated in table:
SELECT pg_stat_get_tuples_hot_updated('table_name'::regclass::oid)

-- Number of rows HOT-updated in table, in the current transaction:
SELECT pg_stat_get_xact_tuples_hot_updated('table_name'::regclass::oid)

Или използвайте pgAdmin. Изберете вашата таблица и проверете раздела „Статистика“ в главния прозорец.

Имайте предвид, че ГОРЕЩИТЕ актуализации са възможни само когато има място за новата версия на кортежа на същата страница на основната вилка за връзка. Един прост начин да наложите това условие е да тествате с малка таблица, която съдържа само няколко реда. Размерът на страницата обикновено е 8k, така че трябва да има свободно място на страницата.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. динамична sql заявка в postgres

  2. Индекс на долните букви на Flask-SQLAlchemy - функция за пропускане, не се поддържа от отражението на SQLAlchemy

  3. Управление и наблюдение на база данни за PostgreSQL 12

  4. Как мога да изпратя имейл от тригера на PostgreSQL?

  5. psycopg2 еквивалент на mysqldb.escape_string?