【问题标题】:Python hangs on fetchall using MySQL connectorPython 在使用 MySQL 连接器的 fetchall 上挂起
【发布时间】:2015-07-18 00:21:39
【问题描述】:

我对 Python 和 MySQL 还很陌生。我正在编写代码,在五分钟内查询 60 个不同的表,每个表都包含每秒的记录。该代码每五分钟执行一次。少数查询可以达到 1/2 MB 的数据,但大多数在 50 KB 范围内。我正在使用 MySQL 连接器/Python 在运行 Windows 7,64 位的工作站上运行。我正在使用 PowerShell windows 测试我的代码,但代码最终将作为计划任务运行。工作站有足够的 RAM (8 GB)。其他进程正在运行,但根据任务管理器,只使用了一半的内存。大多数情况下,一切都按预期执行,但有时处理会挂起。我在代码中插入了打印语句(我还使用了调试器跟踪)来确定挂起的位置。它发生在对 fetchall 的调用中。以下是代码的相关部分。所有大写字母都是(伪)常量。

mncdb = mysql.connector.connect(
    option_files=ENV_MCG_MYSQL_OPTION_FILE,
    option_groups=ENV_MCG_MYSQL_OPTION_GROUP,
    host=ut_get_workstation_hostname(),
    database=ENV_MNC_DATABASE_NAME
    )
for generic_table_id in DBR_TABLE_INDEX:
    site_table_id = DBR_SITE_TABLE_NAMES[site_id][generic_table_id]
    db_cursor = mncdb.cursor() 
    db_command = (
                  "SELECT *"
                  +" FROM "
                  +site_table_id
                  +" WHERE "
                  +DBR_DATETIME_FIELD
                  +" >= '"
                  +query_start_time+"'"
                  +" AND "
                  +DBR_DATETIME_FIELD
                  +" < '"
                  +query_end_time+"'"
                 )
    try:
        db_cursor.execute(db_command)
        print "selected data for table "+site_table_id
        try:
            table_info = db_cursor.fetchall()
            print "extracted data for table "+site_table_id
        except:
            print "DB exception "+formatExceptionInfo()
            print "FETCH failed to return any rows..."
            table_info = []
            raise
    except:
        print "uncaught DB error "+formatExceptionInfo()
        raise

。 . . 使用数据的其他处理 . . . db_cursor.close() mncdb.close() . . . 没有提出任何例外。在单独的 PowerShell 窗口中,我可以访问代码正在处理的数据。对于我的测试,数据库中的所有数据都是在代码执行之前加载的。在测试代​​码时没有进程正在更新数据库。挂起可能发生在第一次执行代码或执行几个小时后。

我的问题是什么可能导致代码挂在 fetchall 语句上?

【问题讨论】:

    标签: mysql python-2.7 mysql-connector-python


    【解决方案1】:

    您可以通过设置获取大小来缓解这种情况:

    mncdb = mysql.connector.connect(option_files=ENV_MCG_MYSQL_OPTION_FILE, option_groups=ENV_MCG_MYSQL_OPTION_GROUP,host=ut_get_workstation_hostname(,database=ENV_MNC_DATABASE_NAME, cursorclass = MySQLdb.cursors.SSCursor)
    

    但在执行此操作之前,您还应该在构建语句时使用mysql excuse for prepared statements 而不是字符串连接。

    【讨论】:

      【解决方案2】:

      挂起可能涉及 MySQL 表本身,而不是 Python 代码。它们包含许多记录吗?他们是很宽的桌子吗?它们是否在 datetime_field 上编入索引?

      考虑各种策略:

      1. 具体选择需要的列而不是星号,调用所有列。

      2. 在 where 子句中使用的 DBR_DATETIME_FIELD 的索引(即隐式连接)。

      3. 使用打印的计时器print(datetime.datetime.now()) 进一步诊断以查看哪些是瓶颈表。这样做时,请务必导入 datetime 模块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-18
        • 2014-07-25
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        • 1970-01-01
        • 2019-04-08
        • 2017-11-10
        相关资源
        最近更新 更多