Комментарии 4
Аналогично работает в Go с использованием библиотеки Gorm: https://gorm.io/docs/query.html
Т.е автора смущает
если есть bonuses.active.first, то возможен и bonuses.active.last? Будет то же самое поведение или другое? При такой записи точно ответить нельзя
Но, вот влепить два семантически разных запроса и считать их эквивалентными его не смущает....
SELECT "bonuses".* FROM "bonuses" WHERE "bonuses"."user_id" = 123 AND "bonuses"."status" = 'active' LIMIT 1;
Это означает - возьми первый попавшийся. И строго говоря в зависимости от БД и систем даже последовательных два таких запроса могут дать разный результат на одном и том же наборе данных.
SELECT "bonuses".* FROM "bonuses" WHERE "bonuses"."user_id" = 123 AND "bonuses"."status" = 'active' ORDER BY "bonuses"."id" ASC LIMIT 1;
Означает возьми первый по порядку (скорее всего добавления). И вот он будет всегда одинаков на одном и том же наборе данных.
Что касается вашей таблицы курсов...
Rows Removed by Filter: 6340297
То что-то у вас пошло не так. Посмотрите то же партиционирование. Оно должно дать существенный прирост скорости получения данных без нарушения семантики запроса.
Статья родилась из соображения о том, что если попросить среднестатистического рубиста (возможно даже среднестатистического приверженца ORM'ов) выбрать одну запись по какому-либо условию, то он напишет что-то из разряда Model.where(...).first
Так же я намеренно в начале статьи говорю что
Там, где порядок записей имеет значение, обойтись без
first/last
нет возможности
Упор статьи сделан на тех кейсах, когда по определенным условиям в выборке есть строго одна запись. В моих примерах это обусловлено
в случае с бонусами бизнес требованиями (не может быть в системе два активных бонуса, для этого в системе есть различные проверки)
в случае с курсами валют здравым смыслом (ну не может быть два разных курса у одной валюты в одном промежутке времени)
Поэтому два семантически разных запроса дадут один и тот же практический результат, но вот затраты с которыми этот результат получен уже разные.
Что касается курсов: у нас в проекте используется партиционирование в нескольких местах (где оно оправдано), в данном кейсе мы вполне обходимся индексами, проблем не замечаем.
Поэтому два семантически разных запроса дадут один и тот же практический результат, но вот затраты с которыми этот результат получен уже разные.
Все правильно. Чаще всего это говорит лишь о том, что исходно использовался не тот запрос что нужен.
Возможно я не смог правильно прочесть это в статье в рамках расставленных акцентов.
в случае с курсами валют здравым смыслом (ну не может быть два разных курса у одной валюты в одном промежутке времени)
Зависит от величины промежутка времени. Даже официальные курсы центральных банков, которые устанавливаются на один день имели преценденты изменяться в течении этого самого дня.
Перестаньте везде использовать first/last