3

我对 Python 和 MySQL 还很陌生。我正在编写代码,查询 60 个不同的表,每个表在 5 分钟内每秒包含记录。该代码每五分钟执行一次。少数查询可以达到 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 语句上?

4

2 回答 2

0

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

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 的借口来准备语句而不是字符串连接。

于 2015-07-18T01:35:06.557 回答
0

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

考虑各种策略:

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

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

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

于 2015-07-18T02:04:37.137 回答