SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 01.04.2011 23:10:58

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Вопрос по курсорам

Добрый вечер, скажите если запрос объявленый для курсора DECLARE cur1 CURSOR FOR SELECT a,b FROM table WHERE c=1;возратит пустую строку, то курсор все равно создаться и начнется процесс по открытию курсора, чтение из него и.т.д.и.т.п? Или процедура завершится так и не успев начаться? Или нужно принудительно писать обработчик EXIT HANDLER FOR NOT FOUND?

Неактивен

 

#2 02.04.2011 19:08:14

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

Re: Вопрос по курсорам

Создастся, всё будет работать, как положено. Ошибку Вы получите на этапе
FETCH, разумеется.

Неактивен

 

#3 09.04.2013 14:35:50

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

Ребят, подскажите по такой ситуации.
Прогоняю курсор по всей таблице с почти 200 миллионов записей, у меня всё повисло на несколько минут, результата работы курсора я не увидел (результататы заносятся в другую таблицу), в процессах в статусе запроса было "Sending data", в итоге я процесс убил. Сделал лимит для курсора до 10 тысяч строк, он отработал пулей.

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


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 09.04.2013 16:09:21

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Вопрос по курсорам

Странно, курсор должен работать последовательно и не тратить времени на подготовку. Курсор по сути выполняет элементарную операцию поиска по ключу. Может быть все было в транзакции и она откатилась после того, как запрос был убит?

Неактивен

 

#5 09.04.2013 16:33:22

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

Таблицы myisam, транзакциями не пахнет, если я правильно понял вопрос. Собственно наличие записей во второй таблице я мониторю во время выполнения курсора.

Ставлю в запросе курсора WHERE `id`<=1000000, курсор отрабатывает за несколько секунд и вторая таблица заполняется значениями. Убрал WHERE, курсор запущен уже 3000 секунд, а во второй таблице нет ни одной записи. Вот решил подождать пару дней пока он завершит работу, может он все изменения вносит по факту закрытия курсора, хотя вроде не логично это.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#6 09.04.2013 16:37:06

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Вопрос по курсорам

Не логично, надо попробовать помониторить ситуацию как-то еще. id - индекс?

Неактивен

 

#7 09.04.2013 16:49:49

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

Естественно, PRIMARY smile С триггерами проще, все запросы попадают в лог, а вот с процедуркой не сложилось, кроме CALL в лог запросов ничего не попадает, трудно понять что происходит в конкретный момент времени.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#8 09.04.2013 17:03:02

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

Может что в самой процедуре не так, опыта работы с курсорами почти нет, хотя он мне в наследство достался)))

CREATE PROCEDURE calc_credits_activity()
BEGIN
  DECLARE done BOOLEAN DEFAULT FALSE;

  DECLARE rUserId INT DEFAULT NULL;
  DECLARE rAdded DATE DEFAULT NULL;
  DECLARE rCredits DECIMAL DEFAULT NULL;
  DECLARE rStatus VARCHAR(20) DEFAULT NULL;

  DECLARE rCursor CURSOR FOR SELECT `sn`.`user_id`, `sn`.`cost`, DATE(`s`.`added`), `sn`.`status` FROM `sms_numbers` `sn` JOIN `sms` `s` ON `s`.`id`=`sn`.`sms_id`;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=TRUE;

  TRUNCATE `users_credits_activity`;

  OPEN rCursor;

  WHILE done = FALSE DO
    FETCH rCursor INTO rUserId, rCredits, rAdded, rStatus;

    IF NOT done THEN
      IF rStatus = 'DELIVRD' THEN
        IF ISNULL(rUserId) THEN
          SET rUserId = 0;
        END IF;
        INSERT INTO `users_credits_activity`
          SET
            `user_id` = rUserId,
            `credits` = rCredits,
            `added` = rAdded
        ON DUPLICATE KEY UPDATE `credits` = `credits` + rCredits;
      END IF;
    END IF;

  END WHILE;

  CLOSE rCursor;

END
 


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#9 09.04.2013 17:08:20

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Вопрос по курсорам

Пробуйте вставлять что-то в отдельную таблицу после каждой команды. Тогда станет понятно на чем висит.  Скорее всего проблема из-за JOIN и курсор создает в начале временную таблицу с копией всех данных.
Откажитесь от курсоров.

Неактивен

 

#10 09.04.2013 17:08:21

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

Что интересно, прошло вот чуть более часа пока работал курсор и теперь таблица начала заполняться, а в PROCESSLIST отображаются запросы процедуры, это не может не радовать. Получается, что час с лишним всё же были какие-то подготовки, вот только не понятно какие и почему. Но в логах запросы процедуры так и не отображаются.

Вот словил такой запрос в процессах:

INSERT INTO `users_credits_activity`
         SET
           `user_id` =  NAME_CONST('rUserId',3339),
           `credits` =  NAME_CONST('rCredits',1),
           `added` =  NAME_CONST('rAdded',_binary'2010-09-30' COLLATE 'binary')
       ON DUPLICATE KEY UPDATE `credits` = `credits` +  NAME_CONST('rCredits',1)    

Это нормально, что происходят такие преобразования?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#11 09.04.2013 17:10:18

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Вопрос по курсорам

rgbeast написал:

Скорее всего проблема из-за JOIN и курсор создает в начале временную таблицу с копией всех данных.

Изначально запрос был без JOIN, поведение было такое же.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

Board footer

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