Pull to refresh

Comments 35

А как эта оптимизация позволяет быстрее сравнивать двух пользователей между собой?
Никак, эта оптимизация дает средний чек по всем записям.
Если хотите получить средние данные по нескольким срезам — придётся делать оптимизацию по каждому срезу при каждой записи. Это несколько усложнит программу, но при нескольких миллионах записей и частых запросах результат (выигрыш в скорости) будет того стоить.
Я это понимаю, я задавал вопрос автору. В его таблице результатов ускорился даже вариант сравнения двух пользователей.
Надо будет заново прогнать все эти тесты и написать конкретные результаты.
в фаерберде например, как раз, как вариант и используются тригеры + регистры для генерации суррагатного ключа :)
Вы под «регистром» имеете ввиду SEQUENCE(генератор)?

Ну это ж простой целый счетчик, с ним особо не разгуляешься. Как с дробными числами быть, например?

К тому же генераторы транзакционно-независимы. Т.е. транзакцию с данными можно откатить а генератор останется.
А как лучше хранить текущий баланс счёта?

Сейчас для себя пишу учебный проект «Домашняя Бухгалтерия» (на Ruby on Rails) и столкнулся с проблемой хранения текущего баланса счёта (кошелька). Вижу два варианта:
1) одна запись в базе отвечающая за хранение состояние счёта
+ простота
— сложно узнать сколько было на счету месяц/год назад. Для этого надо будет просуммировать все совершенный транзакции и вычесть от текущего баланса
2) к каждой записи доход/расход добавляем поле «account_state» где хранить состояние счёта на момент выполнения данной транзакции
+ знаем состояние счёта в любой момент времени (месяц/год назад)
— сложность системы: если необходимо добавить/удалить/изменить доход/расход задним числом, тогда придется пересчитывать состояние счёта для всех транзакций
3) Вариант (в 1С: Бухгалтерии, кажется, реализован именно он) — сохранять промежуточные итоги на начало/конец периода (день/неделя/месяц)
Да, это компромисс между двумя случаями.

Я когда-то работал в торговой сети, где было 500 магазинов и по 2000 наименований в каждом. Там решили хранить остатки за каждый день. Получилось, что каждый день прибавлялось бы по 50-100 мегабайт. Их не надо было бы пересчитывать, но если бы понадобилось корректировать, это была бы беда. И самое главное, что эти данные не были точными. Инвентаризации постоянно находили значительные расхождения. То есть хранить неточные оценочные данные не было большого смысла. Они нужны были только ради построения прогнозов, которые делали далеко не по всем наименованиям.
Имплементация скользящего среднего :)
Кстати, в приборах обычно используют именно скользящее среднее для подавление шумов. Проблема только в том, что вход в скользящее среднее занимает время.
Не только. Ещё дисперсия. :) Проблема в том, что в обычных БД этого нет, даже суммы пересчитываются полностью — попробовал на postgres, те же проблемы, только пошустрее работает. По сути я пишу то, что должен делать встроенный оптимизатор запросов.
Дико сложные конечно идеи задействованы, никто бы и не догадался.
Да, верно, люди с Вашим высокоразвитым интеллектом догадались бы за секунду. Им эта статья ни к чему. Однако моему техническому директору не было известно, что средняя разность раскладывается как разность средних, и её можно исправлять, и что квадратичные величины тоже раскладываются на суммы.
Ваш технический директор занимает пост, не соответствующий его скиллам. Вот и все. Частая ситуация в России.
А вы уверены, что мы в России работаем? Не угадали, не в России. И не стоит обсуждать личности людей. По отдельности такие вещи знают многие, а вместе у понятном виде разные знания просто так не лежат. Если бы я нашёл подобные оптимизации в поисковиках, не писал бы эту статью.
Задача технического директора — держать команду, которая может решать технические задачи и ставить ей эти задачи, а не решать их своими силами. Это я вам как технический директор заявляю.

Завтра в проекте понадобится выравнять картинку в DIV по нижней части текста, а послезавтра — распознать изображение с камеры в iOS. И что, ТД должен и это знать? Нет, он должен организовать подчиненных и подрядчиков так, чтобы эти задачи решились максимально быстро, дешево и надежно.
Обычно хранятся накопленные суммы, например, по каждому счету и сумма этих сумм делится на количество строк в таблице либо количество строк в выборке. Опять же, накопленные суммы легко корректировать. Так же возможно построение по различным измерениям. И OLAP не такой уж дорогой получается ;-)
Да, я как-то тоже замышлял OLAP на коленке с автоматической свёрткой по всем возможным измерениям. Но в конторе надо было дёшево и сердито, поэтому решили, пусть клиенты скажут, что им нужно, и обошлись простыми отчётами.
Реально в банке для подсчетов средних значений по всем клиентам, отделениям, годам/месяцам/неделям/дням и пр. достаточно было одной(!) дополнительной таблицы, правда с «хитрым» наполнением. Стоимость была 1-2 месяца для 1 разработчика. -
> Обычные базы данных не предлагают таких оптимизаций.

Да что вы говорите! Google(«материализованные представления»)
Ок, тогда, скажите, пожалуйста, можно ли сделать триггер, который бы не запускал пересчёт суммы по всей колонке, а увеличивал бы её на значение из добавленной записи?
Триггер такой сделать не проблема, проблема в другом. Если нужно пересчитывать суммы по всей колонке, то это уже неправильный дизайн.
Ну вот реальная ситуация: продажи в 10 оптовых магазинах создают 500 000 строк в неделю, 3000 продуктов. Мне надо пересчитать годовые итоги и по категориям продуктов, и по отдельным из них. Руководитель просит дать ему таблицу в Excel. Не веб-отчёт.
Накапливаете по каждому продукту в таблице ежегодные + ежемесячные (для текущего года) + еженедельные (для текущего месяца) + ежедневные (для текущей недели) и т.д. (вплоть до секунд) суммы и количество дней. Всегда имеете среднее. По окончанию периода «схлопываете» данные. Тоже самое по категориям. «Окончательный» пересчет происходит на закрытии периода. На практике пересчитывать, максимум, приходилось последний месяц, что далеко не все года.
duckduckgo «postgres materialized view выдаёт»: «Materialized Views are currently the #1 requested feature in a user survey for addition to PostgreSQL.»
Да, хотя попытки уже были. Но ведь не Постгресом единым ограничивается круг «обычных баз данных» :)
В тексте статьи есть картинка с формулой из трёх строк.
Во второй строке почему после открывающей скобки идёт n вместо суммы по n?
Там сумма по u от 1 до n. Xq от u не зависит, поэтому сумма из n одинаковых Xq — это n*Xq.
Идея, конечно, хорошая, но нужно хорошо решить вопрос с параллельным доступом. Так как в момент времени от данных данных и до их записи, сами данные уже могут быть изменены.

Мы аналогичную практику уже применяли на одном проекте средней нагруженности. Кэшированные значения постоянно «уезжали» от реального значения, пока не решили вопрос с конкуретным доступом. Нужно делать атомарным этот ряд операций. Выбрать соответствующий уровень изолированности транзакций БД и предотвратить чтение конкурентными потоками данных (для переподсчета) в период выполнения этой атомарной операции.

Использование сигналов в том виде, как Вы написали — недостаточно. Кстати, select_for_update() (для AnswerAggregate) Django поддерживает только с версии 1.4, которая недавно вышла.
… Так как в момент времени от данных получения данных…
Sign up to leave a comment.

Articles