Đây là phiên bản SQLAlchemy của tập lệnh MySQL của bạn thực hiện trong bốn giây, so với ba cho MySQLdb:
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
thời gian chạy:
total time: 0:00:04.706010
Đây là một tập lệnh sử dụng ORM để tải đầy đủ các hàng đối tượng; bằng cách tránh tạo danh sách cố định với tất cả 1 triệu đối tượng cùng một lúc bằng cách sử dụng lợi suất mỗi đối tượng, quá trình này sẽ chạy sau 13 giây với SQLAlchemy master (18 giây với rel 0.9):
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))
Sau đó, chúng tôi có thể tách sự khác biệt giữa hai phương pháp này và chỉ tải các cột riêng lẻ bằng ORM:
for obj in sess.query(Foo.id, Foo.a, Foo.b, Foo.c).yield_per(100).limit(1000000):
pass
Phần trên sẽ chạy lại sau 4 giây .
Sự so sánh của SQLAlchemy Core là sự so sánh phù hợp hơn với một con trỏ MySQLdb thô. Nếu bạn sử dụng ORM nhưng truy vấn cho các cột riêng lẻ, thì khoảng bốn giây trong các phiên bản gần đây nhất.
Ở cấp ORM, các vấn đề về tốc độ là do việc tạo các đối tượng trong Python chậm và SQLAlchemy ORM áp dụng một lượng lớn sổ sách kế toán cho các đối tượng này khi nó tìm nạp chúng, điều này cần thiết để nó hoàn thành hợp đồng sử dụng, bao gồm cả đơn vị. công việc, bản đồ danh tính, tải nhanh, bộ sưu tập, v.v.
Để tăng tốc truy vấn đáng kể, hãy tìm nạp các cột riêng lẻ thay vì các đối tượng đầy đủ. Xem các kỹ thuật tại http:// docs .sqlalchemy.org / vi / new / faq / performance.html # result-fetching-slowness-orm mô tả điều này.
Để bạn so sánh với PeeWee, PW là một hệ thống đơn giản hơn nhiều với ít tính năng hơn, bao gồm cả việc nó không làm được gì với bản đồ nhận dạng. Ngay cả với PeeWee, một ORM đơn giản đến mức khả thi, vẫn mất 15 giây , đó là bằng chứng cho thấy cPython thực sự rất chậm so với tìm nạp MySQLdb thô trong C.
Để so sánh với Java, máy ảo Java nhanh hơn cPython theo cách khác . Hibernate thật nực cười phức tạp, nhưng máy ảo Java cực kỳ nhanh do JIT và thậm chí tất cả sự phức tạp đó cũng chạy nhanh hơn. Nếu bạn muốn so sánh Python với Java, hãy sử dụng Pypy.