我想弄清楚什么是"性能明智的";如果你在MySQL数据库中有数十万行,并且部分经常更新,那么这是最好的选择。
INSERT INTO…重复键更新
这是我目前的方法,我只是插入/更新整行,而不检查实际更改的内容。
SELECT FROM…ID = ?并让PHP检查是否有发现
这会是一个更好/更快的解决方案吗?因此触发INSERT语句,如果ID存在,则更新整行。
或者我是否应该进一步检查(在ID存在的情况下),并将发现的行与PHP中更新的行进行比较,然后只更新实际更改的值?
LOAD DATA Statement
到目前为止我从未使用过这个,并且需要熟悉它,但是也许将它与REPLACE参数一起使用将是另一种可能加快整个导入的方法。
从技术上讲,插入总是会更改已索引的行,从而导致引擎重新创建索引。但是如果你的更新改变了索引,它就是一个静音点,因为索引仍然会被重新创建。
这在这里的长度解释:https://stackoverflow.com/a/15412865/11005071
我认为你的第一种方法在效率和性能方面要好得多。使用简单、更短的代码比在几行代码上编写查询更有效。只要你达到了预期的目的。无论你是使用第二种方法还是第一种方法,都不应该成为你的主要动力。你真正的目标应该是可读性、可维护性和效率。
这样做:
CREATE TEMPORARY TABLE t ...;
LOAD DATA ... INTO t ...;
INSERT INTO real_table
SELECT ... FROM t
ON DUPLICATE KEY UPDATE ... ;
每一步都是快速有效的。upsert将根据需要更新现有行(基于唯一键)或添加新行。
注意,您有机会在数据到达real_table之前对其进行操作。允许您清理数据(如果需要)。(Load Data with Replace不提供太多清理的机会)
- "十万行";——没问题。
- "部分updated"——它是这样做的。
- "检查是否有发现"——包括在内。
我重复一遍:您必须有一个UNIQUE
键来让进程知道哪些行需要更新而不是插入。
一个粗略的性能经验法则:在批处理中执行某些操作(就像我的建议一样)比一次执行一行操作快10倍(就像使用Select +检查如果发现)。