因此,我一直在研究Python中的多访问或并行进程,以执行大约十几个SQL查询。现在,查询是串行进行的,大约需要4分钟,其中1个查询的时间与其他11个查询的长度一样长。因此,理论上,如果我可以并行运行所有查询,我可以将总运行时间减少一半。
我正试图按照以下思路做一些事情,但我还没有找到支持我当前思维过程的文档:
所以,假设我有:
SSMS_query1 = "SELECT * FROM TABLE1"
SSMS_query2 = "SELECT * FROM TABLE2"
HANADB_query3 = "SELECT * FROM TABLE3"
因此,要连接到SSMS,我使用:
import pyodbc
server = "server_name"
cnxn = pyodbc.connect("DRIVER={SQL Server};SERVER=" + server + ";trusted_connection=Yes")
然后连接到我的HANAdb,我使用:
from hdbcli import dbapi
conn = dbapi.connect(address="", port=, user="", password="")
然后本质上,我想做一些可以利用池来节省时间的事情,比如:
import pandas as pd
with cnxn, conn as ssms, hana:
df1 = pd.read_sql(SSMS_query1, ssms)
df2 = pd.read_sql(SSMS_query2, ssms)
df3 = pd.read_sql(HANADB_query3, hana)
我尝试过使用:
import multiprocessing
import threading
但我无法获得所需的输出,因为最终我想输出df1、df2和df3以取得优异成绩。那么,我如何存储数据帧,并在以后使用并行性将其用作输出呢?
我认为多线程可能比不知道创建的数据帧有多大的多处理更高效,因为通常情况下,多处理将结果从子进程移回主进程会有更多的开销。但由于查询需要4分钟,我不得不假设数据量相当大。此外,大部分时间都花在网络活动上,多线程非常适合这些活动。
在这里,我假设最坏的情况是,数据库连接不能在线程之间共享。如果不是这样,那么只创建一个连接并将其用于所有提交的任务:
from multiprocessing.pool import ThreadPool
import time
import pandas as pd
import pyodbc
def run_sql(conn, sql):
return pd.read_sql(sql, conn)
def main():
SSMS_query1 = "SELECT * FROM TABLE1"
SSMS_query2 = "SELECT * FROM TABLE2"
HANADB_query3 = "SELECT * FROM TABLE3"
queries = (SSMS_query1, SSMS_query2, HANADB_query3)
n_queries = len(queries)
server = "server_name"
connections = [
pyodbc.connect("DRIVER={SQL Server};SERVER=" + server + ";trusted_connection=Yes")
for _ in range(n_queries)
]
t0 = time.time()
# One thread per query:
with ThreadPool(n_queries) as pool:
results = pool.starmap(run_sql, zip(connections, queries))
df1, df2, df3 = results # Unpack
t1 = time.time()
print(df1)
print(df2)
print(df3)
print(t1 - t0)
if __name__ == '__main__':
main()