php - MySQL Performance INSERT 或(部分)UPDATE 如果存在,什么是最好的?
问题描述
如果您在 MySQL 数据库中有数十万行并且部分频繁更新,我试图弄清楚什么是“性能明智”的最佳选择。
插入 ... 在重复密钥更新时
这是我目前的方法,我只是插入/更新整行而不检查实际更改的内容。
从...选择 ID=?让 PHP 检查是否找到了东西
这会是一个更好/更快的解决方案吗?所以我触发了一个 INSERT 语句,如果 ID 存在,我更新整行。
或者也许我应该进一步检查(如果 ID 存在)并将找到的行与 PHP 中的更新行进行比较,然后只更新实际更改的值?
加载数据语句
到目前为止,我从未使用过它,需要熟悉它,但也许将它与 REPLACE 参数一起使用将是另一种可能加速整个导入的方法。
解决方案
这样做:
CREATE TEMPORARY TABLE t ...;
LOAD DATA ... INTO t ...;
INSERT INTO real_table
SELECT ... FROM t
ON DUPLICATE KEY UPDATE ... ;
每一步都快速有效。upsert 将根据需要更新现有行(基于唯一键)或添加新行。
请注意,您有机会在数据到达 real_table 之前对其进行操作。允许您清理数据(如果需要)。(使用替换加载数据并没有提供太多清理的机会。)
- “十万行”——没问题。
- “部分更新”——它做到了。
- “检查是否发现了什么”——包括在内。
我再说一遍:你必须有一个UNIQUE
键来让进程知道哪些行需要更新而不是插入。
粗略的性能经验法则:批量做某事(如我的建议)是一次做某事的 10 倍(如您的 Select + check if found)。
推荐阅读
- ansible - 替代的 ansible 语法
- javascript - 如何修复错误:JavaScript 错误:TypeError: undefined is not an object (evalating 'this.context.clearRect') 在第 24 行
- python - SageMath:在 dochtml 阶段运行`make`以 ImportError 结束
- c++ - 如何在保留角点的同时简化折线?
- mysql - 使用 In 命令和 group by 子句
- laravel - 格式化日期并验证
- flutter - 颤振嵌套的手势检测器不起作用
- c++ - 将逻辑写入语法代码的问题
- angularjs - AngularJS 1.4.9部署dropzone的一些问题
- timer - 如何在颤动中从零开始计数器计时器?