Комментарии 17
CREATE UNIQUE INDEX ON events(ts DESC, id DESC);
Зачем здесь UNIQUE? id, как я понимаю, уже Primary Key, от добавления колонок он не потеряет уникальности. Дополнительная проверка уникальности не даёт лишней нагрузки на базу при INSERT?
0
пора бы перейти на навигацию от последнего показанного значения
Увы, не поможет если навигация допускается на произвольную страницу (а не только на следущую/предыдущую), без offset/limit тут уже никак (если только не гарантировать сквозную нумерацию в id).
0
Тогда возникает вопрос — а нужен ли действительно переход именно «на страницу» или таки достаточно «по координатам». Ну или как-то загодя нумеровать (и перенумеровывать потом) весь набор.
0
Загодя нумеровать кажется не получится, если интерфейс позволяет десятки вариантов фильтров и сортировок, до куче в кластере из нескольких серверов.
0
Было бы интересно почитать про более сложные случаи. Например когда у вас таблица содержит сотни тысяч записей, уникальный ключ и 5-10 полей значений по которым может производиться фильтрация/сортировка. Мы вот как раз живем в таких условиях. B SQL у нас нет (
0
Тут надо очень хорошо ориентироваться в предметной области. Например, как часто изменяется/добавляются записи в таблицу, какие возможны комбинации фильтров, все ли из них должны работать «идеально быстро»,…
И не все из этих вариантов вообще решаются с помощью SQL.
И не все из этих вариантов вообще решаются с помощью SQL.
0
Ну если брать наши случаи, то есть как раз два варианта:
1) Записи создаются и не обновляются
2) Записи создаются и часто изменяются (специфические документы, проходящие разные стадии привязки, дополнения, одобрения и т.п.)
При этом у нас записи НИКОГДА не удаляются.
Фильтры и их комбинации по сути комбинаторные, т.е произвольные сочетания произвольного количества фильтров с произвольным порядком сортировки и *ирония ON* конечно же за минимальное время *ирония OFF*.
Было бы интересно узнать больше о способах решения подобного класса задач. И в том числе о решениях не с помощью SQL, SQL у нас нет.
Если говорить о наших решениях (которые крайне все таки специфичны ввиду недоступности SQL, хотя СУБД и реляционная), то мы пока остановились на создании индексов покрывающих хотя бы по одному критерию (максимум двум), и проходу с помощью мммм… проблемы терминологического характера… курсора скорее всего. Наша сложность еще в том, что одним из требований является знание об общем числе записей отвечающих этим фильтрам.
1) Записи создаются и не обновляются
2) Записи создаются и часто изменяются (специфические документы, проходящие разные стадии привязки, дополнения, одобрения и т.п.)
При этом у нас записи НИКОГДА не удаляются.
Фильтры и их комбинации по сути комбинаторные, т.е произвольные сочетания произвольного количества фильтров с произвольным порядком сортировки и *ирония ON* конечно же за минимальное время *ирония OFF*.
Было бы интересно узнать больше о способах решения подобного класса задач. И в том числе о решениях не с помощью SQL, SQL у нас нет.
Если говорить о наших решениях (которые крайне все таки специфичны ввиду недоступности SQL, хотя СУБД и реляционная), то мы пока остановились на создании индексов покрывающих хотя бы по одному критерию (максимум двум), и проходу с помощью мммм… проблемы терминологического характера… курсора скорее всего. Наша сложность еще в том, что одним из требований является знание об общем числе записей отвечающих этим фильтрам.
0
Первый кейс неплохо покрывает clickhouse. Второй кейс тоже, если сможете адаптировать архитектуру под первый кейс — там есть специальные штуки.
0
Фильтры и их комбинации по сути комбинаторные, т.е произвольные сочетания произвольного количества фильтров с произвольным порядком сортировкиВ таких условиях лучше всего себя покажет полная материализация всех возможных комбинаций. :)
На самом деле, поисковые движки типа Sphinx, ElasticSearch «внутри» ровно это и делают. Только не всегда «полную» материализацию.
Пару лет назад читал где-то, что Я.Маркет как раз делает in-memory-материализацию результатов поиска, поэтому все фильтры-поиски идеально быстры, но первичное построение индекса занимает дни. Возможно, что-то уже изменилось.
0
У меня слишком много комбинаций в такой схеме получается и сильно проседает запись. В пиках запись 500МБ/с при отдельных индексах на всех фильтруемых колонках, если ещё и материализовать — будет совсем треш.
0
При таком объеме записи не надо давать пользователям хотеть «все возможные комбинации». Как только перестать такое хотеть, можно достаточно несложно «заточить» индексы по конкретные наиболее типовые выборки.
Иначе это путь в большие кластеры из много-много серверов.
Иначе это путь в большие кластеры из много-много серверов.
0
Если наступает перехотеть — тогда clickhouse начинает лучше выполнять эту задачу… Поэтому пока живём с limit offset и без count всей выборки.
0
clickhouse начинает лучше выполнять эту задачу
А вот это очень сильно зависит от задачи. Как известно, CH плохо относится к UPDATE, поэтому если ваши выборки должны строиться по накапливающимся агрегатам…
Конечно, в PG из-за MVCC тоже возникают с этим некоторые проблемы, но таки есть разница для скорости заранее известной выборки — иметь небольшую таблицу результирующих агрегатов с пачкой нужных индексов, или для каждого запроса собирать агрегат, хоть и очень быстро.
0
А вариант 3 точно лучше второго?
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
PostgreSQL Antipatterns: навигация по реестру