重复键更新-优先级

时间:2019-03-26 16:54:23

标签: mysql on-duplicate-key

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

如何评估重复键?我假设MySQL首先检查tableB中的元组是否存在与tableA中的唯一/主键冲突。如果SELECT不包含主键,或者不存在其他重复键,则将评估每个后续的UNIQUE INDEX“组”并执行相同的检查。但是,如果您的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

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

2 个答案:

答案 0 :(得分:2)

您是正确的:只要MySQL在任何UNIQUE索引中检测到重复项,它就会放弃INSERT并进行更新。

MySQL评估唯一索引的顺序不会改变结果。 更好的匹配对于另一个唯一索引来说是不存在的。因为它们是唯一索引,所以显示为重复项的列值的任何组合都足以完全指定要更新的行。

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

答案 1 :(得分:1)

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

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

这与要插入的值有关,而不是源表的约束。

您也可以不使用任何源表而触发UPDATE,只需插入带有一组常量的VALUES()子句即可。