Это должно работать с Sqlalchemy> = 0.6
from sqlalchemy.sql import compiler
from psycopg2.extensions import adapt as sqlescape
# or use the appropiate escape function from your db driver
def compile_query(query):
dialect = query.session.bind.dialect
statement = query.statement
comp = compiler.SQLCompiler(dialect, statement)
comp.compile()
enc = dialect.encoding
params = {}
for k,v in comp.params.iteritems():
if isinstance(v, unicode):
v = v.encode(enc)
params[k] = sqlescape(v)
return (comp.string.encode(enc) % params).decode(enc)
посмотрев, где условие, вы можете использовать составной индекс для таблицы cdu_sessions
create index idx1 on cdu_sessions(teacher_id, sort, enabled);
и ищите возможность присоединиться и выбрать таблицу cdu_sessions_lessons
create index idx2 on cdu_sessions_lessons(session_id, lesson_id);
Без учета плана запроса, количества строк и распределения в каждой таблице сложно предсказать хороший индекс, чтобы он работал быстрее.
Но я бы сказал, что это может помочь:
> create index sessions_teacher_idx on cdu_sessions(teacher_id);
Сначала напишите запрос, чтобы не было необходимости в преобразовании типов. Все сравнения в предложении where
относятся к числам, поэтому используйте числовые константы:
SELECT s.*,
sl.session_id, -- unnecessary because s.id is in the result set
sl.lesson_id
FROM cdu_sessions s INNER JOIN
cdu_sessions_lessons sl
ON sl.session_id = s.id
WHERE s.sort = 1 AND
s.enabled = 1 AND
s.teacher_id IN (193, 1, 168, 1797, 7622, 19951);
Хотя это может не произойти в этом конкретном случае, типы смешивания могут препятствовать использованию индексов.
Я удалил столбец как псевдонимы (например, as session_id
). Они были избыточными, потому что имя столбца является псевдонимом, а запрос не менял имя.
Для этого запроса сначала посмотрите на предложение WHERE
. Все ссылки на столбцы взяты из одной таблицы. Они должны войти в индекс, прежде всего для сравнения равенств:
create index idx_cdu_sessions_4 on cdu_sessions(sort, enabled, teacher_id, id)
Я добавил id
, потому что он также используется в JOIN
. Формально id
не требуется в индексе, если он является первичным ключом. Тем не менее, мне нравится быть явным, если я хочу это там.
Далее вам нужен индекс для второй таблицы. Оттуда ссылаются только два столбца, поэтому они оба могут войти в индекс. Первый столбец должен быть тем, который используется в join
:
create index idx_cdu_sessions_lessons_2 on cdu_sessions_lessons(session_id, lesson_id);