определенной таблицы при каждом действии пользователя.
Сейчас в этой таблице 10к записей, и действия выполняются моментально(пользователь не испытывает никаких задержек).
Когда в таблице станет скажем 1-2 млн записей, на сколько может быть увеличено время отклика? Оно останется в пределах 500мс чтобы остаться незаметным для пользователя или же будет несколько секунд составлять?
БД и тг бот на самой простой конфигурации VPS 1vCpu, 1ram
1) делай инсерты, делейты и апдейты отдельной процедурой 2) заведи отдельную таблицу где будешь хранить текущую сумму 3) когда дергаешь процедуру из п.1, пересчитывай сумму - т.е. к уже подсчитанной сумме добавляй или отнимай новые значения
у меня есть таблица куда записывается итоговая сумма, но она постоянно меняется потому что добавляются строки(либо удаляются) и нужно пересчитывать сумму заново
ну так когда добавляется строка ты возьми число из этой строки и прибавь к текущей сумме
По-моему, вся эта тема — монумент premature optimization (и да, в реальной системе такого масштаба при следовании почти каждому из данных советов станет только хуже), извините. CREATE TABLE test_table ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, some_value numeric NOT NULL ); INSERT INTO test_table(some_value) SELECT round((random() * 100000.0)::numeric, 2) FROM generate_series(1, 2000000) AS g(n); > \dt+ test_table Size -------- 98 MB -- остальное порезано > SELECT SUM(some_value) FROM test_table; sum ----------------- 100047217912.55 (1 row) Time: 101.230 ms Т.е. протестируйте на Ваших похожих на реальные данных и на используемом "железе", прежде чем заниматься "оптимизацией" (и решать, скорее всего, несуществующие проблемы).
Спасибо! Попробую
Если у него табличка с логами (и там есть поля, занимающие гораздо больше места, чем два числовых поля, но они не уходят в TOAST), из которой надо просто показать какую-то цифру, а иное использование (помимо insert-ов туда) редко, то регулярный пересчет числа строк приведёт к напрасному занятию части shared buffers данными этой таблички на постоянной основе и лишним чтениям (ведь табличка будет уже не сотню мб, а гораздо больше). Но если там тупо два числовых поля, то да, никакие оптимизации не нужны.
Мой посыл в том, что никто не спросил, что там у автора на самом деле (есть ли какая-то проблема вообще) и не посоветовал, как выяснить — нет, все стали давать советы, следование которым приведёт к усложнению БД (т.е. скорее всего, внесению ошибок), и, хуже того, провалит производительность CRUD (в типичных случаях). :(
Ещё многие забывают что инструментом денормализации данных являются индексы
а чем варианты усложнят crud? По классике тут вообще место для триггера(но они сейчас не модные). И да то что ты показал 102 мс на запросе с sum - не дает никакой гарантии то этот sum верный
> а чем варианты усложнят crud? Тем, что простые (не тот, что предложил https://t.me/pgsql/511910 ) превращают многозадачную систему в однозадачную, например? Там будет точка сериализации (блокировка) на обновлении этой суммы, и соответственно, очередь (т.е. либо ожидания, либо откаты). > не дает никакой гарантии то этот sum верный Это даёт абсолютную гарантию того, что он верный (на момент получения в той транзакции, которая его получила), в отличие от других предложенных методов (где об этом ещё надо думать), о чём Вы говорите?! А если это не так — пора писать bug report в проект PostgreSQL, а не рассуждать о блокировках и т.п. ;)
вообще никакой гарантии нет что между подсчетом сум и записью суммы, не будет нового инсерта
Это не имеет никакого значения. Но, строго говоря (чтоб не думать) абсолютную гарантию корректности (в любых обстоятельствах) даёт только использование transaction isolation level serializable (который и стоит использовать всем, кто в этом не разбирается... да и вообще всем, кроме тех, у кого какая-то "исключительная" ситуация или требования к производительности). Мне кажется, Вам стоит почитать что-то по основам изоляции транзакций в СУБД, это Вам не [убогий] multi-threading. ;)
Ярослав, 1) Не переходи на личности 2) Почитай сам то что пытаешься рекомендовать другим, особенно если рекомендуешь serializable
> 1) Не переходи на личности Я же написал "мне кажется". И показалось мне это потому, что Вы написали про "не будет нового инсерта" — это типичная ошибка новичков (которым кажется, что transaction isolation в СУБД как-то соотносится с реальным временем). Извините. > 2) Почитай сам то что пытаешься рекомендовать другим, особенно если рекомендуешь serializable Зачем мне это читать?! Я же это написал. ;) В чём проблема с данным советом, а?
Он хочет считать это на квждое движжние мышкой. Так что — нет, пока эту идею не отменят — рассчёт суммы заранее выглядит минимально-необходимым.
Я не увидел в вопросе никаких "движжний мышкой", написано было вот так: "Оно останется в пределах 500мс". Так вот оно запросто может остаться, и тогда минимально-необходимым расчёт суммы заранее не выглядит.
Обсуждают сегодня