SQLAlchemy: эффективный / лучший выбор по первичным ключам? - PullRequest
2 голосов
/ 15 апреля 2010

Еще один вопрос новичка ..

Допустим, у меня есть пользовательская таблица в декларативном режиме:

class User(Base):
    __tablename__ = 'user'
    id = Column(u'id', Integer(), primary_key=True)
    name = Column(u'name', String(50))

Когда у меня есть список идентификаторов пользователей, я получаю их из базы данных с помощью:

user_ids = [1, 2, 3, 4, 5]
users = Session.query(User).filter(User.id.in_(user_ids)).all()

Мне не нравится использовать in_, потому что я думаю, что узнал, что он имеет плохую производительность на проиндексированных полях (это правда / ложь?).

В любом случае, есть ли лучший способ выполнить этот запрос?

Спасибо!

РЕДАКТИРОВАТЬ: я использую MySQL

Как бы я написал этот запрос, используя ИЛИ с sqlalchemy?

РЕДАКТИРОВАТЬ: получил:

from sqlalchemy.sql.expression import or_
user_ids = [1, 2, 3, 4, 5]
clauses = or_( *[User.user_id==x for x in users] )
users = Session.query(User).filter(clauses).all()

Ответы [ 2 ]

4 голосов
/ 15 апреля 2010

Много проблем производительности зависит от ядра базы данных. Остальная часть этого поста будет посвящена MySQL.

Предложение IN () может иметь плохую производительность в индексированном поле, но не будет в приведенном вами примере. До определенного числа user_ids ваш запрос будет максимально быстрым. Однако в какой-то момент становится быстрее помещать user_ids во временную таблицу и присоединяться к ней. Вы можете увидеть более подробную информацию о производительности IN () по сравнению с временной таблицей в MySQL здесь .

Если этот список user_ids основан на каком-то атрибуте пользователей (например, администратор или недействительный), то вы можете добавить поле в свою таблицу User и вообще избежать этой проблемы.

3 голосов
/ 15 апреля 2010

Альтернативой использованию предложения "in" является "или" идентификаторы, то есть где "id = 1 или id = 2 или id = 3". Если их немного, вы можете набрать определенную скорость.

Из документов: http://www.sqlalchemy.org/docs/ormtutorial.html#common-filter-operators

from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))

Вы не говорите, какую DBM вы используете, но ваш администратор может быть вашим лучшим активом здесь. Лучший способ узнать, какую конструкцию использовать, - это проанализировать запрос и попробовать несколько разных, чтобы вы знали, насколько хорошо ваш конкретный механизм базы данных обрабатывает различные запросы. Независимо от того, какую базу данных вы используете, если она поддерживает «или» или «в», вы, вероятно, получите большую скорость, используя их вместо того, чтобы перебирать все нужные вам идентификаторы и делать отдельные запросы.

Может оказаться, что беспокойство по поводу того, использовать ли «in» или другую конструкцию, не окажет большого влияния на общую скорость приложения по сравнению с изменением других частей кода. Движки баз данных довольно хитроумно оптимизируют простые запросы, поэтому вы получите хорошую производительность, если ваш запрос будет разумным. Одна из вещей, которую мы должны узнать о программировании, - это сначала заставить код работать хорошо, а затем тестировать и оптимизировать, если есть проблемы. Часто мы предполагаем, что знаем, где находится узкое место, но инструмент профилирования покажет, что мы ошиблись. Использование профилировщика и тестовых инструментов может помочь сузить проблемные области и показать, каковы наилучшие способы ускорить любые изменения.

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