You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Flask查询SQL Server大数据并渲染到HTML表格的性能问题

问题解决方案

核心问题根因

你当前的方案完全没有实现真正的分页逻辑,性能瓶颈非常明显:

  • 后端直接调用fetchall()一次性拉取全量22.9万行数据,数据库查询、网络传输、模板渲染三层都存在巨量性能损耗
  • 前端用Jinja循环直接生成22.9万行DOM节点,浏览器渲染超量DOM必然出现卡顿甚至冻结
  • 你配置的DataTable服务端分页是官方示例的模拟逻辑,完全没有和后端真实接口对接,属于无效配置
  • 额外存在字段不匹配问题:SQL仅查询A/B/C/D四个字段,但模板渲染了6个列,会触发索引异常

改造方案

后端改造(sql.py)

新增专门的分页数据接口,在SQL层面直接做分页查询,避免拉取全量数据,同时增加资源释放逻辑避免连接泄漏:

from datetime import datetime 
from flask import Flask, render_template, request, jsonify
import pypyodbc 
from waitress import serve

app = Flask(__name__)

# 原路由仅渲染空页面模板,不做数据查询
@app.route('/index', methods=['GET'])
def ShowResult():
    return render_template('index.html')

# 新增分页数据接口,专供DataTable调用
@app.route('/api/data', methods=['GET'])
def get_paginated_data():
    # 接收DataTable传递的分页参数
    draw = int(request.args.get('draw', 1))
    start = int(request.args.get('start', 0))
    page_size = int(request.args.get('length', 10))

    connection = None
    cursor = None
    try:
        connection = pypyodbc.connect('Driver={SQL Server}; Server=Server; Database=DB; UID=UserID; PWD={Password};')
        cursor = connection.cursor()

        # 查询总记录数
        cursor.execute("SELECT COUNT(*) FROM [TABLE]")
        total_count = cursor.fetchone()[0]

        # 分页查询,ORDER BY后替换为你实际需要排序的字段,保证分页结果顺序稳定
        cursor.execute("""
            SELECT A,B,C,D,E,F FROM [TABLE] 
            ORDER BY A OFFSET ? ROWS FETCH NEXT ? ROWS ONLY
        """, (start, page_size))
        page_data = cursor.fetchall()

        # 格式化返回数据
        format_data = [list(row) for row in page_data]
        return jsonify({
            "draw": draw,
            "recordsTotal": total_count,
            "recordsFiltered": total_count,
            "data": format_data
        })
    finally:
        # 主动释放数据库资源,避免连接泄漏
        if cursor:
            cursor.close()
        if connection:
            connection.close()

if __name__ == '__main__':
    serve(app, port=5009)

前端改造(index.html)

删除Jinja循环渲染逻辑,交由DataTable通过接口拉取数据渲染,修改后核心代码如下:

  1. 表格tbody清空,不需要提前渲染数据:
<tbody>
</tbody>
  1. 修改DataTable配置,删除模拟数据逻辑,对接后端接口:
$(document).ready(function() {
    $('#example').DataTable( {
        serverSide: true,
        ordering: false,
        searching: false,
        ajax: '/api/data',
        scrollY: 200,
        scroller: {
            loadingIndicator: true
        },
        deferRender: true // 开启延迟渲染,仅渲染可见区域行,进一步优化性能
    } );
} );
  1. 调整thead的表头列数,和实际查询的字段数对齐,避免表格错位。

额外优化建议

  • 给分页用到的排序字段增加数据库索引,可大幅提升分页查询速度
  • 若后续需要开启搜索功能,只需在后端接口新增对应过滤逻辑即可
  • 可根据团队使用习惯调整单页展示条数,平衡加载速度和浏览效率

内容的提问来源于stack exchange,提问作者Sara Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 09:06:03