最近在完善一個項目,由於展示界面使用的是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:[email protected]: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:[email protected]: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:[email protected]: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:[email protected]: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效率低是出了名的,於是就導致將大量時間花在了轉化上面,由此帶來了效率低下。