mysql - INSERT ... ON DUPLICATE UPDATE - 锁定等待超时

标签 mysql sql optimization insert-update

我正在为大型 InnoDB 表上的文件进行 INSERT .. ON DUPLICATE KEY UPDATE 苦苦挣扎。

我的values 表保存属于客户端的每个实体的详细信息。一个实体的特定键只能有一个值。因此,当发生变化时,我们也会更新相同的内容。该表如下所示:

CREATE TABLE `key_values` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `client_id` int(11) NOT NULL COMMENT 'customer/tenant id',
  `key_id` int(11) NOT NULL COMMENT 'reference to the keys',
  `entity_id` bigint(20) NOT NULL,
  `value` text,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `client_id` (`client_id`,`entity_id`,`key_id`),
  KEY `client_id_2` (`client_id`,`key_id`)
) ;

所有写入查询的形式如下:

INSERT INTO `key_values` 
  (client_id, key_id, entity_id,value)
values
  (23, 47, 147, 'myValue'), (...), (...)...
ON DUPLICATE KEY UPDATE value = values(value);
  • 该表目前约有 3.5 亿条记录,并且增长速度相当快。
  • 对表的写入通常可以通过实时集成进行 插入少于 10 行或从离线源插入 25K 行。
  • 对于给定客户端,一次只能运行一个批量操作。这是减少 insert
  • 之间的行锁
  • 锁定等待超时时间设置为 50 秒

目前,当离线事件有时(并非总是)发生时,我们会遇到锁定等待超时。如果不避免超时,可以进行哪些更改?

  • 目前无法更改设计(分片/分区/集群)。
  • REPLACE 是另一个候选者,但我不想在生产中向代码中的任何内容授予删除权限。
  • INSERT IGNORE 然后UPDATE 是一个不错的选择,但是它会带来很大的改进吗?

我还有什么其他选择?

预先感谢您的所有建议和回答。

最佳答案

关于锁等待超时,可以通过 mysql 配置设置 innodb_lock_wait_timeout 进行更改除了在 my.cnf 中更改之外,还可以动态修改它(无需重新启动 mysql)。

关于锁等待,mysql 需要考虑的一件事是默认的事务隔离级别,即 REPEATABLE READ。此设置的副作用是,对于您可能期望的读取,会发生更多的锁定(特别是如果您有 SQL Server 背景,其默认 tran iso 级别为 READ COMMITTED)。现在,如果您不需要 REPEATABLE READ,您可以在查询中使用 SET TRANSACTION ISOLATION LEVEL 语法更改 tran iso 级别,或者使用配置设置 transaction-isolation 更改整个服务器的 tran iso 级别。 。我建议使用 READ COMMITTED,并考虑应用程序中是否有其他地方甚至可以接受“脏”读取(在这种情况下,您可以使用 READ UNCOMMITTED。

关于mysql - INSERT ... ON DUPLICATE UPDATE - 锁定等待超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22389099/

相关文章:

c# - 来自 sql 表的 TreeView

python - 长方程或分解方程在 Python 中什么更快?

php - DB 不会从 php 脚本渲染

mysql - HDBC ODBC MySQL - 查询仅在编译时失败

mysql - Eloquent count distinct 返回错误的总数

sql - 强制 Oracle 在远程数据库站点上处理递归 CTE(可能使用 DRIVING_SITE 提示)

javascript - 我们可以将对象作为参数传递到类似sql的数组中,以防止使用promise-mysql模块在nodejs中进行sql注入(inject)吗

c++ - 直接使用只读变量的性能与存储在对象中然后使用它的性能不同吗?

performance - 如何针对动态间隔调度优化这些 ocaml 函数?

java - 无法在 Hibernate 5.1.0.Final 中配置 hibernate-ehcache-4.3.5.Final.jar 的二级缓存