最近在完善一个项目,由于展示界面使用的是django,但是却想解耦合,后台与展示界面并没有直接使用django的ORM,于是就使用了SQLAlemchy来做后端数据收集的数据库接口,但是网上说,SQLAlemchy的性能并不好,今天,就想着来测试一下其性能瓶瓶颈在哪儿,下面是过程记录:
查询测试
测试代码如下:
def pymsql_select():
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root', db='test')
cursor = conn.cursor()
for i in range(1, 10000):
sql = "select count(*) from informations_alarm;"
cursor.execute(sql)
print(cursor.fetchone())
def alchemy_select():
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/test", max_overflow=5)
# 创建mysql操作对象
Session = sessionmaker(bind=engine)
session = Session()
for i in range(1, 10000):
count = session.query(Alarm).count()
print(count)
def alchemy_select_withsql():
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/test", max_overflow=5)
# 创建mysql操作对象
Session = sessionmaker(bind=engine)
session = Session()
for i in range(1, 10000):
count = session.execute("select count(*) from informations_alarm")
print(count.first())
if __name__ == '__main__':
pymsql_select()
alchemy_select()
alchemy_select_withsql()
先测试直接使用pymysql,即pymsql_select函数,结果如下:
然后就是测试使用SQLAlchemy的ORM来测试,就是函数alchemy_select,结果如下:
最后就是使用SQLAlchemy直接执行SQL语句,就是函数alchemy_select_withsql,结果如下:
下面测试数据库写入:
def pymsql_select():
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root', db='test')
cursor = conn.cursor()
for i in range(1, 400):
sql = "INSERT INTO informations_alarm(receive_id,client_id,cpu,svmem,swap,diskio,diskusage,snetio,level,message) VALUES (1,1,1,1,1,1,1,1,1,\'1\');"
cursor.execute(sql)
conn.commit()
print(cursor)
def alchemy_select():
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/test", max_overflow=5)
# 创建mysql操作对象
Session = sessionmaker(bind=engine)
session = Session()
for i in range(1, 400):
alarm = Alarm(receive_id=1, client_id=1, cpu=1, svmem=1,
swap=1,
diskio=1, diskusage=1, snetio=1,
level=1, message=1)
session.add(alarm)
result = session.commit()
print(result)
def alchemy_select_withsql():
engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/test", max_overflow=5)
# 创建mysql操作对象
Session = sessionmaker(bind=engine)
session = Session()
for i in range(1, 400):
count = session.execute("INSERT INTO informations_alarm(receive_id,client_id,cpu,svmem,swap,diskio,diskusage,snetio,level,message) VALUES (1,1,1,1,1,1,1,1,1,\'1\');")
print(session.commit())
if __name__ == '__main__':
pymsql_select()
#alchemy_select()
#alchemy_select_withsql()
由于10000条数据太多,太耗时,于是测试插入400条数据
先测试直接使用pymysql,即pymsql_select函数,结果如下:
然后就是测试使用SQLAlchemy的ORM来测试,就是函数alchemy_select,结果如下:
最后就是使用SQLAlchemy直接执行SQL语句,就是函数alchemy_select_withsql,结果如下:
总体来说,直接使用pymysql是更胜一筹的,但是pymysql我们常不是这样用的,而是每次创建新的连接,执行完释放,而SQLAlemchy使用的是连接池机制,每次保证只有一个操作入口,下面是测试一般的pymysql用法:
def pymsql_select():
for i in range(1, 400):
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root', db='test')
cursor = conn.cursor()
sql = "INSERT INTO informations_alarm(receive_id,client_id,cpu,svmem,swap,diskio,diskusage,snetio,level,message) VALUES (1,1,1,1,1,1,1,1,1,\'1\');"
cursor.execute(sql)
conn.commit()
conn.close()
print(cursor)
结果如下:
查询代码如下:
def pymsql_select():
for i in range(1, 10000):
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='root', db='test')
cursor = conn.cursor()
sql = "select count(*) from informations_alarm;"
cursor.execute(sql)
print(cursor.fetchone())
conn.close()
结果如下:
于是,就基本有结论了:
从单线程方面来说,SQLAlemchy的ORM还是差于pymysql,但是去掉ORM直接执行sql的话,由于SQLAlemchy使用了连接池技术,避免了多次打开关闭连接的耗时,于是不管在写还是读上面,还是明显优于pymysql的,所以你想用SQLAlemchy,还想要求效率的话,建议你直接使用SQLAlemchy来执行SQL。
而SQLAlemchy的瓶颈在于ORM这一段,其要通过对象机制,将相应的对象转化为SQL语句,由于python效率低是出了名的,于是就导致将大量时间花在了转化上面,由此带来了效率低下。