无响应的请求 - 了解瓶颈(Flask + Oracle + Gunicorn)

时间:2018-03-20 17:21:17

标签: python multithreading flask gunicorn cx-oracle

我是Flask / Gunicorn的新手,对SQL有一个非常基本的了解。

我有一个使用cx_oracle连接到远程oracle数据库的Flask应用程序。根据所选的应用程序路径,它会运行两个查询之一。我使用gunicorn -w 4 flask:app运行应用。第一个查询是对一个约70000行的表的简单查询,并且响应非常快。第二个更复杂,查询几个表,其中一个包含约1.5亿行。通过遍布print语句,我注意到有时第二个查询甚至从未开始,特别是如果它不是用户选择的第一个app.route并且它们都要同时运行。多次打开app.route('/')将多次快速触发其查询并并行运行,但不能与app.route('/2')一起运行。我启用了多个工作线程,并且threaded=True用于oracle。为什么会这样?由于桌子的大小,它是注定要缓慢/彻底没有反应吗?

import cx_Oracle
from flask import Flask
import pandas as pd

app = Flask(__name__)

connection = cx_Oracle.connect("name","pwd", threaded=True)

@app.route('/')
def Q1():
    print("start q1")
    querystring=""" select to_char(to_date(col1,'mm/dd/yy'),'Month'), sum(col2)
        FROM tbl1"""
    df=pd.read_sql(querystring=,con=connection)
    print("q1 complete")

@app.route('/2')
def Q2():
    print("start q2")
    querystring=""" select tbl2.col1, 
        tbl2.col2, 
        tbl3.col3 
        FROM tbl2 INNER JOIN 
        tbl3 ON tbl2.col1 = tbl3.col1
        WHERE tbl2.col2 like 'X%' AND
        tbl2.col4 >=20180101"""
    df=pd.read_sql(querystring=,con=connection)
    print("q2 complete")

我尝试将每个查询的数据集导出为csvs并让pandas读取csvs,在这种情况下,两个读取都可以同时运行,并且不会错过任何一个节拍。这是一个SQL问题,线程问题,工人问题吗?

1 个答案:

答案 0 :(得分:1)

请注意,连接一次只能处理一件事。如果连接忙于执行其中一个查询,则它无法执行另一个查询。一旦执行完成并且已经开始提取,则两者可以一起操作,但是每一个必须等​​待另一个完成其提取操作,然后另一个可以开始。要解决此问题,您应该使用会话池(http://cx-oracle.readthedocs.io/en/latest/module.html#cx_Oracle.SessionPool),然后在每个路由中添加以下代码:

connection = pool.acquire()

这些都不会有助于一个查询的执行,但至少它会阻止它的干扰!