首页 > 解决方案 > 我的查询在 SSMS 中很快,但在我的应用程序中超过 1 小时

问题描述

我的应用程序中的查询速度很慢,但在 SSMS 中查询速度非常快。看到一些答案后,我注意到执行计划似乎有所不同。

我注意到,当我使用 SSMS 时,使用了称为 [Parallelism (Repartition Streams)] 的东西,但我在 C# 应用程序的执行计划中没有看到它(我在 SSMS 中使用 Activity Monitor 来查看)。此外,当我使用我的应用程序时,我看到查询列在“活动昂贵查询”列表中,但当我从 SSMS 运行它时,情况并非如此。

我将添加我的查询,但为了我的公司隐私尝试隐藏一些文本:

SELECT  [REC_INVENT_LIST_ID]
      , ril.[NOTE_TYPE_ID]
      , ril.[TRANS_ID] 
      , [QUANTITIES]
      , [AMOUNT]
      , nt.[CU_TYPE]
      , nt.[CASH_TYPE]
      , nt.[NOTE_VALUE]
      , nt.[UNIT_ID]
      , t.RECYCLER_ID
FROM [D].[dbo].[RecyclerInventoryList] ril
JOIN [S].[dbo].[NoteType] nt ON nt.NOTE_TYPE_ID = ril.NOTE_TYPE_ID
JOIN [D].[dbo].[Transaction] t ON ril.TRANS_ID = t.TRANS_ID
WHERE QUANTITIES <> 0
AND ril.TRANS_ID IN (
        SELECT sub.TRANS_ID FROM (SELECT *, MAX(CREATE_DATE) 
        OVER(PARTITION BY t.RECYCLER_ID) AS _max
        FROM [D].[dbo].[Transaction] AS t
        WHERE TRANS_ID <= @lastTransId) AS sub
        WHERE CREATE_DATE = _max
                 )
ORDER BY t.RECYCLER_ID, CU_TYPE 

我所做的是:

1-我试图删除它所说的部分WHERE TRANS_ID <= @lastTransId以确保它不是参数转换问题,但这没有帮助。

2- 我删除了它说 WHERE CREATE_DATE = _max我在应用程序中快速返回结果的部分!但这不是我想要的结果。这对我来说真的很重要。

3-我使用 SQL SERVER PROFILER 来查看在我的应用程序超时和崩溃(1 小时命令超时)后尝试运行的确切查询是什么我看到这样

exec sp_executesql N'SELECT [REC_INVENT_LIST_ID], ril.[NOTE_TYPE_ID], ril.[TRANS_ID], [QUANTITIES], [AMOUNT], nt.[CU_TYPE], nt.[CASH_TYPE], nt.[NOTE_VALUE], nt.[UNIT_ID], t.[RECYCLER_ID] FROM[RCMDYNAMIC].[dbo].[RecyclerInventoryList] ril JOIN[RCMSTATIC].[dbo].[NoteType] nt ON nt.NOTE_TYPE_ID = ril.NOTE_TYPE_ID JOIN[RCMDYNAMIC].[dbo].[Transaction] t ON ril.TRANS_ID = t.TRANS_ID  WHERE QUANTITIES<> 0 AND ril.TRANS_ID IN (SELECT sub.TRANS_ID FROM (SELECT TRANS_ID, CREATE_DATE , MAX(CREATE_DATE) OVER(PARTITION BY t.RECYCLER_ID) AS _max FROM[RCMDYNAMIC].[dbo].[Transaction] AS t WHERE TRANS_ID <= @lastTransId ) AS sub WHERE CREATE_DATE = _max) ORDER BY t.RECYCLER_ID, CU_TYPE',N'@lastTransId int',@lastTransId=XXXXX

当我在 SSMS 上运行它时,它仍然非常快(毫秒),并且执行计划似乎与我直接从 SSMS 运行查询时相同。

有任何想法吗?

编辑:

我的 C# 代码:

public Dictionary<int, List<RCMBalanceTransactionModel>> getBalanceTransactions(int transId) {

        SqlCommand command;
        SqlDataReader reader;
        command = new SqlCommand(getBalanceTransactionInfoQuery(), con);
        command.CommandTimeout = 3600;
        command.Parameters.AddWithValue("@lastTransId", transId);
        reader = command.ExecuteReader();


  //the rest is omitted the application is stuck here at ExecutedReader();
}

标签: c#sqldatabaseexecutequery

解决方案


I tried to rewrite the query, but without data I am not sure if I got it right

SELECT  [REC_INVENT_LIST_ID]
      , ril.[NOTE_TYPE_ID]
      , ril.[TRANS_ID] 
      , [QUANTITIES]
      , [AMOUNT]
      , nt.[CU_TYPE]
      , nt.[CASH_TYPE]
      , nt.[NOTE_VALUE]
      , nt.[UNIT_ID]
      , t.RECYCLER_ID
FROM [D].[dbo].[RecyclerInventoryList] ril
JOIN [S].[dbo].[NoteType] nt ON nt.NOTE_TYPE_ID = ril.NOTE_TYPE_ID
JOIN [D].[dbo].[Transaction] t ON ril.TRANS_ID = t.TRANS_ID
WHERE QUANTITIES <> 0
AND t.TRANS_ID <= @lastTransId
AND NOT EXISTS(SELECT 1 FROM [D].[dbo].[Transaction] AS t2 
    WHERE t2.RECYCLER_ID = t.RECYCLER_ID 
      AND t2.CREATE_DATE > t.CREATE_DATE 
          AND t2.TRANS_ID <= @lastTransId)

ORDER BY t.RECYCLER_ID, CU_TYPE 

推荐阅读