Python 使用mysql连接池

与普通的pymysql方式相比,主要区别在于是否使用连接池(Connection Pool):

性能优势:

连接池预先创建和维护一组数据库连接,避免了频繁创建和销毁连接的开销 当需要连接时,直接从池中获取,而不是重新建立连接 特别是在高并发场景下,性能差异显著

资源管理:

你给出的代码每次都创建新连接,可能导致数据库连接数暴增 连接池可以限制最大连接数,防止数据库服务器过载 自动管理空闲连接,及时释放不需要的连接

连接复用:

# 使用连接池
for i in range(1000):
    conn = pool.connection()  # 从池中获取已存在的连接
    # 使用连接
    conn.close()  # 实际上是返回到池中,而不是真正关闭

# 不使用连接池
for i in range(1000):
    conn = pymysql.connect(**config)  # 每次都创建新连接
    # 使用连接
    conn.close()  # 真正关闭连接并释放资源

结论

  1. 单次脚本执行:pymysql的方式够用
  2. Web应用或长期运行的服务:建议使用连接池
  3. 高并发场景:连接池几乎是必须的

代码

pip install DBUtils


from dbutils.pooled_db import PooledDB
import pymysql
import os
import sys
from pathlib import Path

# 获取项目根目录路径
current_file = Path(__file__).resolve()
project_root = str(current_file.parent.parent.parent)  
sys.path.append(project_root)

# 导入并加载.env
from dotenv import load_dotenv
env_path = os.path.join(project_root, '.env')
load_dotenv(env_path)



class DBPool:
    _pools = {}

    @classmethod
    def get_pool(cls, database):
        if database not in cls._pools:
            mysql_config = {
                'host': os.getenv('url'),
                'port': int(os.getenv('port')),
                'user': os.getenv('user'),
                'password': os.getenv('pwd'),
                'database': database,
                'charset': 'utf8mb4'
            }
            
            cls._pools[database] = PooledDB(
                creator=pymysql,
                maxconnections=32,
                mincached=5,
                maxcached=10,
                maxusage=1000,
                blocking=True,
                **mysql_config
            )
        return cls._pools[database]

def get_db_connection(database):
    """从连接池获取连接"""
    pool = DBPool.get_pool(database)
    return pool.connection()

conn = get_db_connection('okx')
cursor = conn.cursor()
cursor.execute("SELECT * FROM `15m_btc` LIMIT 10")
print(cursor.fetchall())
cursor.close()
conn.close()

作者:spike

分类:

创作时间:2025-01-01

更新时间:2025-01-02

联系方式放在中括号之中例如[[email protected]],回复评论在开头加上标号例如:#1