快速选择但慢速插入选择

Posted

技术标签:

【中文标题】快速选择但慢速插入选择【英文标题】:Fast Select but slow Insert Select 【发布时间】:2019-11-24 23:03:05 【问题描述】:

我正在尝试

仅当另一个表 final_stock_etablissements(10M 记录)与“警报器”代码匹配时,才从表 final_stock_ul(4M 记录)中获取信息 将结果限制为 1000 在临时表中插入所有内容

以下代码非常慢(15 秒):

DROP TABLE IF EXISTS temp_results ; 

CREATE TEMPORARY TABLE IF NOT EXISTS temp_results (
    siren INT,
    denomination VARCHAR(255)

)  ENGINE=MYISAM DEFAULT CHARSET=utf8  ;


INSERT INTO temp_results (
    siren,
    denomination
)
SELECT 
    ul.siren,
    ul.denomination

FROM dw.final_stock_ul ul

WHERE 

     exists 
            (
                SELECT 1
                FROM dw.final_stock_etablissements s
                WHERE code_postal =  69001
                AND s.siren = ul.siren
            ) 

LIMIT 1000

但是“SELECT”部分本身非常快(0.078 秒):

SELECT 
    ul.siren,
    ul.denomination

FROM dw.final_stock_ul ul

WHERE 

     exists 
            (
                SELECT 1
                FROM dw.final_stock_etablissements s
                WHERE code_postal =  69001
                AND s.siren = ul.siren
            ) 

LIMIT 1000

INSERT 怎么会比 SELECT 慢这么多?

(只有 1000 条记录要插入)

编辑:在 INSERT 语句中添加了缺失的字段

【问题讨论】:

INSERT 提到一栏; SELECT 提到 2 列。请修复。 final_stock_etablissements 中可以有多个匹配的警报器吗? (我正在考虑使用JOIN 而不是EXISTS。) 你有INDEX(postal_code, siren)吗? @RickJames 是的,它们有很多可能的匹配项(“etablissement”是一个位置,“siren”是一个公司编号,因此它们可以是一个公司的多个位置)-是的,我添加了一个postal_code 和警报器上的复合索引,没有任何结果。仍然无法弄清楚为什么插入会这么慢 【参考方案1】:

我找不到性能缓慢的答案:/

然而,潜在的问题非常普遍,并且在网络上有记录:

仅在匹配另一个表格时列出项目

似乎“IF EXISTS”解决方案或“WHERE IN”解决方案在大型表上运行缓慢

最好的解决方案是使用 JOIN(快得多)。

但是,如果您在第二个表中有多个匹配项,它并不能完全解决问题,因为您将获得多次相同的行结果 (LEFT JOIN only first row)

我找到的解决方案是:

创建要加入的特定表只有一个可能的匹配用于公共索引和 where 条件 - 在我的例子中,我构建了一个包含两个索引列的表 final_stock_etablissements_derived:警报器和 code_postal(每个警笛 x 邮政编码 1 行) 在索引上进行内部连接(在我的例子中是警报器)并在最后应用 where 条件 两个索引都用了,整体速度很快

【讨论】:

【参考方案2】:

如果您指望复合索引的性能(在您的 CREATE TABLE 语句中不存在),请尝试使用 InnoDB 作为临时表的引擎,它可能会有所帮助(请参阅 Rick James 的回答:MyISAM vs InnoDB for quick inserts and a composite unique key )...

【讨论】:

以上是关于快速选择但慢速插入选择的主要内容,如果未能解决你的问题,请参考以下文章

图形化排序算法比较:快速排序插入排序选择排序冒泡排序

Java选择排序,插入排序,快速排序

直接插入排序 ,折半插入排序 ,简单选择排序, 希尔排序 ,冒泡排序 ,快速排序 ,堆排序 ,归并排序的图示以及代码,十分清楚

常见排序算法的实现(归并排序快速排序堆排序选择排序插入排序希尔排序)

排序算法(冒泡,选择,插入,快速)查找算法(二分,快速)

选择 冒泡 快速 插入排序