MS SQL Server查询缓存

问题描述 投票:1回答:4

我的一个项目有一个非常大的数据库,我无法编辑索引等,必须按原样工作。

我在测试一些我将在他们的数据库上运行的查询时看到的内容是我在.net写的服务是第一次运行时它们很慢。

他们之前做过的事情是 - 他们有2个主要(大)表,主要用于。他们告诉我他们打开SQL Server Management Studio并运行一个

SELECT * 
FROM table1 
JOIN table2

第一次运行大约需要5分钟的查询,但如果再次运行它而不关闭SQL Server Management Studio则需要大约30秒。他们所做的是他们保持打开SQL Server Management Studio 24/7,这样当他们的一个程序执行与这两个表相关的查询(这几乎所有查询都是由他们的程序运行)才能有30秒运行时间而不是5分钟。

发生这种情况是因为我假设2个表被缓存,然后没有(或几乎没有)磁盘读取。

这是一个好主意,有一个服务然后运行查询来不时地缓存这两个表?或者是否有更好的解决方案,因为我无法编辑索引或拆分表等?

编辑:对不起只是我可能不清楚,数据库希望已经有索引,只是我不允许编辑它们或任何东西。

编辑2:查询计划:https://www.brentozar.com/pastetheplan/?id=ByC5s06Dm

sql .net sql-server database service
4个回答
0
投票

这可能是索引视图的候选者(如果你可以说服你的DBA创建它!),例如:

CREATE VIEW transhead_transdata
WITH SCHEMABINDING
AS
    SELECT
        <columns of interest>
    FROM
        transhead th
        JOIN transdata td
            ON th.GID = td.HeadGID;

GO

CREATE UNIQUE CLUSTERED INDEX transjoined_uci ON transhead_transdata (<something unique>);

这将“预先计算”JOIN(并在transheadtransdata更改时保持同步)。


1
投票

你不能创建索引?这是关于性能的最大问题。更好的解决方案是创建正确的索引并通过检查等待统计信息,资源争用等来解决任何性能......我将从Brent Ozar's blog和开源工具开始,然后从那里继续前进。

保持SSMS打开不会阻止清除计划缓存。我会从一些链接开始。

除此之外...该查询是可疑的。我不希望您的应用程序使用这些结果。也就是说,我不希望您每次调用时将两个表中的每一行和每列加载到您的应用程序中。了解对这些相同表的不同查询,例如选择较少的列,添加谓词等,可能并且可能会导致SQL Server生成更优化的新查询计划。当前查询,没有谓词并选择每一列......并且没有如你所述的索引,只会进行两次表扫描。未来性能的任何提高都不会因为计划被缓存,而是因为数据存储在内存中,后续读取不会进行物理读取。即它是从内存和磁盘读取。

还有更多可以说的,但我会在这里停下来。


0
投票

您还可以考虑将此查询放入存储过程,然后可以将其安排为通过SQL代理定期运行,以保持缓存所需的页面。


0
投票

感谢@scsimon @Branko Dimitrijevic的回答,我认为他们非常有用,并且引导我朝着正确的方向前进。

最后,事实证明,最大的两个问题是硬件资源(RAM,没有SSD)和设置为True的自动关闭功能。

我做的其他修复(在这里写给其他试图改进的人):

  • 帮助程序服务工具将每周重新排列(碎片整理)一次索引,并将每月重建一次。
  • 创建一个包含2个表中所有列的视图 - 以消除JOIN成本。
  • 建议DBA可以帮助更好的表/索引
  • 建议改进服务器硬件......

接受@Branko Dimitrijevic的回答,因为我不能同时接受

© www.soinside.com 2019 - 2024. All rights reserved.