峰峦@叠嶂 2025-08-13 19:12 采纳率: 98%
浏览 15
已结题

查询速度慢,怎么解决

请教一下,以下,是我的代码,用于查询生产系统内的药品追溯码的,目前是查询比较慢,查询91600条数据用时约12分钟,我们的数据库还是SQL SERVR 2008R2,其中w_JdrugUpload和w_drugInfo,是我自建的表,大数量是在jishun01_Code表,请问有什么办法,能给优化一下查询性能,也有给建议创建索引的,若是创建索引,会影响我们前端生产系统,以后增删删除改查操作吗;

if (Compro == "追溯码关联关系")
{
    try
    {
        // 分页参数
        int pageSize = 10000;  // 每页记录数
        int pageNumber = 1;    // 当前页码
        bool hasMoreData = true;
        int totalProcessed = 0;

        while (hasMoreData)
        {
            // 构建分页查询
            string pagedQuery = $@"
                                SELECT * 
                                FROM (
                                SELECT 
                                ROW_NUMBER() OVER (ORDER BY d.PrefixID) AS RowNum,
                                d.PrefixID as ID,t.BatchNo, p1.PackCode,p3.PackCode AS ParentPackCode,p3.LevelNo AS LevelNo,1 AS SuNum
                                FROM
                                jishun01.dbo.Task t
                                JOIN jishun01_Code.dbo.PackCodeInfo p1 ON t.Id = p1.PackageTaskID
                                JOIN jishun01.dbo.w_drugInfo w ON t.ProductID = w.ID AND p1.LevelNo = 1
                                JOIN Uploadata.dbo.w_JdrugUpload d ON w.NDC = d.NDC AND t.BatchNo = d.batchNo1
                                JOIN jishun01_Code.dbo.PackCodeInfo p2 ON p1.ParentPackCode = p2.PackCode AND p2.LevelNo = 2
                                JOIN jishun01_Code.dbo.PackCodeInfo p3 ON p2.ParentPackCode = p3.PackCode AND p3.LevelNo = 3
                                WHERE
                                t.ProductDate >= @startdate
                                AND t.ProductDate <= @enddate
                                AND p3.ParentPackCode IS NULL
                                ) AS PagedResults
                                WHERE RowNum BETWEEN {(pageNumber - 1) * pageSize + 1} AND {pageNumber * pageSize}
                                ORDER BY RowNum";

            // 执行分页查询
            DataTable pageData = new DataTable();
            using (SqlConnection connSource = new SqlConnection(Conn))
            {
                await connSource.OpenAsync();
                using (SqlCommand cmd = new SqlCommand(pagedQuery, connSource))
                {
                    cmd.Parameters.AddWithValue("@startdate", startdate);
                    cmd.Parameters.AddWithValue("@enddate", enddate);
                    cmd.CommandTimeout = 1000;  // 单个页面超时时间

                    using (SqlDataReader reader = await cmd.ExecuteReaderAsync())
                    {
                        pageData.Load(reader);
                    }
                }
            }

            // 检查是否还有更多数据
            hasMoreData = pageData.Rows.Count > 0;

            if (hasMoreData)
            {
                // 处理当前页数据
                using (SqlConnection connTarget = new SqlConnection(Conn1))
                {
                    await connTarget.OpenAsync();
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connTarget, SqlBulkCopyOptions.TableLock, null))
                    {
                        bulkCopy.DestinationTableName = "w_JTcodeUpload";
                        bulkCopy.BatchSize = 5000;
                        bulkCopy.BulkCopyTimeout = 1000;

                        // 列映射
                        bulkCopy.ColumnMappings.Add("ID", "batchNo");
                        bulkCopy.ColumnMappings.Add("ParentPackCode", "TlevelCode");
                        bulkCopy.ColumnMappings.Add("PackCode", "FlevelCode");
                        bulkCopy.ColumnMappings.Add("LevelNo", "PackLevel");
                        bulkCopy.ColumnMappings.Add("SuNum", "SuNum");

                        // 异步写入
                        await bulkCopy.WriteToServerAsync(pageData);
                    }
                }

                // 更新总数和页码
                totalProcessed += pageData.Rows.Count;
                pageNumber++;
            }
        }

        // 所有页处理完成
        MessageBox.Show($"数据批量插入成功!共处理 {totalProcessed} 条记录",
                       "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"操作失败: {ex.Message}\n\n{ex.StackTrace}",
                       "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

  • 写回答

7条回答 默认 最新

  • svygh123 2025-08-13 23:04
    关注

    建议先加索引,如果没有索引,就好比没有目录的新华字典,每次查询都要全本扫描,速度肯定慢。

    1、索引在逻辑上和物理上都与相关的表和数据无关,当创建或者删除一个索引时,不会影响基本的表;

    2、索引一旦建立,在表上进行DML操作时(例如在执行插入、修改或者删除相关操作时),数据库会自动管理索引,索引删除,不会对表产生影响

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 8月22日
  • 已采纳回答 8月14日
  • 创建了问题 8月13日