Производительность хранимой процедуры нормализации MySQL

Я написал хранимую процедуру в MySQL, чтобы принимать значения, находящиеся в настоящее время в таблице, и "нормализовать" их. Это означает, что для каждого значения, переданного хранимой процедуре, она проверяет, находится ли оно уже в таблице. Если это так, то он сохраняет идентификатор этой строки в переменной. Если значение отсутствует в таблице, оно сохраняет идентификатор вновь вставленного значения. Затем хранимая процедура берет идентификаторы и вставляет их в таблицу, которая эквивалентна исходной денормализованной таблице, но эта таблица полностью нормализована и состоит в основном из внешних ключей.

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

INSERT INTO TableA 
 (first_value) 
VALUES 
 (argument_from_sp) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);

SET @TableAId = LAST_INSERT_ID();

«НА ОБНОВЛЕНИИ ДУПЛИКАЦИОННОГО КЛЮЧА» — это что-то вроде взлома из-за того, что в дублирующем ключе я не хочу ничего обновлять, а просто возвращаю значение идентификатора строки. Однако, если вы пропустите этот шаг, функция LAST_INSERT_ID() вернет неправильное значение, когда вы попытаетесь запустить оператор "SET ...".

Кто-нибудь знает лучший способ сделать это в MySQL?


person srkiNZ84    schedule 13.06.2010    source источник


Ответы (2)


Я вернулся и создал функцию для обработки этого случая:

CREATE DEFINER=`root`@`%` FUNCTION `value_update`(inValue VARCHAR(255)) RETURNS int(11)
BEGIN
        DECLARE outId INT;
        SELECT valueId INTO outId FROM ValuesTable WHERE value = inValue;

        IF outId IS NULL THEN
                INSERT INTO ValuesTable (value) VALUES (inValue);
                SELECT LAST_INSERT_ID() INTO outId;
        END IF;

        RETURN outId;
END

Упомянутая выше хранимая процедура вызывает эти функции вместо выполнения самих инструкций INSERT. С точки зрения производительности вышеуказанная функция работает быстрее в моей настройке (с использованием типа таблицы ndb). Кроме того, после сравнительного анализа всех частей моего приложения я обнаружил, что проблемы с производительностью, которые это вызывало, были лишь незначительной частью общего узкого места производительности.

person srkiNZ84    schedule 17.06.2010

Если у вас уже есть уникальный идентификатор, нужен ли автоматически увеличивающийся первичный ключ?

person Brian Hooper    schedule 08.07.2010
comment
В противном случае уникальный идентификатор был бы полем VARCHAR. Я бы предпочел целочисленное поле из соображений производительности. - person srkiNZ84; 26.07.2010
comment
Уникальный идентификатор по-прежнему является полем varchar; все, что вы сделали, это добавили в таблицу еще один столбец и еще один уникальный индекс. Целочисленный уникальный идентификатор не имеет смысла, и лучшее, что можно о нем сказать, это то, что он не сильно замедляет работу. Сравнительный анализ всех частей вашего приложения был хорошей идеей, и это позволит вам сконцентрироваться на важных вещах. - person Brian Hooper; 26.07.2010