快速选择但慢速插入选择

时间:2019-07-16 08:42:50

标签: mysql database-performance

我正在尝试

  • 仅在另一个表中有与“警笛”代码匹配的表 final_stock_etablissements (1000万条记录)时,才从表 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

但是“选择”部分 本身非常快 (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语句中添加了缺少的字段

2 个答案:

答案 0 :(得分:0)

我找不到性能下降的答案:/

但是潜在的问题非常普遍,并记录在网上:

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

在大型表上,“ IF EXISTS”解决方案或“ WHERE IN”解决方案似乎很慢

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

但是,如果您在第二张表中有多个匹配项,那么它并不能完全解决问题,因为结果是同一行中的行数会多次(LEFT JOIN only first row

我找到的解决方案是:

  • 创建要联接的特定表,其中仅一个可能的匹配项用于公共索引和where条件-在我的情况下,我构建了一个由两个索引组成的表final_stock_etablissements_derived列:警报器和code_postal(每个警报器1行x代码邮政编码)
  • 对索引进行内部联接(在我的情况下为警笛),并在末尾应用where条件
  • 使用了两个索引,总体速度非常快

答案 1 :(得分:0)

如果您要依靠复合索引来提高性能(在CREATE TABLE语句中不存在),请尝试使用InnoDB作为临时表的引擎,这可能会有所帮助(请参见Rick James的回答:{{3 }})...