2013-03-04 2 views
1

У меня есть таблица с около 50М строк и формат:MySQL INSERT INTO ... SELECT ... GROUP BY слишком медленно

CREATE TABLE `big_table` (
    `id` BIGINT NOT NULL, 
    `t1` DATETIME NOT NULL, 
    `a` BIGINT NOT NULL, 
    `type` VARCHAR(10) NOT NULL, 
    `b` BIGINT NOT NULL, 
    `is_c` BOOLEAN NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `a_b_index` (a,b) 
) ENGINE=InnoDB; 

Я тогда определить таблицу t2, без индексов:

Create table `t2` (
    `id` BIGINT NOT NULL, 
    `a` BIGINT NOT NULL, 
    `b` BIGINT NOT NULL, 
    `t1min` DATETIME NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Затем я заполняю t2, используя запрос от big_table (это добавит около 12M строк).

insert into opportunities 
    (id, a,b,t1min) 
    SELECT id,a,b,min(t1) 
    FROM big_table use index (a_b_index) 
    where type='SUBMIT' and is_c=1 
    GROUP BY a,b; 

Я считаю, что он принимает этот запрос около минуты, чтобы обработать 5000 отчетливое (a,b) в big_table.
Так как существует 12M различных (a,b) в big_table, тогда потребуется около 40 часов для запуска запрос по всем big_table.

Что происходит не так?

Если я просто делаю SELECT ..., тогда запрос делает 5000 строк примерно за 2 секунды. Если I SELECT ... INTO OUTFILE ..., тогда запрос по-прежнему занимает 60 секунд для 5000 строк.

EXPLAIN SELECT ... дает:

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra 
1,SIMPLE,stdnt_intctn_t,index,NULL,a_b_index,16,NULL,46214255,"Using where" 
+1

q1: сколько времени занимает только выбор? – Sebas

+1

q2: каков план объяснения выбранной части? – Sebas

+0

'EXPLAIN SELECT ...' дает – BvdS

ответ

1

Я обнаружил, что проблема заключалась в том, что GROUP_BY привел к слишком большому количеству случайных чтений big_table. Следующая стратегия позволяет одно последовательное прохождение через big_table. Во-первых, мы добавим ключ к t2:

Create table `t2` (
    `id` BIGINT NOT NULL, 
    `a` BIGINT NOT NULL, 
    `b` BIGINT NOT NULL, 
    `t1min` DATETIME NOT NULL, 
    PRIMARY KEY (a,b), 
    INDEX `id` (id) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Затем мы заполняем t2 с помощью:

insert into t2 
    (id, a,b,t1min) 
    SELECT id,a,b,t1 
    FROM big_table 
    where type='SUBMIT' and is_c=1 
ON DUPLICATE KEY UPDATE 
    t1min=if(t1<t1min,t1,t1min), 
    id=if(t1<t1min,big_table.id,t2.id); 

В результате скорость вверх на несколько порядков величины.

0

Группа по может быть частью проблемы. Вы используете индекс (a, b), но ваш, где он не используется. Я бы индекс по

(типа, is_c, а, б)

Кроме того, вы получаете «ID», но не уточняя, которые ... вы, вероятно, хотите сделать MIN (ID) для последовательного результата.

+0

Я попробовал индекс на '(type, is_c, a, b)', и потребовалось около часа для 5000 строк. Я предполагаю, что индекс больше не вписывается в пул буферов nnodb (4 ГБ на моей машине). – BvdS

+0

Идея min (id) была полезной. – BvdS

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

  • Нет связанных вопросов^_^