扬帆18 2025-10-30 09:11 采纳率: 50%
浏览 12

pyqt5连接mysql数据库卡住

我用PyQt5写了个查询mysql数据的程序,发现程序启动后查询正常,只要几分钟(测试过5min)不查询,再次查询时程序就会卡住,大概需要65s才能恢复,恢复后好像最初几次的查询的速度还会受影响,查询了几次后恢复正常。

img

问过deepseek说是数据库连接时没有用连接池造成的,改用了连接池,但问题依旧。

# 01创建数据库连接池
pool = PooledDB(
    creator=pymysql,  # 数据库驱动

    # 数据库相关参数
    host=C.SERVER_HOST,
    port=3306,
    user=C.DB_USER,
    password=C.DB_PASSWORD,
    database=C.DB_NAME,
    charset='utf8mb4',

    # 连接池配置
    maxconnections=50, # 最大总连接数
    mincached=5,      # 初始空闲连接数
    maxcached=20,     # 最大空闲连接数
    reset=True,
    blocking=True, # 连接耗尽时阻塞等待

    # 关键设置
    autocommit=True,
    ping=7 # 使用ping检查连接是否有效。0=不检查, 1=当连接被从池中取出时检查, 2=当创建游标时检查, 4=当查询执行时检查, 7=总是检查(1+2+4)
    )

大家有没有遇到过类似的问题的,有没有找到原因,有没有好的解决办法。

  • 写回答

4条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-10-30 09:53
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 程序启动后最初查询正常,但间隔几分钟不查询再次查询时会卡住约65s,且最初几次查询速度也受影响。这很可能是由于数据库连接的某种状态问题或者连接池相关的问题导致的。
      - 可能是连接在长时间闲置后出现了异常,重新建立连接或者恢复连接状态时花费了较长时间。
    2. 解决方案:
      - 使用连接池
      • 可以使用DBUtils库来实现数据库连接池。首先安装DBUtils库:pip install DBUtils
      • 示例代码如下:
    from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton
    from dbutils.pooled_db import PooledDB
    import pymysql
    
    
    class QueryWindow(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
            self.pool = PooledDB(pymysql, 5, host='localhost', user='root', passwd='password', db='testdb', port=3306)
    
        def initUI(self):
            self.setWindowTitle('MySQL Query')
            self.setGeometry(100, 100, 400, 200)
    
            self.label = QLabel('Query Result:', self)
            self.queryEdit = QLineEdit(self)
            self.queryButton = QPushButton('Query', self)
            self.queryButton.clicked.connect(self.queryDatabase)
    
            layout = QVBoxLayout()
            layout.addWidget(self.label)
            layout.addWidget(self.queryEdit)
            layout.addWidget(self.queryButton)
            self.setLayout(layout)
    
        def queryDatabase(self):
            query = self.queryEdit.text()
            conn = self.pool.connection()
            cursor = conn.cursor()
            cursor.execute(query)
            result = cursor.fetchall()
            conn.close()
            self.label.setText(str(result))
    
    
    if __name__ == '__main__':
        app = QApplication([])
        window = QueryWindow()
        window.show()
        app.exec_()
    
    • 优化数据库连接参数
      • 检查pymysql连接参数是否合理。例如,适当调整autocommit参数。如果设置为False,事务结束时需要手动调用conn.commit(),这可能会影响性能。可以尝试将其设置为True,让数据库自动提交事务。修改连接代码如下:
    conn = pymysql.connect(host='localhost', user='root', passwd='password', db='testdb', port=3306, autocommit=True)
    
    • 定期检查连接状态
      • 在程序中定期检查数据库连接是否有效。可以在每次查询前添加如下代码:
    import time
    
    
    def queryDatabase(self):
        query = self.queryEdit.text()
        conn = self.pool.connection()
        try:
            conn.ping(reconnect=True)
            cursor = conn.cursor()
            cursor.execute(query)
            result = cursor.fetchall()
        except pymysql.Error as e:
            print(f"Database error: {e}")
            result = []
        finally:
            conn.close()
            self.label.setText(str(result))
    
    1. 多种解决方案的优缺点:
      - 使用连接池
      • 优点
      • 可以有效管理数据库连接,避免频繁创建和销毁连接,提高性能。
      • 减少了连接建立的时间开销,对于频繁查询的场景非常适用。
      • 缺点
      • 引入了额外的库(DBUtils),增加了项目的依赖。
      • 需要对代码结构进行一定的调整,以适应连接池的使用。
      • 优化数据库连接参数
      • 优点
      • 简单直接,只需要对连接参数进行调整,不需要引入新的库。
      • 对于一些简单的连接状态问题可能有较好的效果。
      • 缺点
      • 可能无法完全解决连接长时间闲置后的问题,只是在一定程度上优化连接性能。
      • 对于复杂的连接异常情况可能无能为力。
      • 定期检查连接状态
      • 优点
      • 可以在一定程度上保证连接的有效性,及时处理连接异常。
      • 不需要引入新的库,代码修改相对简单。
      • 缺点
      • 增加了额外的检查逻辑,可能会消耗一定的系统资源。
      • 不能从根本上解决连接池管理的问题,只是一种辅助手段。
    2. 总结:
      - 程序在长时间不查询后再次查询卡住的问题,通过使用连接池、优化连接参数和定期检查连接状态等方法可以尝试解决。连接池是较为全面和有效的解决方案,但引入了新的库;优化连接参数简单直接但可能不完全解决问题;定期检查连接状态是一种辅助手段,可以增强程序的健壮性。具体选择哪种方案或结合使用,需要根据项目的实际情况来决定。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 修改了问题 10月30日
  • 创建了问题 10月30日