Я узнал, что SQLAlchemy переводит
db.query(...).filter(A.id.in_(ids))
в
SELECT ...
FROM a
WHERE a.id != a.id
если ids пусто. Это приводит к последовательному сканированию в таблице a, что, очевидно, катастрофично для производительности.
Первый вопрос: почему? Почему не просто 1 = 0 или что-то, что не требует последовательного сканирования?
Второй, более важный: есть ли обычно обходное решение (кроме if рядом с каждым in_)?
Я думаю, что in_ не может быть легко переопределено для охвата всех случаев, не вызывая этой проблемы, но я не могу быть первым, кто столкнулся с ним, и может быть какое-то решение, охватывающее простые, распространенные случаи использования in_.
ИЗМЕНИТЬ
SQLAlchemy регистрирует предупреждение каждый раз, когда это происходит:
"The IN-predicate on 'foo.bar' was invoked with an empty sequence. This results in a contradiction, which nonetheless can be expensive to evaluate. Consider alternative strategies for improved performance."