今回は前回に引き続きSQLAlchemyを使ってPythonでデータベースの情報をSELECTで抽出する処理を高速化すう知見についてまとめていきます。
前回の記事:【Python】SqlalchemyでのINSERT処理を高速化する方法
前準備
前回と同じ要領でテーブルを作成し、1000レコードのデータを登録します。
from datetime import datetime from sqlalchemy import create_engine, MetaData from sqlalchemy.orm import scoped_session, sessionmaker import time uri = 'sqlite:///test.db' engine = create_engine(uri) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() from sqlalchemy.schema import Column from sqlalchemy.types import Integer, String class User(Base): __tablename__ = "user" # テーブル名を指定 user_id = Column(Integer, primary_key=True) first_name = Column(String(255)) last_name = Column(String(255)) age = Column(Integer) def full_name(self): # フルネームを返すメソッド return "{self.first_name} {self.last_name}" Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker SessionClass = sessionmaker(engine) session = SessionClass() user_a = User(first_name="first_a", last_name="last_a", age=20) session.add(user_a) session.commit() # 登録用のデータを作成 data_list = [] for i in range(1000): data_list.append(["first_a","last_a", i]) #bulk_insert session.bulk_save_objects( [User(first_name=d[0], last_name=d[1], age=d[2]) for d in data_list], return_defaults=True) session.commit()
SqlalchemyでのSELECT文の実行
通常の方法
from sqlalchemy import select, desc, and_, func start_core = time.time() users = session.query(User).order_by(desc(User.age)).limit(100).all() result = [{'first_name': u.first_name, 'last_name': u.last_name, 'age': u.age} for u in users] print(time.time() -start_core)
実行時間:0.028秒
SQLAlchemy Coreを使う方法
次はSQLAlchemy Coreを使ってSELECT文を実行してみます。
コードは以下のようになります。
start_core = time.time() u = User.__table__.c sel = select([u.first_name, u.last_name, u.age])\ .select_from(User.__table__)\ .order_by(desc(u.age)).limit(100) result = [{'first_name': r[0], 'last_name': r[1], 'age': r[2]} for r in session.execute(sel)] print(time.time() -start_core)
実行時間:0.015秒
終わり
結果としてはSQLAlchemy Coreを使う方が通常の方法より半分くらいの処理時間でデータを抽出することができました。一応他にも並列処理などを用いて高速化することも可能です。
FlaskやDjangoなどのPython製webアプリでデータベースからデータの読み込み時間で苦心している方の参考になれば幸いです。では~
コメント