我有一个 Postgres 数据库,其中包含有关服务器集群的详细信息,例如服务器状态(“活动”、“待机”等)。活动服务器在任何时候都可能需要故障转移到备用服务器,我不在乎特别使用哪个备用服务器。
我想要一个数据库查询来更改备用服务器的状态 - 只有一个 - 并返回要使用的服务器 IP。选择可以是任意的:因为服务器的状态随着查询而改变,所以选择哪个备用数据库并不重要。
是否可以将我的查询限制为一次更新?
这是我到目前为止所拥有的:
UPDATE server_info SET status = 'active'
WHERE status = 'standby' [[LIMIT 1???]]
RETURNING server_ip;
Run Code Online (Sandbox Code Playgroud)
Postgres 不喜欢这样。我可以做些什么不同的事情?
我有一个名为 ips 的表,如下所示:
CREATE TABLE `ips` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`begin_ip_num` int(11) unsigned DEFAULT NULL,
`end_ip_num` int(11) unsigned DEFAULT NULL,
`iso` varchar(3) DEFAULT NULL,
`country` varchar(150) DEFAULT NULL
) ENGINE=InnoDB
Run Code Online (Sandbox Code Playgroud)
假设我countryid在国家/地区表中的此表上有一个字段,如下所示:
CREATE TABLE `country` (
`countryid` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`ordering` smallint(5) unsigned NOT NULL DEFAULT '0',
`iso` char(2) NOT NULL,
PRIMARY KEY (`countryid`)
) ENGINE=InnoDB
Run Code Online (Sandbox Code Playgroud)
ips 表中大约有 100,000 条记录。是否有以下情况的查询:
检查是否ips.iso等于country.iso …
在 Ubuntu 12.04 上使用 PG 9.1。
目前,我们在数据库上运行大量 UPDATE 语句最多需要 24 小时,它们的形式如下:
UPDATE table
SET field1 = constant1, field2 = constant2, ...
WHERE id = constid
Run Code Online (Sandbox Code Playgroud)
(我们只是覆盖由 ID 标识的对象的字段。)这些值来自外部数据源(尚未在数据库中的表中)。
每个表都有几个索引,没有外键约束。直到最后都没有提交。
导入pg_dump整个数据库的一个需要 2 小时。这似乎是我们应该合理定位的基线。
除了生成以某种方式重建数据集以供 PostgreSQL 重新导入的自定义程序之外,我们是否可以做些什么来使批量 UPDATE 性能更接近导入的性能?(这是一个我们认为日志结构合并树处理得很好的领域,但我们想知道是否可以在 PostgreSQL 中做任何事情。)
一些想法:
基本上有很多事情要尝试,但我们不确定什么是最有效的,或者我们是否忽略了其他事情。我们将在接下来的几天里进行实验,但我们想我们也会在这里问。
我确实在表上有并发负载,但它是只读的。
大多数表使用 MySQL 5.6 和 InnoDB 存储引擎。InnoDB 缓冲池大小为 15 GB,Innodb DB + 索引大约为 10 GB。服务器有 32GB RAM 并运行 Cent OS 7 x64。
我有一张包含大约 1000 万条记录的大表。
我每 24 小时从远程服务器获取更新的转储文件。该文件为 csv 格式。我无法控制那种格式。该文件约为 750 MB。我尝试将数据逐行插入 MyISAM 表,花了 35 分钟。
我只需要从文件中的每行 10-12 中取出 3 个值并在数据库中更新它。
实现这样的目标的最佳方法是什么?
我需要每天都这样做。
目前 Flow 是这样的:
以上操作大约需要30-40 分钟才能完成,在执行此操作时,还有其他更新正在进行中,这给了我
超过锁等待超时;尝试重新启动事务
使用LOAD DATA LOCAL INFILE. 在 MyISAM 中,38.93 sec在 InnoDB 中需要 7 分 5.21 秒。然后我做了:
UPDATE table1 t1, table2 t2
SET …Run Code Online (Sandbox Code Playgroud) 我有一个与性能相关的问题。假设我有一个名为 Michael 的用户。进行以下查询:
UPDATE users
SET first_name = 'Michael'
WHERE users.id = 123
Run Code Online (Sandbox Code Playgroud)
查询是否会实际执行更新,即使它被更新为相同的值?如果是这样,我该如何防止它发生?
如果我有一个UPDATE实际上没有改变任何数据的语句(因为数据已经处于更新状态)。在WHERE子句中进行检查以防止更新是否有任何性能优势?
例如,以下 UPDATE 1 和 UPDATE 2 之间的执行速度是否有任何差异:
CREATE TABLE MyTable (ID int PRIMARY KEY, Value int);
INSERT INTO MyTable (ID, Value)
VALUES
(1, 1),
(2, 2),
(3, 3);
-- UPDATE 1
UPDATE MyTable
SET
Value = 2
WHERE
ID = 2
AND Value <> 2;
SELECT @@ROWCOUNT;
-- UPDATE 2
UPDATE MyTable
SET
Value = 2
WHERE
ID = 2;
SELECT @@ROWCOUNT;
DROP TABLE MyTable;
Run Code Online (Sandbox Code Playgroud)
我问的原因是我需要行数来包含未更改的行,所以我知道如果 ID 不存在是否进行插入。因此,我使用了 UPDATE 2 表单。如果使用 UPDATE 1 表单有性能优势,是否有可能以某种方式获得我需要的行数?
情况 我有一个 postgresql 9.2 数据库,它一直都在大量更新。因此系统受 I/O 限制,我目前正在考虑进行另一次升级,我只需要一些关于从哪里开始改进的指导。
以下是过去 3 个月情况的图片:

