TL;DR:通过schema.table表缓存引用的表是否保留?
我有大量客户端数据库,我们的应用程序基于 http 请求连接到这些数据库。这些用于应用程序的每个部分,除了访问日志记录。我们使用第二个中央模式来记录跨应用程序所有实例的登录尝试。
但是,登录表是通过与本地模式的连接作为外部表访问的。例如:
UPDATE central_schema.login SET column = 'value';
Run Code Online (Sandbox Code Playgroud)
而不是直接使用第二个连接到中央模式并仅login作为本地表处理:
UPDATE login SET column = 'value';
Run Code Online (Sandbox Code Playgroud)
或者切换模式:
USE central_schema;
UPDATE login SET column = 'value';
USE client_schema;
Run Code Online (Sandbox Code Playgroud)
鉴于在繁忙时期,我看到很多简单的更新或选择查询等待表关闭,当引用跨模式时,MySQL 是否可能不缓存表?是否有可能因为它连接到client_schema,它想要使用客户端架构缓存,因此无法正确缓存外部表?
而且,如果我不能得到一个明确的答案,我将如何开始测试缓存中的内容和不包含的内容?
我有两个 mysql 5.1 实例(比如 A、B)托管相同的数据库架构。如果我在两个实例上运行(使用 mysql 工作台)相同的查询,我不明白为什么我在后续请求中得到非常不同的响应时间。
在实例 A 上,第一次查询执行需要 0.688 秒,第二次查询执行需要 0.683 秒
在实例 B 上,第一次查询执行需要 0.688 秒,第二次查询执行需要 0.027 秒
看起来两个实例之间存在缓存配置差异,但我找不到它。
比较SHOW VARIABLES两个实例的结果只给出了几个不同的值(我看不出它们如何影响查询执行时间):
general_log_file :
/path/to/file2.log VS /path/to/file1.log
hostname :
mysql2 VS mysql1
pid_file :
/var/lib/mysql/mysql2.pid VS /var/lib/mysql/mysql1.pid
slave_max_allowed_packet :
1073741824 VS (empty)
slow_query_log_file :
/var/lib/mysql/mysql2-slow.log VS /var/lib/mysql/mysql1-slow.log
system_time_zone :
CET VS CEST
timestamp :
1352219171 VS 1352219229
version :
5.1.66-0ubuntu0.10.04.1 VS 5.1.62-0ubuntu0.10.04.1
Run Code Online (Sandbox Code Playgroud)
顺便提一下,实例A是我们的测试环境,实例B是我们的生产环境
编辑:(@Rick James 推荐)
以下变量在两种环境中严格相同
SHOW VARIABLES LIKE '%buffer%'
bulk_insert_buffer_size 8388608
innodb_buffer_pool_size 8388608 …Run Code Online (Sandbox Code Playgroud) 问题目前影响 C#/.NET、基于 ADO.NET 和 SQL Server 2008 R2 的 DB 访问,但我认为它也适用于其他数据库。
我注意到系统的一些旧模块具有非最佳 SQL 查询,使用多个串联的值字符串而不是参数占位符。他们对表进行轮询,例如每 10 秒一次,以获取在过去几分钟内添加的项目,从而在每次执行时生成新的查询计划。
它们的性能还不错,没有 SQL 注入风险(没有 Web/用户表单),它们很旧,将它们的查询更改为正确的参数化需要做很多工作。我建议做这个改变,但有争论说这会浪费时间,其他事情更重要。
编辑:数据库应该使用大部分参数化查询(所有较新的模块都使用)运行,所以我想避免“优化临时”选项。部分参数化查询无论如何都会创建一个计划。在临时优化模式下运行时是否有缺点,主要是参数化查询?
对我来说,这些旧模块似乎占用了数据库资源的很大一部分,尽管它们很少。随着时间的推移,即使是这种类型的单个模块也会创建数千个查询计划,而所有较新的模块加在一起则更少。
更改这些是否重要,还是我可以将它们保留在它们的状态,仅在当前/未来模块中使用优化/参数化查询?
SQL 是这样的:
select ItemId, ItemName from Items
where ItemType=3 and ItemCreator=1234
and ItemDate >= '2013-11-23 12:30:00'
Run Code Online (Sandbox Code Playgroud)
其中值会有所不同,日期是几分钟之前。在少数情况下,日期已更改为“@startDate”之类的参数,以避免出现格式问题,但 ItemType 和 ItemCreator 值仍然是串联字符串。
在使用 DMV 或 Activity Monitor(最近昂贵的查询 - 计划计数列)监视查询计划时,我注意到其中一些查询在缓存中有 8000 多个等效的查询计划:
select count(*), query_plan_hash
from sys.dm_exec_query_stats
group by query_plan_hash
order by count(*) desc
Run Code Online (Sandbox Code Playgroud)
然后使用 sys.dm_exec_query_plan 上的 CROSS APPLY 选择计划 XML,并通过查询计划哈希选择计划句柄。
编辑/临时结论: 似乎最好让非常旧的应用程序保持原样,即使在创建大量临时查询时也是如此。我最担心的是,大量的一次性临时查询会导致好的、多用途的参数化和准备好的查询计划从缓存中被驱逐。这不会发生,因为当清理完成时,临时计划首先被驱逐,其他计划根据复杂性、使用次数等因素进行评级。因此,无论有多少使用率,参数化查询都可能被保留临时或部分参数化的计划大量涌入。临时优化减少了计划大小(实际上,第一次使用时没有存储真正的计划),但可能会保留更多计划,使用类似的内存(这是正确的吗?)。即使是部分参数化的 SQL(避免本地格式问题的 DateTime 参数)如果不再使用,也会很快被驱逐,即使使用 sp_executesql 发送,这会强制参数化和计划缓存。拥有大量(5000 …
我的 SQL Server 2008 R2 实例有问题。上周的表现突然崩溃了。所有插入都非常非常缓慢。它需要比以前长4-5倍。在硬件上我们没有发现任何缺陷。一个月前我们遇到了同样的问题,但一周后问题消失得很快。
我不是这些方面的专家,但我注意到实例上所有数据库的性能都很差。CPU 和磁盘未达到极限,因此应该不是硬件性能问题。
我将使用此查询查看缓存页数:
select
count(*)as cached_pages_count,
obj.name as objectname,
ind.name as indexname,
obj.index_id as indexid
from sys.dm_os_buffer_descriptors as bd
inner join
(
select object_id as objectid,
object_name(object_id) as name,
index_id,allocation_unit_id
from sys.allocation_units as au
inner join sys.partitions as p
on au.container_id = p.hobt_id
and (au.type = 1 or au.type = 3)
union all
select object_id as objectid,
object_name(object_id) as name,
index_id,allocation_unit_id
from sys.allocation_units as au
inner join sys.partitions as p
on au.container_id = p.partition_id …Run Code Online (Sandbox Code Playgroud) 我们遇到了 SQL Server 突然删除 proc 缓存的问题。
我在 2 分钟内将 4GB 降为 0。在过去的两周里,这种情况大约每天发生一次。
它确实发生在随机时间并且与过程不一致。
有没有人见过这个?
据我所知,只有在DBCC FREEPROCCACHE执行或重新启动 SQL 时才会擦除缓存。
版本:Microsoft SQL Server 2005 - 9.00.4226.00 (X64) 2009 年 5 月 26 日 14:58:11 版权所有 (c) 1988-2005 Microsoft Corporation Enterprise Edition(64 位),Windows NT 5.2(内部版本 3790:Service Pack 2)
32GB RAM
Run Code Online (Sandbox Code Playgroud)
非常感谢任何帮助。
我们使用 Idera SQL 诊断管理器。
结果:
DateTime Proc Cache Size MB
23/12/2015 19:19:00 4,165.63
23/12/2015 19:25:00 4,165.71
23/12/2015 19:32:00 4,178.93
23/12/2015 19:38:00 4,175.44
23/12/2015 19:44:00 4,176.87
23/12/2015 19:50:00 4,179.80
23/12/2015 19:57:00 …Run Code Online (Sandbox Code Playgroud) 我们对我们的 PHP/MySQL 站点感到烦恼,因为它似乎从数据库缓存数据,而我们的 PHP 页面显示过时的记录。事实上,有些页面链接到已从数据库中完全删除的 URL,但它们不显示更新的记录,甚至不显示丢失的数据。
如果我们有耐心等待几个(未定义)小时,数据最终会显示出来。我已经通过 PHP 在所有页面上添加了常规的无缓存标头,但它似乎不会影响 MySQL 输出。
网站的 PHP 部分可以立即更新,并立即显示 HTML 等更改。有没有办法强制 MySQL 只从其查询中提取新数据?我认为这就是它的工作方式!
谢谢,克里斯
PS这是我用来尝试强制无缓存情况的php代码:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // Always modified
header("Cache-Control: private, no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
Run Code Online (Sandbox Code Playgroud) 我有一个总数据大小为 115GB 的 Postgres 数据库。服务器有~60GB 的内存。索引缓存命中率保持在 99% 以上,但表缓存命中率已降至约 97%。
我试图确定是否有我们正在制作的特定查询或访问模式导致下降。如果是这样,我们也许能够优化应用程序。
我使用以下查询来识别命中率低的表...
SELECT relname,
CASE (sum(heap_blks_hit) + sum(heap_blks_read))
WHEN 0 THEN 1
ELSE sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read))
END as hitrate,
pg_size_pretty(sum(heap_blks_hit) + sum(heap_blks_read)) AS total_read,
pg_size_pretty(sum(heap_blks_read)) AS total_miss
FROM pg_statio_user_tables
GROUP BY relname
ORDER BY hitrate
Run Code Online (Sandbox Code Playgroud)
我不知道从这里去哪里。有没有办法跟踪某些查询是否通常会为我知道的表产生未命中数?
您可以按照此处所述计算缓存未命中。
但是,我对如何最小化 PostgreSQL 9.4.3 在 x86_64-unknown-linux-gnu 上的现象很感兴趣,它由 gcc (Debian 4.9.2-10) 4.9.2, 64-bit 编译。我有一些基于哈希表的算法,它们通过随机访问导致很多缓存未命中。我对如何最大限度地减少 PostgreSQL 中的缓存未命中感兴趣。
如何通过设计最大限度地减少 PostgreSQL 中的缓存未命中?
postgresql performance cache configuration postgresql-9.4 postgresql-performance
我们有一个InventoryActivity表,用于保存项目数量的交易变化:
CREATE TABLE dbo.InventoryActivity(
InventoryActivity_uid int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Organization_uid int NOT NULL,
MasterInventory_uid int NOT NULL,
AdjustmentType_cd varchar(20) NULL,
AdjustmentReason_cd varchar(20) NULL,
Quantity int NULL
)
Run Code Online (Sandbox Code Playgroud)
我们想要一个InventorySummary应该聚合到每个的当前数量。汇总计数应该始终可以从交易记录的总和中推导出来,但是我们有几种不同的方法来计算汇总计数:
哪些性能考虑因素应该使天平有利于特定策略?
存在哪些最佳实践? *(我知道最佳实践接近于讨论,但我想知道哪些考虑会有助于做出决定)
存储过程
最简单的选择是每次都执行新鲜的 SUM 操作。但不涉及缓存,随着时间的推移可能会导致性能问题。
CREATE PROCEDURE dbo.GetInventorySummary
AS
SELECT Organization_uid,
MasterInventory_uid,
SUM(Quantity) AS Quantity
FROM dbo.InventoryActivity
GROUP BY Organization_uid, MasterInventory_uid
Run Code Online (Sandbox Code Playgroud)单独的表
我们可以创建一个表来存储当前数量。好的一面是获取这些数据是微不足道的。缺点是我们每次写入 InventoryActivity 表时都必须手动维护它并保持记录同步。
CREATE TABLE dbo.InventorySummary(
Organization_uid int NOT NULL,
MasterInventory_uid int NOT NULL,
Quantity int NOT NULL, …Run Code Online (Sandbox Code Playgroud)我们每天都在经历大量的查询缓存修剪,目前为 80851746。即使在 50 多个并发连接的合理负载下,MySQL 也确实很挣扎。
主机是具有配置为 RAID 5、24 核和 128GB RAM 的 SSD 的物理服务器。它是一个专用的 MySQL 5.6 服务器,可供各种 PHP 客户端访问。
实例由3个数据库组成,总大小为1TB,所有表都是InnoDB并经过压缩。
我在下面包含了尽可能多的信息,任何建议将不胜感激。如果需要,我可以提供更多信息。谢谢。
# lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
# uname -a
Linux xxxxxxxxxx 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
# free -m
total used free shared buffers cached
Mem: 128915 128335 580 0 396 78764
-/+ buffers/cache: 49174 79740
Swap: 30517 192 30325
Run Code Online (Sandbox Code Playgroud)
cache ×10
mysql ×4
performance ×3
postgresql ×2
sql-server ×2
aggregate ×1
insert ×1
mysql-5.6 ×1
parameter ×1