【问题标题】:SQL Server cache questionSQL Server 缓存问题
【发布时间】:2010-01-04 22:00:52
【问题描述】:

当我第一次运行某个存储过程时,大约需要 2 分钟才能完成。当我第二次运行它时,它在大约 15 秒内完成。我假设这是因为第一次运行后所有内容都被缓存了。在我第一次运行此过程之前,我是否可以“预热缓存”?缓存的信息是只在我再次调用相同参数的同一个存储过程时使用,还是在我调用不同参数的相同存储过程时才使用?

【问题讨论】:

    标签: sql-server-2005 caching performance


    【解决方案1】:

    当您执行查询时,数据会以块的形式读入内存。这些块保留在内存中,但它们会“老化”。这意味着块被标记为最后一次访问,并且当 Sql Server 需要另一个块进行新查询并且内存缓存已满时,最近最少使用的块(最旧的)将被踢出内存。 (在大多数情况下 - 全表扫描块会立即老化,以防止全表扫描超出内存并阻塞服务器)。

    这里发生的情况是,第一次查询的内存中的数据块尚未被踢出内存,因此可以用于第二次查询,这意味着避免了磁盘访问并提高了性能。

    所以你的问题真正要问的是“我可以将我需要的数据块放入内存而不将它们读入内存(实际上是在进行查询)吗?”。答案是否定的,除非您想缓存整个表并将它们永久驻留在内存中,从您描述的查询时间(以及数据大小)来看,这可能不是一个好主意。

    提高性能的最佳选择是查看查询执行计划并查看更改索引是否会产生更好的结果。这里有两个主要方面可以提高性能:

    • 创建一个索引,查询可以使用一个索引来避免低效查询和全表扫描
    • 向索引添加更多列以避免第二次磁盘读取。例如,您有一个查询返回列 A 和 B,并在 A 和 C 上有一个 where 子句,并且您在列 A 上有一个索引。您的查询将使用列 A 的索引,需要读取一个磁盘,但随后需要第二个磁盘命中以获取列 B 和 C。如果索引中包含所有列 A、B 和 C,则可以避免第二个磁盘命中以获取数据。

    【讨论】:

      【解决方案2】:

      我认为生成执行计划的时间不会超过 1 秒。

      我认为第一次和第二次运行的差异是由于缓存数据在内存中造成的。

      缓存中的数据可以被任何进一步的查询(存储过程或简单选择)重用。

      您可以通过读取相同数据的任何选择读取数据来“加热”缓存。但这甚至会花费大约 90 秒。

      【讨论】:

        【解决方案3】:

        您可以检查执行计划以了解您的查询使用了哪些表和索引。然后,您可以执行一些 SQL 以将数据放入缓存中,具体取决于您看到的内容。

        • 如果您看到聚集索引查找,您可以简单地执行 SELECT * FROM my_big_table 以强制将所有表的数据页放入缓存中。
        • 如果您看到非聚集索引搜索,您可以尝试SELECT first_column_in_index FROM my_big_table

        要强制加载特定索引,您还可以在缓存预热查询中使用 WITH(INDEX(index)) 表提示。

        【讨论】:

          【解决方案4】:

          SQL 服务器缓存从磁盘读取的数据。 连续读取会减少 IO。 这很有帮助,因为磁盘 IO 通常是瓶颈。

          更多信息: http://blog.sqlauthority.com/2014/03/18/sql-server-performance-do-it-yourself-caching-with-memcached-vs-automated-caching-with-safepeak/

          【讨论】:

            【解决方案5】:

            执行计划(过程的缓存信息)每次都被重用,即使使用不同的参数。这是使用存储过程的好处之一。

            第一次执行存储过程时,SQL Server 会生成一个执行计划并将其放入过程缓存中。

            对数据库的某些更改会触发执行计划的自动更新(您也可以明确要求重新编译)。

            执行计划根据其“年龄”从过程缓存中删除。 (来自 MSDN:不经常引用的对象很快就有资格进行解除分配,但实际上并没有被解除分配,除非其他对象需要内存。)

            我认为没有任何方法可以“加热缓存”,除了执行一次存储过程。这将保证缓存中有一个执行计划,任何后续调用都会重用它。

            更多详细信息请参见 MSDN 文档:http://msdn.microsoft.com/en-us/library/ms181055(SQL.90).aspx

            【讨论】:

            • 您的回复,虽然我看不出有什么问题,但没有抓住重点。查询编译不需要 1 分 45 秒,所以这不是 OP 的问题。 OP 缓存问题与数据页缓存有关,与执行计划缓存无关。
            猜你喜欢
            • 2013-07-26
            • 1970-01-01
            • 2012-08-13
            • 1970-01-01
            • 1970-01-01
            • 2011-11-07
            • 1970-01-01
            • 1970-01-01
            • 2016-03-09
            相关资源
            最近更新 更多