【问题标题】:Linq performance: Two queries, the first response immediately and the second is very slowLinq 性能:两次查询,第一次立即响应,第二次很慢
【发布时间】:2012-03-27 06:43:26
【问题描述】:

我有两个查询非常相似,使用 Linq ExecuteQuery 方法第一个需要 30 秒,而第二个查询是中间的。

我也在 Microsoft SQL Server Management Studio 中执行查询,两个查询的响应时间为 0 秒。

查询 1(慢)

IEnumerable<ViewDataTanksDataDevice> res= 
this.ExecuteQuery<ViewDataTanksDataDevice>(
   "SELECT TOP 1 * FROM ViewDataTanksDataDevicesSB WHERE id_tank = {0} AND date >= {1} order by date", 
   new object[] { tankId, date });

查询 2(快速)

IEnumerable<ViewDataTanksDataDevice> res= 
this.ExecuteQuery<ViewDataTanksDataDevice>(
   "SELECT TOP 1 * FROM ViewDataTanksDataDevicesSB WHERE id_tank = {0} AND date <= {1}     order by date desc", 
   new object[] { tankId, date });

注1:ViewDataTanksDataDevicesSB是一个带有SCHEMA BINDING的视图,它有两个索引

  1. 索引 1(id_tank,日期升序)
  2. 索引 2(id_tank,日期描述)

注意 2:如果我先执行第二个查询,结果是相同的:查询 1 慢,查询 2 快。

注意 3:视图有数百万个寄存器,不同日期和坦克的结果是相同的。

【问题讨论】:

  • 执行计划告诉你什么?
  • 如果先运行查询 2,最后运行查询 1,会发生什么情况?
  • 您可以考虑在执行代码查询和执行计划时查看 SQL Server 的 Profiler 工具。它闻起来很像索引问题(ASC 与 DESC)
  • 对于给定的日期,第一个查询的工作集是否明显更大?此外,它对某些日期输入的响应是否比其他的更快?
  • 您是否尝试过更新统计信息? EXEC sp_updatestats。因为听起来查询计划的生成方式错误

标签: sql-server linq-to-sql executequery


【解决方案1】:

如果不比较查询计划等。这很难回答...

但是从您的描述看来,在 SSMS 中运行时,这两个查询都很快,而在 .NET 中运行时,其中一个查询很慢 - 这种不同行为的原因可能在于用于 DB 会话的设置,SSMS 有默认值不同于 ADO.NET 中使用的默认值(这是 LINQ 使用的)。可以在here找到非常详细的解释,包括一些关于如何解决这方面某些情况的提示。

请发布更多详细信息,尤其是。查询计划以获得更具体的帮助...

【讨论】:

    【解决方案2】:

    尝试在查询末尾添加option(recompile)

    更新

    您的索引 1 和索引 2 几乎相同,您可以删除其中任何一个。也可以通过表上的with(index(ix_index1)) 选项提示引擎使用哪个索引,如下所示:

    SELECT TOP 1 * 
    FROM ViewDataTanksDataDevicesSB with(index(ix_index1))
    WHERE id_tank = 123 AND date <= '20120313'
    order by date desc
    

    【讨论】:

    • 是的...我重新编译并清除了执行计划缓存。
    【解决方案3】:

    一周后我解决了,查看执行计划(感谢Yahia的建议)!!!

    在两个查询中,我指定了 INDEX(感谢 Denis)并且我必须指定提示 NOEXPAND

    NOEXPAND解释可以在:Table hints

    所以,最终的查询是:

    查询 1

    IEnumerable<ViewDataTanksDataDevice> res= 
    this.ExecuteQuery<ViewDataTanksDataDevice>(
       "SELECT TOP 1 * FROM ViewDataTanksDataDevicesSB with (index(IX_ViewDataTanksDataDevicesSB_TankIdDate) noexpand) WHERE id_tank = {0} AND date >= {1} order by date", 
       new object[] { tankId, date });
    

    查询 2

    IEnumerable<ViewDataTanksDataDevice> res= 
    this.ExecuteQuery<ViewDataTanksDataDevice>(
       "SELECT TOP 1 * FROM ViewDataTanksDataDevicesSB with (index(IX_ViewDataTanksDataDevicesSB_TankIdDate) noexpand) WHERE id_tank = {0} AND date <= {1} order by date desc", 
       new object[] { tankId, date });
    

    【讨论】:

      【解决方案4】:

      您能否提供来自 MS SQL Server Profiler 的更多信息?查询计划是首选以确定它是在 MS SQL Server 端还是在 CLR 端。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-12
        • 2020-12-03
        • 2021-07-23
        • 2013-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多