MySQL - Выполнение интенсивных запросов на реальном сервере - PullRequest
0 голосов
/ 25 мая 2011

У меня есть некоторые проблемы, связанные с обновлением и вставкой миллионов строк в базу данных MySQL.Мне нужно отметить 50 миллионов строк в таблице A, вставить некоторые данные из отмеченных 50 миллионов строк в таблицу B, а затем снова обновить те же 50 миллионов строк в таблице A.В таблице A содержится около 130 миллионов строк, а в таблице B - 80 миллионов.

Это должно происходить на работающем сервере без запрета доступа к другим запросам с веб-сайта.Проблема заключается в том, что во время выполнения этой хранимой процедуры другие запросы с веб-сайта блокируются, а время ожидания HTTP-запроса истекает.

Вот суть SP, немного упрощенная для иллюстрации:

Ответы [ 2 ]

0 голосов
/ 26 мая 2011

А как насчет этого?Он в основном вызывает исходную хранимую процедуру в цикле, пока не будет достигнута общая необходимая сумма, и имеет период ожидания между вызовами (например, 2 секунды), чтобы позволить другим запросам обрабатываться.

increment - это суммаделать за один раз (используя 10 000 в этом случае)totalLimit - общая сумма для обработкиsleepSec - это время отдыха между вызовами

BEGIN
SET @x = 0;
REPEAT
    SELECT SLEEP(sleepSec);
    SET @x = @x + increment;
    CALL OriginalProcedure( increment );

    UNTIL @x >= totalLimit
END REPEAT;
END$$

Очевидно, что он может использовать небольшую математику, чтобы убедиться, что приращение не превысит общий лимит, если оно не делится равномерно, но оно выглядитна работу (под работой я имею в виду, что другие запросы по-прежнему обрабатываются из веб-запросов), и, кажется, в целом также быстрее.

Любое понимание здесь?Это хорошая идея?Плохая идея?

0 голосов
/ 25 мая 2011

Обработка 50M строк три раза будет медленной независимо от того, что вы делаете.

Убедитесь, что ваши обновления влияют на непересекающиеся множества меньшего размера. И выполняйте каждый из них один за другим, а не каждый из них в рамках одной транзакции.

Если вы уже делаете это, а MySQL работает неправильно, попробуйте выполнить небольшую настройку вашего кода:

create a temporary table

begin

insert into tmp_table
select your stuff
limit ?
for update

do your update on A using tmp_table

commit

begin
do your insert on B using tmp_table
do your update on A using tmp_table
commit

это должно держать замки в течение минимального времени.

...