Pull to refresh
42
0
retvizan @retvizan

User

Send message
Вот как эта задача решалась бы в СУБД с поддержкой аналитических функций:

SELECT group_id, order_id, value
FROM(
SELECT *, ROW_NUMBER()OVER(PARTITION BY group_id ORDER BY order_id) RowNum
FROM TestTable
)T
WHERE RowNum <= 2;

Однако оптимизатор MySQL ничего не знает о том, по каким правилам мы вычисляем поле RowNum. Ему придётся пронумеровать ВСЕ строки, и только потом отобрать нужные.

Теперь представьте, что у нас 1 миллион записей и 20 уникальных значений group_id. Т.е. чтобы выбрать 40 строк, MySQL будет вычислять значение RowNum для миллиона строк!

Фраза построена так, что создается впечатление, что только в MySQL будет идти перебор всех строк, а в других СУБД с поддержкой аналитических функций всё ok.
Разве row_number() в других СУБД не будет нумеровать все строки для указанного примера?
Статья хорошая, 10 лет назад внимательно читал бы примеры. Сейчас же, имхо, «старики» уже давно написали свои реализации, а новичкам есть решения из коробки.
По существу: утверждение «Красивого решения этой задачи одним запросом в MySQL нет.» устарело. LATERAL как раз и реализует, описанный ниже вариант, только в рамках одного запроса.
NOWAIT and SKIP LOCKED — Запретить запросу ждать блокировку на уровне таблицы и на уровне отдельных строк, соответственно.
Неудачная формулировка. Создается впечатление, что NOWAIT относится к уровню таблицы, а SKIP LOCKED — строк. Это не так.

SKIP LOCKED используюется для не детерминистического чтения из таблицы с пропуском строк, заблокированых другими пользователями.
NOWAIT — при наличии заблокированной строки не ждать освобождения блокировки innodb_lock_wait_timeout секунд, а сразу завершить выполнение запроса и вернуть ошибку:
ERROR 3572 (HY000): Do not wait for lock.

Есть хорошая статья Мартина Ханссона, перевод тут.
Во-первых, для настройки прав доступа. Помню во времена MySQL 4 испытывал трудности с тем, чтобы дать пользователям права на отдельные строки таблицы.

Во-вторых, для совместимости с приложениями, когда они требуют определенной структуры данных.
Зависит от запроса. Если используется алгоритм MERGE, то будут. Сравните explain итогового запроса через таблицу и запроса через представление, увидите их полную идентичность.
Спасибо за ценный комментарий.

Вообще-то в черновом варианте даже написал про FOR UPDATE и LOCK IN SHARE MODE, но потом решил что в отрыве от InnoDB, а соответственно и транзакций с их уровнями изоляций это будет не в тему. Всё-таки эта статья предназначена для новичков, чтобы было понимание, что такое блокировки и с чем их едят, а уже потом можно рассматривать особенности различных механизмов хранения.
Обязательно напишу, только это будет, наверное, после нового года.

Information

Rating
Does not participate
Registered
Activity