2013-08-28 44 views
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 

每包有很多賬單,我希望得到一個公司的法案的細節, 結果數據庫,它只是二萬元,我有:

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管理中,它需要25秒!任何提示請解決。

更新

這是執行計劃:

enter image description here

UPDATE2

還有就是我對這個問題的事(我想你的想法)兩個問題。

  1. PT.Datechar(8)(它被用來由顯影劑如何開始此項目)(YYYYMMDD)

  2. detailTable包含102列。

+0

使用正確的連接。這是2013 – podiluska

+0

請添加您的執行計劃。也許你只需要在你的表上添加一些索引。 – Devart

+0

@Devart,添加了執行計劃,並且使用Id作爲主鍵自動增量,並且與外鍵 – Akrem

回答

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 
+0

第一個同樣的結果(24秒),但是用PROCEDURE只有7秒,我不想用它,我會讓它成爲我最後的解決方案,(thx爲您的答案) – Akrem