сервера БД.
есть поток событий (не очень большой, примерно 1-1.5к в секунду). у каждого события есть один уникальный признак и 3 возможно не уникальных.
нужно сохранить только последнее состояние для каждого уникального события.
в моем мире ( :) ) я бы просто использовал список, например, с доступом по хэшу от уникального признака и каждый раз переписывал состояние вне зависимости от того, изменилось оно или нет. операции в памяти - быстрые.
в случае с БД, как я понял, можно делать INSERT ... ON CONFLICT UPDATE.
вопрос в следующем - движок БД поймет, что неуникальные записи не изменились и не будет ничего апдейтить, или втупую каждый раз будет аплейтить безусловно?
тупой пример:
CREATE TABLE T1 (uid primary key not null, property1 int, property2 int, property 3 int)
insert into t1 (1, 2,3,4);
insert into t1(1, 1,1,4);
при вставке второй записи естественно возникнет исключение неуникальности uid. будет ли движок БД обновлять property3, учитывая, что оно не изменилось с предидущего раза?
а я сам на свой вопрос и отвечу. писаться на диск будет в любом случае страница, поэтому пофиг сколько там записей обновляется, в пределах страницы. ок, ушел читать дальше :)
MVCC требует хранить прошлое состояние
Новая строка будет записана с новым содержимым, даже если оно равно старому. При этом если есть индексы по обновленным полям то становится сильно хуже - в общем случае придется обновлять индексы.
Новая версия будет создаваться всегда. Но при определённых условиях, если Посгрес поймёт что старая никому не нужна и старая и новая версия окажутся на одной странице, то старая версия реюзнётся достаточно быстро. В противном случае на странице останется "дырка". Если записи на этой странице больше апдейтится не будет, то она там так и останется - никакой vacuum её не схлопнет. Т.е. у нас будет фрагментация. Поможет только vacuum full - полное переписываение таблицы. Кроме того, в Посгресе реализован hot update: если апдейт не затрагивает проиндексированные поля и новая версия попадает на одну страницу со старой, то в индексы она включаться не будет, а будет провязана в hot update цепочку. Что значительно ускоряет апдейты. Но это только если не поменялось ни одно из проиндексированных полей. Самое очевидной решение - это использовать upsert (insert ... on conflict update). Но в некоторых случаях append only табличка может действительно оказаться более эффективной.
Обсуждают сегодня