慢MySQL查询填满了我的磁盘空间

use*_*185 0 mysql database

这是我正在运行的查询(28小时过去了!):

drop table if exists temp_codes;
create temporary table temp_codes
    select distinct CODE from Table1;
alter table temp_codes
    add primary key (CODE);

drop table if exists temp_ids;
create temporary table temp_ids
    select distinct ID from Table1;
alter table temp_ids
    add primary key (ID);

drop table if exists temp_ids_codes;
create temporary table temp_ids_codes
    select ID, CODE
    from temp_ids, temp_codes;

alter table temp_ids_codes
    add index idx_id(ID),
    add index idx_code(CODE); 

insert into Table2(ID,CODE,cnt)
select 
    a.ID, a.CODE, coalesce(count(t1.ID), 0)
from 
    temp_ids_codes as a
    left join Table1 as t1 on (a.ID = t1.ID and a.CODE=t1.CODE)
group by
    a.ID, a.CODE;
Run Code Online (Sandbox Code Playgroud)

我的表是这个(表1):

ID         CODE
-----------------
0001        345
0001        345
0001        120
0002        567
0002        034
0002        567
0003        567
0004        533
0004        008
......
(millions of rows)
Run Code Online (Sandbox Code Playgroud)

我正在运行上面的查询,以获得这个(表2):

ID  CODE    CNT
1   008      0
1   034      0
1   120      1
1   345      2
1   533      0
1   567      0
2   008      0
2   034      1
...
Run Code Online (Sandbox Code Playgroud)

CNT是每个ID的每个代码的计数.如何以最佳方式实现这一点以提高性能而不使用磁盘空间?谢谢

Gor*_*off 5

您将数千个代码乘以数百万个ID,并想知道为什么要占用磁盘空间.您正在生成数十亿行.这将需要很长时间.

我可能会提出一些建议(如果您要重新启动流程或有资源并行运行).

首先,将中间结果保存在实际表中,可能在另一个数据库("myTmp")中,以便您可以监视进度.

其次,在最终查询中的连接之前进行聚合.实际上,因为您正在使用临时表,所以首先将它放在表中:

select t1.ID, t1.CODE, count(*) as cnt
from Table1 as t1 
group by t1.ID, t1.CODE;
Run Code Online (Sandbox Code Playgroud)

现在,您通过包含所有其他代码然后分组来将原始数据相乘.

然后从完整表左边连接到这一个.

另一种方法是在原始表上有一个索引并尝试这样做:

insert into Table2(ID,CODE,cnt)
select a.ID, a.CODE,
       (select count(*) from Table1 t1 where a.ID = t1.ID and a.CODE=t1.CODE) as cnt
from temp_ids_codes a
group by a.ID, a.CODE;
Run Code Online (Sandbox Code Playgroud)

这可能看起来有悖常理,但它会在table1上使用相关子查询的索引.我不喜欢用SQL玩这类游戏,但这可能会导致查询在我们的生命周期中完成.