我有一个 ASP.NET 网站,它自己独立缓存数据,并且数据在很长一段时间内不会改变,所以它不需要用相同的查询第二次查询 SQL Server。我需要提高到该 SQL Server 的首次(原始)查询的性能。某些查询处理的数据过多,可能会导致 SQL Server 使用tempdb. 我不使用临时表变量或临时表,因此 SQL Server 决定tempdb在需要时自行使用。
我的数据库大小是 16Gb,我的服务器机器上有 32Gb 的物理 RAM。
我知道 MS SQL Server 缓存策略会尝试将数据保留在 RAM 中,以在类似查询需要再次加载相同数据时提高它们的性能。除此之外,它会尝试使用可用 RAM 而不是 tempdb 来提高性能,而不会导致磁盘访问。
我想当需要在 tempdb SQL Server 中存储某些内容的查询出现并且没有足够的可用 RAM 时,SQL Server 有两种选择:
1) 卸载一些缓存数据并使用备用 RAM 而不是 tempdb 以避免磁盘写入
2) 为将来的查询保留缓存数据并开始使用 tempdb,这会导致写入磁盘速度变慢。
我不知道 SQL Server 在这种情况下会做出什么选择,但我希望它做出选择 #1,因为我只关心首次(原始)查询的性能,因为我再也不会向 SQL Server 发送相同的查询(虽然我可能会发送类似的查询)。
这种情况下的 SQL Server 缓存策略是什么?
它如何在避免原始查询的 tempdb 和第二次查询的速度之间平衡 RAM 的使用?
是否可以将 SQL Server 配置为做出选择 #1 的方式?如果是,那么如何?
我还能如何提高所有原始 SQL 查询的性能?
由于我不知道 …
有没有办法可以确定计划是为特定查询生成的,还是在计划缓存中找到的?
有没有办法找出表在 SQL Server(2005 及更高版本)中占用了多少内存?
例如,假设我有一个包含 3000 万条记录的表。我想知道当前缓冲区缓存中有多少属于该表的页面,包括索引、数据和文本/图像页面。
我找到了 Pinal Dave 的这个查询,但似乎这个查询只返回由索引分配的页面(无论是集群的还是非集群的)。
我EXPLAIN (ANALYZE, BUFFERS) SELECT ...在我的 Postgres 9.3 服务器上运行。我最终Buffers: shared hit=166416 dirtied=2在输出中看到了类似的东西。
从文档中,“脏”表示:
脏的块数表示此查询更改的先前未修改的块数;而写入的块数表示该后端在查询处理期间从缓存中逐出的先前脏块的数量。
这听起来像是将块标记为脏的过程应该只在更新数据时发生。SELECT但是,我的查询是,并且只读取数据。我想它只会报告点击或阅读。我显然错了。但是,在这种情况下到底发生了什么?
我有一个运行多个数据库的 SQL2012 SP4 节点。
服务器有 20GB 可用内存,14GB 分配给 SQL(盒子上没有其他东西在运行)。
每隔几分钟,SQL 就会转储整个缓冲区缓存。页面预期寿命为零,缓冲区缓存描述符显示缓存中没有任何内容。
我查看了资源监视器通知,通知每隔几毫秒从高/稳定/低反弹:
RESOURCE_MEMPHYSICAL_HIGH RESOURCE_MEM_STEADY RESOURCE_MEMPHYSICAL_LOW
时间戳相隔几毫秒。PLE 本质上是一种锯齿图案。
我以前在 SQL2012 SP1 和这个问题中看到过这种情况:
未使用缓冲区缓存中的 SQL Server 2012 空闲页
似乎是一个类似的问题,虽然我已经更新到 SP4。
我试过为服务帐户打开 LPIM,我试过搞乱最大内存设置。降低最大内存似乎导致缓冲区缓存更频繁地清空。
关于下一步要检查什么的任何想法?
服务器工作负载实际上什么都没有(我正在浏览 ERP 系统中的项目列表,在缓存再次下降之前它达到了大约 40-50MB)。
这很有趣,因为我从 SP1 升级来尝试解决这个问题 - 那里的缓存达到了大约 500MB。从那以后,我将最大内存设置降低到 14GB,这似乎使情况变得更糟。
我想知道 Windows 是否会恐慌并在 SQL 处抛出错误的内存压力通知 - 因此将最大内存设置为无界的服务器似乎运行正常,但从未填充超过几百 MB 的缓存 - 但现在它勉强达到50...
更多信息:对于那些问
核心数: 4
数据库大小: 80GB
错误日志显示: A significant part of sql server process memory has been paged out. This may result in a performance degradation. Duration: 0 …
当所有数据页都应仅在磁盘中时,我必须找到在 SQL-SERVER 2016 中执行查询所需的总时间。为此,我使用以下命令清除了 SQL-SERVER 中的所有缓冲区:
DBCC FREEPROCCACHE WITH NO_INFOMSGS
GO
DBCC DROPCLEANBUFFERS
GO
DBCC FREESESSIONCACHE
GO
DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL
GO
DBCC FLUSHPROCINDB (@dbId)
GO
Run Code Online (Sandbox Code Playgroud)
在此之后,我再次发现存在逻辑读取,然后我了解了 Read-Ahead ,因此我通过跟踪标志禁用了预读
DBCC TRACEON(652,-1)
GO
Run Code Online (Sandbox Code Playgroud)
以及预取标志
DBCC TRACEON(8744,-1)
GO
Run Code Online (Sandbox Code Playgroud)
现在我仍然有逻辑读取,但物理读取明显高于清除缓冲区。有什么办法可以实现0逻辑读,还是我对逻辑读的理解有误?
请指导我,我是 SQL-SERVER 世界的新手
当您仅重新启动 SQL 服务本身时,服务器缓存是否会被擦除(类似于重新启动 SQL 实例/机器时)?
我正在管理一个运行使用 PostgreSQL 的工具的服务器。该工具自行处理大多数 PostgreSQL 配置,但我观察到一些性能问题。我可以在操作系统级别确认正在发生大量 I/O,因此我怀疑正在发生大量缓存未命中。
如果您在互联网上寻找“缓存未命中”或“缓存未命中 postgresql”或类似的搜索,您会发现很多对“ cache_miss 统计信息”的引用。但是没有任何地方解释如何获得它们!我有点理解,该值必须从 fetches 中减去命中来计算。但由于我不是经验丰富的数据库管理员,我真的不明白价值观的意思:-S
我找到了PostgreSQL - Monitoring Database Activity文档,但我不确定以下公式是否是我所需要的:
cache_miss = "result_of" pg_stat_get_db_blocks_fetched(oid) - "result_of" pg_stat_get_db_blocks_hit(oid)
Run Code Online (Sandbox Code Playgroud)
对假人的解释将不胜感激。
先感谢您!
近日,笔者从标准MySQL来移动Percona,并使用了Percona的向导生成my.cnf。
但是,我可以看到,默认情况下,生成的my.cnfuse设置query_cache_type = 0。(查询缓存被禁用)。
我在服务器上运行的唯一内容是 Wordpress 博客。我的问题是:
我有几个关于数据缓存如何工作的问题
想象一下我们有以下情况:
服务器重新启动或我们刚刚运行 DBCC DROPCLEANBUFFERS
我们有一个Table150 GB 并且有列A, B, C, D, E。
列A是聚集索引键,列B和C对他们的非聚集索引。
当我们做
select top 100 * from Table1
Run Code Online (Sandbox Code Playgroud)
整个聚集索引(表)是否从磁盘读取到内存,即使我们只需要 100 行?还是只有 100 行(它们的数据页)从磁盘读取到内存?
与非聚集索引相同,当我们这样做时
select top 100 * from Table1 where column B = 'some value'
Run Code Online (Sandbox Code Playgroud)
整个非聚集索引+聚集索引是否被加载到内存中?或者只有来自非聚集索引的 100 行和来自聚集索引的 100 行?
cache ×10
sql-server ×7
memory ×3
performance ×2
postgresql ×2
query ×2
statistics ×2
explain ×1
mysql ×1
optimization ×1
percona ×1
plan-cache ×1