我一直在阅读 Kimberly Tripp 撰写的一些关于 SQL Server 计划缓存的精彩文章,例如:http : //www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/
为什么甚至有“针对临时工作负载进行优化”的选项?这不应该一直开着吗?无论开发人员是否使用 ad-hoc SQL,为什么不在每个支持它的实例上启用此选项(SQL 2008+),从而减少缓存膨胀?
有没有一种系统的方法可以强制 PostgreSQL 将特定表加载到内存中,或者至少从磁盘中读取它以便系统缓存它?
所以今天早上我们有一个长时间运行的 proc 导致问题(30 秒 + 运行时间)。我们决定检查参数嗅探是否是罪魁祸首。因此,我们重写了 proc 并将传入的参数设置为变量,以阻止参数嗅探。一种尝试过的/真实的方法。Bam,查询时间得到改善(不到 1 秒)。在查看查询计划时,在原始未使用的索引中发现了改进。
为了验证我们没有得到误报,我们对原始 proc 进行了 dbcc freeproccache 并重新运行以查看改进的结果是否相同。但是,令我们惊讶的是,原来的 proc 仍然运行缓慢。我们再次尝试使用 WITH RECOMPILE,但仍然很慢(我们尝试在对 proc 的调用以及在 proc 内部进行重新编译)。我们甚至重新启动了服务器(显然是开发箱)。
所以,我的问题是……当我们在空计划缓存上得到相同的慢查询时,参数嗅探怎么会受到指责……不应该有任何参数嗅探???
我们是否会受到与计划缓存无关的表统计信息的影响。如果是这样,为什么将传入参数设置为变量会有所帮助??
在进一步的测试中,我们还发现,将在PROC的内部的OPTION(OPTIMIZE未知)DID得到预期的改进计划。
所以,你们中的一些人比我更聪明,你能提供一些关于幕后发生了什么来产生这种结果的线索吗?
另一方面,慢计划也有理由提前中止,GoodEnoughPlanFound而快计划在实际计划中没有提前中止原因。
总之
更新:
在此处查看慢速执行计划:https : //www.dropbox.com/s/cmx2lrsea8q8mr6/plan_slow.xml
在此处查看快速执行计划:https : //www.dropbox.com/s/b28x6a01w7dxsed/plan_fast.xml
注意:出于安全原因,表、架构、对象名称已更改。
我目前正在研究一个 MySQL 数据库,我们看到查询缓存中有大量无效,主要是因为在许多表上执行了大量的 INSERT、DELETE 和 UPDATE 语句。
我要确定的是,允许将查询缓存用于针对这些表运行的 SELECT 语句是否有任何好处。由于它们很快就失效了,在我看来,最好的办法是在这些表的 SELECT 语句上使用 SQL_NO_CACHE。
频繁失效的开销值得吗?
编辑:应以下用户@RolandoMySQLDBA 的要求,这里是有关 MyISAM 和 INNODB 的信息。
数据库
我的ISAM
附加信息:
我很难找到关于如何在 PostgreSQL 中缓存索引的“外行”解释,所以我想对这些假设中的任何一个或所有假设进行现实检查:
buffer cache与行位于相同的缓存(?)中,因此索引使用的缓存空间不可用于行。在开始之前,我想明确一点,使用部分索引会产生两个优势:
目前,DBCC FREEPROCCACHE当我想在运行 SQL 查询之间从缓冲池中清除信息时,我会运行。但是,我正在查看这篇Technet 文章,其中引用了DBCC FREESYSTEMCACHE. 哪些缓存会FREESYSTEMCACHE擦除而FREEPROCCACHE不会?
我如何在生产框中检查我的 SQL 服务器的内存使用情况。我正在使用 SQL Server 2016。当我检查任务管理器时,它显示在 90% 以上。我不认为这是 sql server 的真实内存使用情况。
我有一个 SQL 性能工具 grafana,它显示的 CPU 使用率比我在任务管理器中看到的少得多。我检查了资源监视器,可以看到平均 CPU 值。我对 SQL 服务器内存使用情况感到困惑。我正在尝试确定内存压力是否是我的某些问题的一个问题。
有人可以直接给出一个好的/正确的解释。
在 Dynamics AX 中有一个缓存机制,可以将表配置为加载到内存中并缓存。此缓存限制为一定数量的 KB,以防止出现内存问题。我正在谈论的设置被调用entiretablecache并在请求单个记录时将整个表加载到内存中。
直到最近,我们依靠一些脚本来验证具有此设置的表的大小,以查看表大小是否高于此限制。
然而,现在,压缩开始发挥作用,诸如sp_spaceused或sys.allocation_units 之类的东西似乎报告了压缩数据实际使用的空间。
显然,应用程序服务器正在处理未压缩的数据,因此 SQL Server 中磁盘上的数据大小无关紧要。我需要未压缩数据的实际大小。
我知道sp_estimate_data_compression_savings但正如名字所说,这只是一个估计。
我希望尺寸尽可能正确。
我能想到的唯一方法是一些复杂的动态 SQL 创建与压缩表具有相同结构的未压缩表,将压缩数据插入到影子表中,然后检查影子表的大小。
不用说,这有点乏味,在数百 GB 的数据库上运行需要一段时间。
Powershell 可能是一个选项,但我不想遍历所有表以select *对它们执行 a以检查脚本中的大小,因为这只会淹没缓存并且可能需要很长时间。
简而言之,如果可能的话,我需要一种方法来获取每个表的大小,因为它一旦被解压缩,并且在呈现给应用程序的等式中会出现碎片。我对不同的方法持开放态度,首选 T-SQL,但我不反对 Powershell 或其他创造性方法。
假设应用程序中的缓冲区是数据的大小。bigint 始终是 bigint 的大小,而字符数据类型是每个字符 2 个字节(unicode)。BLOB 数据也占用数据的大小,枚举基本上是一个整数,数字数据是 numeric(38,12),datetime 是日期时间的大小。此外,没有NULL值,它们要么存储为空字符串,要么存储1900-01-01为零。
没有关于如何实现的文档,但这些假设基于一些测试以及 PFE 和支持团队使用的脚本(显然也忽略了压缩,因为检查是在应用程序中构建的,而应用程序无法分辨)如果底层数据被压缩),它还检查表大小。例如,此链接指出:
避免对大型表使用 EntireTable 缓存(在 AX 2009 中超过 128 KB 或 16 页,在 AX 2012 中超过“整个表缓存大小”应用程序设置[默认值:32KB 或 4 页])——改为使用记录缓存。
我刚刚开始涉足我们的 CMS 的查询缓存。
谁能告诉我(或至少提供一个良好的猜测)为什么我得到了很多的Qcache_lowmem_prunes时候有一半以上Qcache_free_memory是免费的吗?
query_cache_size=512M
query_cache_limit=1M
Run Code Online (Sandbox Code Playgroud)
这是大约 12 小时后的样子
show status like '%qcach%';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| Qcache_free_blocks | 10338 |
| Qcache_free_memory | 297348320 |
| Qcache_hits | 10254104 |
| Qcache_inserts | 6072945 |
| Qcache_lowmem_prunes | 725279 |
| Qcache_not_cached | 2237603 |
| Qcache_queries_in_cache | 48119 |
| Qcache_total_blocks | 111346 |
+-------------------------+-----------+
Run Code Online (Sandbox Code Playgroud)
这就是它的照顾方式flush query cache;
show status like '%qcach%';
+-------------------------+-----------+
| Variable_name | …Run Code Online (Sandbox Code Playgroud) 在为使用 SQL Server 的应用程序运行性能测试/基线之前,我希望能够将实例设置为“干净”状态,而无需重新启动实例。我倾向于遵循一些步骤,但我想构建一个按正确顺序排列的明确列表,并且没有多余的步骤。
此步骤列表是否完成将 SQL Server 设置为“干净”状态?
顺序是否合乎逻辑/正确?
有没有多余的步骤?
CHECKPOINT -- Write all dirty pages
DBCC DROPCLEANBUFFERS -- All should be clean after checkpoint?
DBCC FREEPROCCACHE -- Clear the plan cache
DBCC FREESYSTEMCACHE -- Is this necessary after FREEPROCCACHE?
DBCC FREESESSIONCACHE -- May not be necessary if distributed queries aren't used, but want to catch all scenarios
EXEC SP_UPDATESTATS -- Refresh stats
'BEGIN TESTING!'
Run Code Online (Sandbox Code Playgroud) cache ×10
performance ×6
sql-server ×5
memory ×3
mysql ×2
postgresql ×2
buffer-pool ×1
compression ×1
dbcc ×1
index-tuning ×1
innodb ×1
myisam ×1
query-cache ×1
size ×1