2013-08-04 2 views
-4

У меня есть эта таблица:мне нужна помощь, чтобы переписать мой запрос в MySQL

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; 

Этот запрос принимает навсегда, и до сих пор не закончил после дня .. Это результат Объяснения:

Explain

idx_id и idx_code являются индексы для ID и ITEM

Может вы даете мне несколько советов о том, как улучшить мой запрос, чтобы он работал быстрее и, надеюсь, закончил? Спасибо

+1

Результат не совсем объясняет, чего вы хотите достичь. – ep0

+0

Возможный дубликат [Считать запрос слишком длинным - прошло более 24 часов] (http://stackoverflow.com/questions/17996652/count-query-is-taking-too-long-over-24-hours-have -passed) – Chococroc

+0

CNT - это вхождения каждого элемента для каждого отдельного идентификатора. – user2578185

ответ

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 значения, результат равен нулю), но это всего лишь мнение.

Помните: таблицы Temp видны только для соединения, которое их создает, и они устраняются при закрытии соединения. Я думаю, что может быть полезно поставить весь вышеописанный процесс в хранимую процедуру.

Надеюсь, это поможет

+0

Спасибо за то, что нашли время ответить на мой вопрос. Я собираюсь попробовать это – user2578185

Смежные вопросы