【问题标题】:Is it specified that INSERT IGNORE... SELECT is performed in order?是否指定按顺序执行 INSERT IGNORE... SELECT?
【发布时间】:2020-10-26 15:15:11
【问题描述】:

MariaDB INSERT IGNORE... SELECT 语法在 https://mariadb.com/kb/en/insert/ 中定义。

我还依赖于假设在这种情况下每个INSERT 都将按照SELECT 子句结果集的顺序执行。

测试用例:

DROP TEMPORARY TABLE IF EXISTS index_and_color;
CREATE TEMPORARY TABLE index_and_color (`index` INT PRIMARY KEY, color TEXT);
INSERT IGNORE INTO index_and_color SELECT 5, "Red" UNION ALL SELECT 5, "Blue";
SELECT * FROM index_and_color;

直观地说,我看到SELECT 子句结果集中的“第一”行有(5, "Red"),然后“第二”行被忽略,包含与“蓝色”相同的键。

据我所知,这是未定义的行为,因为实现相同文档的另一台服务器可以以不同的顺序处理行。

我在这里的使用确实依赖于未定义的行为吗?

【问题讨论】:

标签: sql duplicates mariadb sql-order-by sql-insert


【解决方案1】:

什么是“未定义行为”是UNION ALL 查询返回的行的顺序。如果您想要稳定的结果,请使用ORDER BY 子句:

INSERT IGNORE INTO index_and_color (`index`, color)
SELECT 5 `index`, 'Red' color UNION ALL SELECT 5, 'Blue' ORDER BY color;

【讨论】:

  • 我知道结果集可以按颜色排序。但是在 INSERT 文档中没有任何地方说“将首先插入结果集的第一个结果”。
  • 这意味着实现完全可以接受“将插入结果集中的随机行,直到插入所有结果”
【解决方案2】:

SQL 语句 SELECT * FROM index_and_color 应该准确地为您提供您所要求的:给定表中的所有数据行。

如果您希望结果集以特定顺序交付,那么您需要添加一个ORDER BY 子句,否则它可能按索引排序,或者基于优化器期望最快生成数据的任何算法.

例如::

CREATE TABLE t1 (a int, b int, index(a));
INSERT INTO t1 VALUES (2,1),(1,2);

/* Here we get the order from last insert statement */
SELECT a,b FROM t1;
MariaDB [test]> select a,b from t1;
+------+------+
| a    | b    |
+------+------+
|    2 |    1 |
|    1 |    2 |
+------+------+

/* Here we get the another order since the optimizer will deliver results from index */
SELECT a FROM t1;
+------+
| a    |
+------+
|    1 |
|    2 |
+------+

【讨论】:

    猜你喜欢
    • 2019-11-12
    • 1970-01-01
    • 2013-10-05
    • 2011-08-25
    • 2022-09-27
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多