关于重复密钥更新 - 优先级

ON DUPLICATE KEY UPDATE - precedence

INSERT INTO {tableA} SELECT a,b,c FROM {tableB} ON DUPLICATE KEY UPDATE x=y

重复键的计算优先级是什么?我假设 MySQL 首先检查表 B 中的元组是否与表 A 中的 unique/primary 键冲突。如果 SELECT 不包含主键,或者如果不存在其他重复键,则评估每个后续的 UNIQUE INDEX "group" 并执行相同的检查。但是,如果您的 tableB 具有多组唯一的多列索引,会发生什么情况?他们是否按照 SHOW INDEXES FROM tableB 所述从上到下进行评估?

这是我的 SHOW INDEXES FROM <table>:

Table,Non_unique,Key_name,Seq_in_index,Column_name,Collation
daily_metrics,0,PRIMARY,1,id,A
daily_metrics,0,unique_lineItem_creative_y_m_d,1,line_item_id,A
daily_metrics,0,unique_lineItem_creative_y_m_d,2,creative_id,A
daily_metrics,0,unique_lineItem_creative_y_m_d,3,year,A
daily_metrics,0,unique_lineItem_creative_y_m_d,4,month,A
...

假设有额外的一组唯一索引类似于 unique_lineItem_creative_y_m_d

文档似乎没有说明这种行为。 https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

我还假设使用第一个匹配的唯一索引,如果存在匹配,则不会尝试匹配后续可以匹配的唯一索引。换句话说,使用第一个匹配的唯一索引,而不考虑尝试在所有索引中找到最佳匹配。

如果 tableB 中存在任何主键或唯一键,那是无关紧要的。 INSERT...ON DUPLICATE KEY UPDATE 唯一重要的是要插入的 table 的主键或唯一键 - 在您的示例中为 tableA

如果您插入到 tableA 的值已在 tableA 的任何主键或唯一键中找到,则会触发 IODKU 的 UPDATE 部分。

这是关于插入的值,而不是源的约束 table。

您也可以在不使用任何来源 table 的情况下触发 UPDATE -- 只需插入带有一组常量的 VALUES() 子句即可。

你是对的:一旦 MySQL 在任何 UNIQUE 索引中检测到重复项,它就会放弃 INSERT 并进行更新。

MySQL 评估唯一索引的顺序不会改变结果。对于某个唯一索引,没有 更好 匹配之类的东西。因为它们是唯一索引,所以显示为重复的列值的任何组合都足以完全指定要更新的行。

MySQL 的查询规划器希望选择评估成本最低的索引。但是,从形式上讲,它用于此目的的索引是不可预测的。这种不可预测性是SQL等声明性语言的属性。 MySQL 可以以任何可行的方式完成它的工作,而且它不必告诉你。程序员可能很难掌握,因为我们已经习惯了 过程 语言。