-4

私はこのテーブルを持っています:

ID         ITEM
-----------------
0001        345
0001        345
0001        120
0002        567
0002        034
0002        567
0003        567
0004        533
0004        008
......

そして、この結果を得るために:

ID  ITEM    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
...

CNT は、個別の ID ごとに各アイテムが出現する回数です。

このクエリを実行します。

select driver.id, driver.item, coalesce(count(t1.id), 0)
from (select id.id, item.item
      from (select distinct id from Table1) id cross join
           (select distinct item from Table1) item
     ) driver left outer join
     Table1 t1
     on driver.id = t1.id and driver.item = t1.item
group by driver.id, driver.item;

このクエリは永遠にかかり、1 日経ってもまだ終了していません。これは EXPLAIN の結果です。

説明

idx_id と idx_code は、ID と ITEM のインデックスです。

クエリを改善して、より高速に実行し、うまくいけば終了できるようにするためのヒントを教えてください。ありがとう

4

1 に答える 1

3

私の提案は次のとおりです。中間ステップ用の一時テーブルを作成し、それらにインデックスを付けてから、それらを使用して最終結果を取得します。

具体的には:

-- The deduplicated item list
drop table if exists temp_items;
create temporary table temp_items
    select distinct item from Table1;
alter table temp_items
    add primary key (item);

-- The deduplicated id list
drop table if exists temp_ids;
create temporary table temp_ids
    select distinct id from Table1;
alter table temp_ids
    add primary key (id);

-- The cross join
drop table if exist temp_ids_items
create temporary table temp_ids_items
    select id, item
    from temp_ids, temp_items;
-- Important: Index the cross join
alter table temp_ids_items
    add index idx_id(id),
    add index idx_item(item); -- Optionally: add unique index idx_dedup(id, item)

これで、この一時テーブルを使用して必要なものを取得できます。

select 
    a.id, a.item, coalesce(count(t1.id), 0)
from 
    temp_ids_items as a
    left join Table1 as t1 on (a.id = t1.id and a.item=t1.item)
group by
    a.id, a.item;

関数は必要ないと思いますcoalesce()(値をカウントnullすると、結果はゼロになります)が、それは単なる意見です。

注意: 一時テーブルは、それらを作成した接続にのみ表示され、接続が閉じられると削除されます。上記のすべてのプロセスをストアド プロシージャに入れると便利だと思います。

お役に立てれば

于 2013-08-04T17:45:54.877 に答える