Назад в категорию «Разработка»

Сортировка, оффсет и план запросов.

Категория: Разработка | Четверг, 20.02.2020 21:02

Лучшие ошибки - это ошибки сделанные своими руками.

Разбирался с ситуацией в сортировке, когда товары интернет-магазина начинали дублироваться. После беседы с клиентом, вообще взялся за голову.
Дальше диалог с представителем клиента:
Клиент: Я каталог смотрю, а там иногда один и тот же товар показывается два раза.
Я: А какой конкретно товар?
Клиент: Ну каждый день разный, вот сегодня “такой-то”
Я: WTF?

Первая мысль - что-то в ORM накрутил с join’ами, и товар размножается из-за каких то коллизий в данных при импорте.
Ну и поехали разборки - получил запрос сформированный ORM и получил все товары, сформированные этим запросом. Просмотрел. Дублей нет.
Иду на сайт. Смотрю - дубли есть. И вот в чём подвох - на первой странице товар-дубль последний в списке, а на второй странице - самый первый в списке. Ну и подозрения закрались в мою голову.
Сравнил полный запрос, с результатами постраничных и в результатах постраничных, действительно товар дублируется, но есть и отсутствующий товар, с точно такой же ценой и точно таким же начальным остатком товаров.
Ну и как понятно из названия поста - да, проблема была в порядке сортировки и оффсетах. При равных условиях (стоимость, количество), для каждой страницы PostgreSQL применял дальше разный порядок выборки.
Добавил третьим параметром сортировки уникальный идентификатор товара и восстановил работоспособность сортировки. При прочих равных параметрах БД теперь точно будет знать, что ей делать.
Итого: споткнулся об ошибку описанную в документации и сам дурак - никто не гарантирует вам, что результаты запроса будут отсортированы в нужном вам порядке, при равных параметрах ORDER BY.
Ну и похожая тема на StackOverflow - https://stackoverflow.com/questions/11263715/is-postgresql-order-fully-guaranteed-if-sorting-on-a-non-unique-attribute/11263927