SQLAlchemy + SQLite Left Join Проблема с производительностью - PullRequest
3 голосов
/ 11 ноября 2011

У меня есть два идентичных запроса, кроме позиции левого соединения в предложении from. Один работает очень медленно, другой - очень быстро (сокращенно для ясности):

--SLOW
SELECT DISTINCT b.id
FROM a LEFT OUTER JOIN b ON a.id = b.id
       JOIN c ON a.id = c.a_id 
       JOIN d ON c.id = d.c_id 
WHERE d.value = 9;

--FAST
SELECT DISTINCT b.id
FROM a JOIN c ON a.id = c.a_id 
       JOIN d ON c.id = d.c_id 
       LEFT OUTER JOIN b ON a.id = b.id
WHERE d.value = 9;

Моя проблема в том, что, используя SQLAlchemy, я, похоже, могу создать только медленную версию запроса. В частности, я использую наследование таблиц и пытаюсь запустить следующий код:

return session.query(A).\
       with_polymorphic(B).\
       join(C).\
       join(D).\
       filter(D.value_id == 9).\
       distinct()

Другими словами, я не могу контролировать, где создается ЛЕВОЕ СОЕДИНЕНИЕ.

Как мне сделать SQLite и / или SQLAlchemy умнее?

1 Ответ

1 голос
/ 11 ноября 2011

Я не знаю, как заставить SA изменить запрос.Но я бы хотел выяснить, почему существует разница в плане выполнения запроса.Я хотел бы предположить, что если у вас есть индексы в столбцах соединения, порядок JOINs в запросе не должен иметь значения.

Вы можете использовать оператор EXPLAIN для проверки плана выполнения,Хотя вам нужно ознакомиться с Virtual Database Engine SQLite .Тем не менее, возможно, вы сразу заметите разницу между двумя планами выполнения и сможете повысить производительность базы данных вместо того, чтобы обманывать SA.
Попробуйте также удалить C или D из запроса для еще более простого сравненияпланов выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...