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

Написах съхранена процедура в MySQL, за да взема стойности в момента в таблица и да ги "нормализира". Това означава, че за всяка стойност, предадена на запомнената процедура, тя проверява дали стойността вече е в таблицата. Ако е така, тогава той съхранява идентификатора на този ред в променлива. Ако стойността не е в таблицата, тя съхранява идентификатора на нововъведената стойност. След това съхранената процедура взема идентификаторите и ги вмъква в таблица, която е еквивалентна на оригиналната денормализирана таблица, но тази таблица е напълно нормализирана и се състои главно от външни ключове.

Моят проблем с този дизайн е, че съхранената процедура отнема приблизително 10 ms, за да се върне, което е твърде дълго, когато се опитвате да работите с около 10 милиона записа. Подозрението ми е, че изпълнението е свързано с начина, по който правя вложките. т.е.

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

SET @TableAId = LAST_INSERT_ID();

„НА АКТУАЛИЗАЦИЯ НА ДУБЛИРАН КЛЮЧ“ е малко хак, поради факта, че на дублиран ключ не искам да актуализирам нищо, а по-скоро просто да върна стойността на 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