2

我有这个查询来获取两个日期之间账单的所有详细信息:

SELECT DT.* 
FROM DetailTable DT, BillTable BT, PackageTable PT
WHERE PT.Id = BT.IdPackage 
  AND DT.IdBill= BT.Id 
  AND PT.CodeCompany = @codeCompany
  AND PT.Date BETWEEN @begin and @end

每个包裹都有很多账单,我想获取公司账单的详细信息,数据库中的结果只有 20,000,但我有:

System.Data.SqlClient.SqlException (0x80131904):超时已过期。在操作完成之前超时时间已过或服务器没有响应。

C#代码:

using (SqlConnection sqlConn = new SqlConnection(SqlServerMasterConnection))
{
  if (sqlConn.State != ConnectionState.Open) sqlConn.Open();
  using (SqlCommand cmd = new SqlCommand("select DT.* from DetailTable DT, BillTable BT, PackageTable PT where  PT.Id= BT.IdPackage and DT.IdBill= BT.Id and  PT.CodeCompany = @codeCompany and PT.Date between @begin and @end",
                            sqlConn))
  {
    cmd.Parameters.Add(new SqlCeParameter(@begin , beginDate));
    cmd.Parameters.Add(new SqlCeParameter("@end", endDate));
    cmd.Parameters.Add(new SqlCeParameter("@codeCompany", codeCompany));
    using (DbDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
           //work todo
        }
    }
  }
}

我什至在 SQL Server Management 中尝试过这个需要 25 秒!任何提示请解决这个问题。

更新

这是执行计划:

在此处输入图像描述

更新2

对于这个问题,我有两个问题(我想要你的想法)。

  1. PT.Date是一个char(8)(开发人员使用它如何开始这个项目)(yyyyMMdd)

  2. 包含detailTable102 列。

4

1 回答 1

3

试试这个查询 -

SELECT DT.*
FROM dbo.DetailTable DT
WHERE EXISTS(
    SELECT 1
    FROM dbo.BillTable BT
    JOIN (
        SELECT PT.Id
        FROM dbo.PackageTable PT
        WHERE PT.CodeCompany = @codeCompany
            AND PT.Date BETWEEN @begin AND @end 
    ) PT ON PT.Id = BT.IdPackage
    WHERE DT.IdBill = BT.Id 
)

另一种方式 -

CREATE PROCEDURE dbo.usp_Test1
      @codeCompany VARCHAR(50)
    , @begin DATETIME
    , @end DATETIME
AS
BEGIN

    IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
    DROP TABLE #temp

    CREATE TABLE #temp (ID BIGINT PRIMARY KEY)

    INSERT INTO #temp (ID)
    SELECT BT.Id
    FROM dbo.BillTable BT
    JOIN dbo.PackageTable PT ON PT.Id = BT.IdPackage
    WHERE PT.CodeCompany = @codeCompany
    AND PT.[Date] BETWEEN @begin AND @end 

    SELECT DT.*
    FROM dbo.DetailTable DT
    WHERE DT.IdBill IN (SELECT Id FROM #temp)

END
于 2013-08-28T10:44:52.337 回答