SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 26.02.2011 12:56:50

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Передача набора значений в ХП

В принципе я накидал вот такую ХП.


DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `workflow_set_result_full`(
    IN par_id_result TEXT
)
BEGIN  
    var_id_result  INT(10) UNSIGNED;    
    DECLARE done INTEGER DEFAULT 0;
    DECLARE tasks CURSOR FOR SELECT id_result  FROM results
        JOIN tasks USING (id_scheme)
            WHERE FIND_IN_SET(id_result, par_id_result);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN tasks;
    read_loop: LOOP
        FETCH tasks INTO var_id_result;
        IF done THEN
            LEAVE read_loop;
        END IF;
        -- Локальный код
    END LOOP;
    CLOSE tasks;            
END$$
DELIMITER ;

Но FIND_IN_SET вызывает full row scan от отличие от IN. Как быть? Динамический SQL тут не прокатывает потому что SELECT объявляет курсор.
Еще можно сделать временную таблицу и через неё передавать параметры, но мне кажется это громоздко и неуклюже.
Есть еще варианты?

Отредактированно NT Man (26.02.2011 13:04:20)

Неактивен

 

#2 26.02.2011 14:25:35

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Передача набора значений в ХП

Честно говоря, не понял, какой смысл во всей этой конструкции — процедура не
делает ничего в принципе: делает плохой SELECT во внутреннюю переменную
и тут же ее забывает. Я бы сказал, что идеальной оптимизацией является удаление
такой процедуры smile

А вообще, конечно, да — делайте временную табличку со списком id и объеди-
няйте запрос с ней. Передавать TEXT в процедуру — еще более громоздко и не-
уклюже.

Неактивен

 

#3 26.02.2011 15:27:45

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Re: Передача набора значений в ХП

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

Если делать через временную таблицу, то какой тип движка хранения данных для неё выбрать? Для всей базы используется XtraDB, а тут вот думается MEMORY наверно будет лучше? Или для CREATE TEMPORARY TABLE это не имеет значения? Насколько вообще операция создания и уничтожения таблицы затратна?

Есть еще 3 вариант, отказаться от передачи списка параметров, курсора и просто дергать ХП для каждой записи из сервера приложений.

Что будет быстрее?

Отредактированно NT Man (26.02.2011 16:27:25)

Неактивен

 

#4 26.02.2011 23:10:09

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Передача набора значений в ХП

Они будут MEMORY по умолчанию — они же хранятся в памяти smile Операция
создания объекта в памяти — не очень затратная (объект же в памяти). Я
думаю, что вполне сравнима с созданием TEXT для передачи в изначальном
варианте smile

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

Я бы всё-таки использовал временную табличку.

Неактивен

 

#5 27.02.2011 01:19:51

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Re: Передача набора значений в ХП

С временной табличкой засада. DROP TABLE и TRUNCATE TABLE неявно делают COMMIT и переводят MySQL а AUTO COMMIT режим, что есть очень не хорошо. Как от этого побочного эффекта избавиться пока даже не представляю.

Пока сделал так:


-- Создаем табличку если нет
CREATE TEMPORARY TABLE IF NOT EXISTS `workflow_processing` (id_result INT(10) UNSIGNED) DEFAULT CHARSET=utf8);
-- Чистим от возможным предыдущих значений
DELETE FROM `workflow_processing;
-- Передаем ID с грида
INSERT INTO `workflow_processing` VALUES (1), (2), (3), (4);
-- Запускаем вариант много строчной ХП
CALL workflow_set_result_multi('120', '48', 'test');
 


Минуса два:
- значения остаются висеть на неопределенное время в памяти во временной табличке
- если измениться структура временной таблички, то придется перестартовывать сервер для обновления

Отредактированно NT Man (27.02.2011 14:38:11)

Неактивен

 

#6 27.02.2011 23:07:00

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Передача набора значений в ХП

А в чем проблема? Создавайте таблицу перед тем, как начать транзакцию?

Неактивен

 

#7 27.02.2011 23:58:35

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Re: Передача набора значений в ХП

paulus написал:

А в чем проблема? Создавайте таблицу перед тем, как начать транзакцию?

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

[ядро]START TRANSACTION[/ядро]
[локально вызванная процедура 1]Что-то правит в базе[/локально вызванная процедура 1]
[локально вызванная процедура 2]
правильно по идее
DROP IF EXISTS TABLE ... ; CREATE TEMPORARY TABLE ...
Что-то правит в базе
DROP TABLE ...
[/локально вызванная процедура 2]
[ядро]нет ошибок, COMMIT, в противном случае ROLLBACK[/ядро]

Неактивен

 

#8 28.02.2011 00:48:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Передача набора значений в ХП

Насколько я вижу, это проблема архитектуры Вашего приложения (наличие ядра,
например, которое нельзя менять). Да, разные окружения накладывают свои огра-
ничения. Это стандартная проблема — если Вы не управляете всем, всё Вы сделать
не можете.

Но это я отвлекся. На самом деле, всё куда проще: я Вам поверил, что CREATE
TEMPORARY TABLE работает как DDL и завершает транзакцию, а это не так smile
Т.е. можно безопасно создать временную таблицу тогда, когда она нужна, и не
переживать по поводу наличия ядер и транзакций (проверил на 5.1.53).

Неактивен

 

#9 28.02.2011 00:53:18

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Передача набора значений в ХП

Блина, перечитал весь тред, это я невнимательный sad

Вы написали, что DROP TABLE бьет транзакции. Да, бьет. А вот
DROP TEMPORARY TABLE, которому тут самое место, не бьет.

Неактивен

 

#10 28.02.2011 06:12:27

NT Man
Участник
Зарегистрирован: 07.06.2008
Сообщений: 16

Re: Передача набора значений в ХП

paulus, вот теперь красота. Спасибо!

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson