MySQLdbの3つと比較して、4秒で実行されるMySQLスクリプトのSQLAlchemyバージョンは次のとおりです。
from sqlalchemy import Integer, Column, create_engine, MetaData, Table
import datetime
metadata = MetaData()
foo = Table(
'foo', metadata,
Column('id', Integer, primary_key=True),
Column('a', Integer(), nullable=False),
Column('b', Integer(), nullable=False),
Column('c', Integer(), nullable=False),
)
class Foo(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
engine = create_engine('mysql+mysqldb://scott:[email protected]/test', echo=True)
start = datetime.datetime.now()
with engine.connect() as conn:
foos = [
Foo(row['a'], row['b'], row['c'])
for row in
conn.execute(foo.select().limit(1000000)).fetchall()
]
print "total time: ", datetime.datetime.now() - start
ランタイム:
total time: 0:00:04.706010
これは、ORMを使用してオブジェクト行を完全にロードするスクリプトです。イールドパーを使用して一度にすべての100万オブジェクトで固定リストを作成することを回避することにより、これは13秒で実行されます。 SQLAlchemyマスターを使用(rel 0.9で18秒):
import time
from sqlalchemy import Integer, Column, create_engine, Table
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Foo(Base):
__table__ = Table(
'foo', Base.metadata,
Column('id', Integer, primary_key=True),
Column('a', Integer(), nullable=False),
Column('b', Integer(), nullable=False),
Column('c', Integer(), nullable=False),
)
engine = create_engine('mysql+mysqldb://scott:[email protected]/test', echo=True)
sess = Session(engine)
now = time.time()
# avoid using all() so that we don't have the overhead of building
# a large list of full objects in memory
for obj in sess.query(Foo).yield_per(100).limit(1000000):
pass
print("Total time: %d" % (time.time() - now))
次に、これら2つのアプローチの違いを分割し、ORMを使用して個々の列のみをロードできます。
for obj in sess.query(Foo.id, Foo.a, Foo.b, Foo.c).yield_per(100).limit(1000000):
pass
上記は再び4秒で実行されます 。
SQLAlchemy Coreの比較は、生のMySQLdbカーソルとのより適切な比較です。 ORMを使用しているが、個々の列をクエリする場合、最新バージョンでは約4秒です。
ORMレベルでは、速度の問題はPythonでのオブジェクトの作成が遅いためです。また、SQLAlchemy ORMは、オブジェクトをフェッチするときにこれらのオブジェクトに大量の簿記を適用します。これは、ユニットを含む使用契約を履行するために必要です。仕事の、アイデンティティマップ、熱心な読み込み、コレクションなど。
クエリを劇的に高速化するには、完全なオブジェクトではなく、個々の列をフェッチします。 http://docsでテクニックを参照してください.sqlalchemy.org / en / latest / faq / performance.html#result-fetching-slowness-orm これを説明しています。
PeeWeeと比較すると、PWは、IDマップでは何も実行しないなど、機能がはるかに少ない、はるかに単純なシステムです。 PeeWeeを使用しても、可能な限り単純なORMでも、15秒かかります。 、これはcPythonが本当に遅いという証拠です ストレートCにある生のMySQLdbフェッチと比較してください。
Javaと比較すると、JavaVMはcPythonよりもはるかに高速です 。 Hibernateはばかげて 複雑ですが、JITのおかげでJava VMは非常に高速であり、その複雑さでさえも実行速度が速くなります。 PythonとJavaを比較する場合は、Pypyを使用してください。