Mysql 连接三个表

Mysql 连接三个表,mysql,sql,join,insert,Mysql,Sql,Join,Insert,我有一个数据库“stats19”,里面有2005年至2013年英国事故的所有数据 现在我必须创建一个数据仓库(星型) 这是我试图连接到一个表中的表,省略了一些不重要的其他变量 stats19.1(2020000行) stats19.typeperson(2020000行) stats19.1事故(1494275排) 最终的表必须有这个变量 dw.casualtytemporation(应具有202.000行) 我一直在尝试执行此命令以插入 INSERT INTO CasualtyTemp

我有一个数据库“stats19”,里面有2005年至2013年英国事故的所有数据

现在我必须创建一个数据仓库(星型)

这是我试图连接到一个表中的表,省略了一些不重要的其他变量

stats19.1(2020000行)

stats19.typeperson(2020000行)

stats19.1事故(1494275排)

最终的表必须有这个变量

dw.casualtytemporation(应具有202.000行)

我一直在尝试执行此命令以插入

INSERT INTO CasualtyTemp
    (SELECT c.AccidentIndex,c.VehicleReference,c.CasualtyReference_id,
    c.CasualtyClass,t.CasualtyType_id,a.AccidentDate,a.AccidentTime,
    c.CasualtySex, c.CasualtyAgeBand
    FROM (stats19.Casualty as c 
        INNER JOIN stats19.typeperson as t 
            ON c.CasualtyReference_id = t.cf_CasualtyReference_id
        INNER JOIN stats19.accident as a
            ON a.AccidentIndex = c.AccidentIndex))
);
当MYSQL命令行或Workbench都因错误(断开连接)或插入时间过长而导致插入失败时,就会出现问题


最终的表dw.casualtytemporal应该有2020000行,因为这是原始表的行数。

因为您正在执行没有“where”的完整表联接,所以我认为搜索复杂度是
n1*log(n2)*log(n3)
其中ni是每个表的行号(如果在内部联接字段上使用索引)

我认为您的SQL语句是正确的,mysql优化器将进一步优化SQL,因此我认为无需对SQL进行优化。但是我想你可以调整MYSQL部分,我列出了一些可能很重要的东西

  • 这两个存储引擎应该是相同的,这可以确保表是在引擎级别进行连接的,否则它们将在服务器级别进行连接,这很慢

  • 如果您使用Innodb,也许您可以调整与InnoODB相关的重要参数,如“Innodb\u buffer\u pool\u size”,因为足够的空间将使Innodb在内存中进行哈希索引

  • 如果使用Myisam引擎,也许可以调整Myisam索引大小,以确保索引可以加载到内存中

  • 此外,由于您将生成派生表,因此tmp_表的大小将非常重要,如果tmp_表的大小很小,myisam表将用作tmp表。还要注意的是,由于双写日志机制,innodb的写速度非常慢,当您使用insert…select时,情况会更糟,因为并发insert是禁用的

  • 其他因素,如字段中是否有NULL,字段是否大量重复,如果是,则可以使用比VARCHAR更快的ENUM。另外请注意,CHAR比VARCHAR快约20%,如果磁盘空间不是问题,并且字符串很短,您可以试试


  • 如果以上所有方法都不能解决您的问题,或者您没有一台大型计算机,因为您只需要处理三个表,您可以用c/c++编写一些代码,这是最有效的方法。

    那么,您的问题是如何使查询更快?或者如何增加客户端上的超时时间,使其在该操作完成之前不会断开连接?您是否检查了
    select
    query?如果您确定数据,请使用
    限制10000
    例如。然后继续执行
    限制1000010000
    ,依此类推。我的问题是我做错了吗?或者,我是否做得对,应该尝试一些相关的方法来增加超时或优化?选择不适用于限制1000或限制10001000(偏移)。当支持联接以生成2020000行时,以及在destiny表中插入多达3000000行的偏移量2000000时,就会出现问题。另一种选择是使用日期范围,以便一次移动较少的数据。我假设您只需要移动历史数据一次。历史时间已经插入到由三个基表(concat(date,time),date,time)共享的维度中。
    CasualtyType_id int(11)
    fk_AccidentIndex    varchar(13)
    fk_VehicleReference int(11)
    fk_CasualtyReference_id int(11)
    ...
    
    AccidentIndex   varchar(13)
    AccidentDate    date
    AccidentTime    time
    ...
    
    AccidentIndex VARCHAR(255),
    VehicleReference INT,
    CasualtyReference INT,
    CasualtyClass INT,
    CasualtyType INT,
    AccidentDate DATE,
    AccidentTime TIME,
    CasualtySex VARCHAR(255),
    CasualtyAgeBand VARCHAR(255)
    
    INSERT INTO CasualtyTemp
        (SELECT c.AccidentIndex,c.VehicleReference,c.CasualtyReference_id,
        c.CasualtyClass,t.CasualtyType_id,a.AccidentDate,a.AccidentTime,
        c.CasualtySex, c.CasualtyAgeBand
        FROM (stats19.Casualty as c 
            INNER JOIN stats19.typeperson as t 
                ON c.CasualtyReference_id = t.cf_CasualtyReference_id
            INNER JOIN stats19.accident as a
                ON a.AccidentIndex = c.AccidentIndex))
    );