2014-09-14 1 views
-1

У меня есть таблица с одной колонке (около 1 миллиона строк):приращение счетчика поле строки, если та же строка существует в другой таблице

Table A (InnoDB) 

ColA (no index, no primary key) 

У меня также есть таблица (3 миллиона строк):

Table B (InnoDB) 

ColA (PK INDEX) | count 

Таблица B является надмножеством таблицы A. Таблица B содержит каждую строку, в которой я нуждаюсь, в то время как таблица A содержит только некоторые строки. Я хочу увеличить поле count таблицы B на 1 для каждой строки, которая существует в таблице A. Проблема заключается в том, что таблица A довольно велика, поэтому я не могу использовать обычную команду UPDATE с предложением where, потому что предложение where будет иметь 1 миллионов условий. Я действительно ищу наиболее оптимизированный способ с точки зрения производительности, чтобы увеличить эти поля. Решение, которое я могу думать:

UPDATE TABLE_B set count = count + 1 where ColA IN (SELECT ColA FROM TABLE_A) 

Но для этого потребуется два полных индексных сканирований на обеих таблицах, поэтому я не уверен, что это самый быстрый способ сделать эту задачу.

+0

Почему нижний уровень? – user2924127

ответ

1

Обеспечение ColA индексируется в обеих таблицах, это будет работать:

UPDATE B set count = count + 1 
WHERE (
    SELECT 1 FROM A 
    WHERE A.ColA = B.ColA LIMIT 1 
) IS NOT NULL 
+1

Вы должны использовать 'exist', а не конструкцию. –

+0

вы ошибаетесь, это самый оптимальный способ, просто подумайте, что man 'exists' равен чему-то, чтобы проверить, удовлетворен ли требуемый оператор хотя бы один раз, поэтому я уже сделал свой подзапрос столь же оптимальным, что' exists' не может добавить более того, даже это даже дополнительный вызов функции –

+1

Это, кажется, самый быстрый способ. Считаете ли вы, что InnoDB - лучший движок для таблицы B, который используется только для обновлений (увеличивая одно поле) только одним пользователем за раз? – user2924127

2

Во-первых, добавить индекс таблицы A:

create index idx_tablea_cola on table_a(cola) 

Тогда фраза ваш запрос как:

update table_b b 
    set count = count + 1 
    where exists (select 1 from table_a a where a.colA = b.colA); 

Предполагается, что в tablea дубликатов нет. Или, по крайней мере, если есть, вы все равно хотите, чтобы счетчик увеличивался на 1.

С индексом это будет болезненная операция.

+0

как это подразумевается, что в таблице нет дубликатов в этой ситуации? и что это предполагает? –

+0

Использование объяснения, похоже, приводит к тому же результату, который впервые появился в @GeorgeGarchagudashvili – user2924127

2

Я нашел более быстрый способ. Кажется, что примерно на 30% -35% быстрее, чем другой ответ:

INSERT 
INTO TABLE_B 
SELECT colA, 1 FROM TABLE_A 
ON DUPLICATE KEY 
UPDATE count = count + 1 
+0

Есть ли записи в 'table_a', которые не находятся в' table_b'? –

+0

Нет, все записи в таблице A находятся в таблице B. Я понимаю, что это обычно не используется для этого случая, но он дает тот же результат и, кажется, намного быстрее. – user2924127

+0

Это довольно интересно. Первоначально я думал, что «этот ответ не отвечает на заданный вопрос». Но, без новых записей, это делает, и производительность лучше. –