Pull to refresh

Comments 21

Решение прикольное. По сути это эмуляция части логики N-ного уровня на N+1-ом, так как сам движок не догадывается о частном случае использования собственных же средств ускорения доступа.

Тут научить движок решению в общем случае многоколоночного индекса — та еще задача. Даже с реализацией Incremental Sort больше двух лет бились — а, казалось бы, тоже «все очевидно».
В оригинальной статье есть соответствующий запрос и оба варианта плана — и с BitmapOr, и с деградацией до Seq Scan. Этот вариант не претендует на суперскорость, но гарантирует отсутствие Seq Scan — если не все записи за одну дату, конечно.

Глянул, грустно. Я надеялся по простоте душевной что слоник умеет выбирать по индексу и досортировывать потом…

Из опыта работы.
Ни одному юзеру никогда не требовался этот самый реестр, особенно с пейджингом.
Что касается таких учетных систем, как сбис, 1с, axapta, и прочих, прочих
Юзер всегда ищет конкретный документ! Всегда!
Юзер, работающий с потоуом звявок Всегда (!!) будет смотреть только первые 5-10 строк и выбирать из них.
По этому. Все эти реестры документов и "проблемы" сортировки лишь в головах разработчиков.
Создавать индексы нужно правильно, но нужно.
Проблемы мутации кортежей надо отслеживать и применять разные техники. Например партицирование и прочее, а не отбрасывать с определением, что вставуа медленная…
Если она медленная, то это проблема архитектуры БД.
Иначе прюолучишь проседание по выборкам с фулсканами.
По мне, так это костыль, для прилуманной проблемы.

Ни одному юзеру никогда не требовался этот самый реестр, особенно с пейджингом.

а, например, покупка авиабилетов? (да и в целом, логистика)

Что касается учётных систем, то совсем не редкость, когда что-то с чем-то не сходится, и тогда юзер начинает «крыжить» документы.

В любой системе на любом сайте не зря есть строка поиска. И совмем не поосто так ее стараются унифицировать в плане распознавания семантики запроса.
Самый простой и очевидный пример — гугл. Много ли людей по статистике при поиске пользуются пэйджингом?

Юзер всегда ищет конкретный документ! Всегда!

Беда в том, что иногда это нужно вдолбить в головы всем людям на проекте, вплоть до архитекторов. А потом еще и юзерам, которые тоже не всегда догадываются, что им нужна хорошая система фильтров, а не «бахнем 10К записей в таблице на экран, а дальше сами поищите».
Неприятность может произойти чуть позже — когда в системе поднакопилось документов столько, что даже «хорошая система фильтров» выдает сотни записей, а о пейджинге не подумали заранее.
Из опыта работы.

А у вас опыт, простите, юзера или разработчика?


Юзер всегда ищет конкретный документ!

Только вот идентифицирует пользователь этот документ совсем не по ID. А примерным интервалом дат и чем-то в комментарии, что "точно не помню, но как увижу, сразу узнаю". И именно грамотный пейджинг позволяет в таких ситуациях найти этот документ максимально быстро.

По опыту, юзерам может и не нужно, но вот заказчику нужно. Обычно не разработчики предлагают сделать пагинацию, а заказчик, стейкхолдера и т. п.

Мне кажется, что не нужно обязательно заземлять теоретическое решение на возможность практического его применения, тем более в решении конкретной или типичной бизнес-задачи.

Представьте, вы приходите с аппаратом комплексных чисел к электротехникам-постоянщикам, и они вас посылают — так как это выдумка сплошная, к практике неприменимо никак итд. Затем они изобретают машину переменного тока, и вдруг оказывается, что аппаратец-то очень кстати, и теперь они уже идут к вам ;)

Поэтому я просто запомнил, что существует прикольный способ — пусть даже 100% как гимнастика ума, ибо в практическом применении действительно а) размер специального индекса будет пренебрежимо мал по сравнению с размером записи в таблице реестров, б) обычно в бизнес-таблицах и так несколько индексов, так что компактный индекс, одна из колонок которого — кластерный, перестроить будет несложно
Есть еще одна интересная задача, на которой слоник валится, а хотелось бы что бы не тупил и полетел.

Представьте что у вас есть массив циферок в строчке — разделов. Так вот, если по нему построить составной btree (cats, ctime) — то вы получите все комбинации того, что лежит внутри cats и списки строк отсортированные по ctime, но индекс не будет толком работать при поиске по вхождению в этот индекс: например cats @> array[2] и будет давать full scan, а вот … where cats = array[2] order by ctime даст, через, так называемый sort hint, очень быструю выдачу по вторичному ключу (не забудьте limit).

Если сделать индекс gin (с расширением btree_gin) — то запросы @> заработают, но вот незадача, sort hint, увы, на gin по полю ctime уже не заработает.
Если кто знает как это решить без доп-таблицы и пачки вариаций btree индексов с where cat @> 1,2,3…, поделитесь плиз )
А если попробовать btree_gist и distance-оператор для k-NN? Что-то вроде WHERE cat @> '{1,2,3}'::int[] ORDER BY point(ctime, ctime) <-> point(0, 0) LIMIT 1, если я правильно понял задачу.
я пробовал — не пашет, с circle может быть, но хинт сортировки — все еще никак. Приходится триггерами приводиться в 2ую форму.
чуть голова не лопнула, но запрос курил до понимания, такого в mysql похоже не провернуть.

Не заумно ли тут все написано? Хотя, ту да голый SQL или поздно и я не уловил сути.


Я делал подобный финт ушами на linq2db (C#), как-то обходился без CTE и UNION по ненадобности.
Главное правило, все что в ORDER BY дожно быть уникальным ключем и тогда такой пейджинг делается с пол пинка. Где-то у меня валялся алгоритм который любой LINQ запрос заворачивал в такой пейджинг. По заявкам откопаю.


Принцип простой, есть ORDER BY asc1, asc2, desc1 DESC
asc1 + asc2 + desc1 — обязательно уникальный ключ


Первый запуск


SELECT * FROM table t
ORDER BY t.asc1, t.asc2, t.desc1 DESC
LIMIT 101

Берем на одну запись больше запоминаем asc1, asc2, desc1 последней записи. Также в таком варианте мы уже можем знать что страница последняя, на клиент возвращаем на одну запись меньше.


Второй запуск, следующая страница


SELECT * FROM table t
WHERE t.asc1 >= asc1 AND t.asc2 >= asc2 AND t.desc1 <= desc1
ORDER BY t.asc1, t.asc2, t.desc1 DESC
LIMIT 101

Повторяем запоминание попоследнаей записи.


Конечно алгоритм чуток больше еще учитывал, просто передал кратко принцип

Тут тема именно в недопущении Seq Scan, когда в индексе (dt, id), а в запросе ORDER BY dt, id DESC — посмотрите планы в исходной статье.
Sign up to leave a comment.