如您所见,更新操作占磁盘利用率的大部分。这是另一张更详细的 3 小时窗口中情况的图:

如您所见,峰值写入速率约为 20MB/s
软件
服务器运行 ubuntu 12.04 和 postgresql 9.2。更新类型通常在由 ID 标识的单个行上进行小更新。例如UPDATE cars SET price=some_price, updated_at = some_time_stamp WHERE id = some_id。我已经尽可能多地删除和优化了索引,并且服务器配置(linux 内核和 postgres conf)也非常优化。
硬件 硬件是一个专用服务器,带有 32GB ECC ram、RAID 10 阵列中的 4 个 600GB 15.000 rpm SAS 磁盘,由带有 BBU 的 LSI RAID 控制器和英特尔至强 E3-1245 四核处理器控制。
问题
- - - - - - - - - - - - - - - 更新 …
我想知道是否可以更新 MySQL 中的触发器定义。例如,我有一个触发器 T,我想向它添加一些新功能。
我的假设是我需要删除并重新创建它。
对于此类场景,数据库管理的最佳实践是什么?
我的数据库中有 2 个表。
表格1
-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
表#2
-----------------------------------------
| gender | address | phone | birthdate |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)
在表#1的列地址和PHONE2是空的和列性别和生日的值是相同的表#2。
当每行的性别和出生日期相同时,如何从表 #2 中读取数据并使用表 #2 address和phone列中的值更新表 #1 中的address和phone2?
例如:这是表 #1 中的一些数据
-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address …Run Code Online (Sandbox Code Playgroud) 在更新一行时,许多 ORM 工具发出一个 UPDATE 语句,设置与该特定实体关联的每一列。
优点是您可以轻松地批量更新语句,因为UPDATE无论您更改什么实体属性,语句都是相同的。此外,您甚至还可以使用服务器端和客户端语句缓存。
所以,如果我加载一个实体并且只设置一个属性:
Post post = entityManager.find(Post.class, 1L);
post.setScore(12);
Run Code Online (Sandbox Code Playgroud)
所有列都将被更改:
UPDATE post
SET score = 12,
title = 'High-Performance Java Persistence'
WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
现在,假设我们也有一个关于该title属性的索引,数据库难道不应该意识到该值无论如何都没有改变吗?
在这篇文章中,Markus Winand 说:
所有列的更新显示了我们在前几节中已经观察到的相同模式:响应时间随着索引的增加而增加。
我想知道为什么会有这种开销,因为数据库将关联的数据页从磁盘加载到内存中,因此它可以确定是否需要更改列值。
即使对于索引,它也不会重新平衡任何内容,因为对于未更改的列,索引值不会更改,但它们已包含在 UPDATE 中。
是不是和冗余不变列关联的B+树索引也需要导航,数据库才意识到叶子值还是一样的?
当然,一些 ORM 工具允许您只更新更改的属性:
UPDATE post
SET score = 12,
WHERE id = 1
Run Code Online (Sandbox Code Playgroud)
但是,当不同行的不同属性更改时,这种类型的 UPDATE 可能并不总是从批量更新或语句缓存中受益。
update ×10
performance ×6
postgresql ×4
mysql ×3
sql-server ×2
bulk ×1
concurrency ×1
hardware ×1
index ×1
join ×1
myisam ×1
mysql-5.6 ×1
orm ×1
queue ×1
t-sql ×1
trigger ×1