Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Доброго всем времени суток.
31 июл 12, 17:27    [12942489]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Сорри, глюкнул браузер...
Таг вод.

Есть ХП, которая делает селект из ДБ.
Внутри этой процедуры, необходимо модифицировать данные полученные селектом и "отдать" внешнему приложению. Попробовал реализовать процедуру через курсор. Все работает, но курсор риальне "тормозной". Обрабатывает данные со скоростью 100 записей за 5 секунд, т.е. 20 строк/сек. Проблема в том, что таблица содержит порядка 100 000 строк, и колбасить такое счастье через курсор просто нереально. Есть ли еще альтернативные варианты выполнения модификации данных "на лету". (модифицировать данные необходимо в каждой строке)

Запихать модификации в сам селект можно, но не везде. Кое где селекты и так загружены условиями и дополнительными модификациями...

К примеру немного корявинькая процедура:

create procedure SELECT_FIRMLIST__
    @P_EMID int,
    @P_PARENT int

as

DECLARE @FID int;
DECLARE @FNAME nvarchar(200);
DECLARE @FPARENTID int;
DECLARE @FPARENTNAME nvarchar(200);
DECLARE @STID char(2);
DECLARE @FSTREET1 nvarchar(200);
DECLARE @FSTREET2 nvarchar(150);
DECLARE @FCITY nvarchar(30);
DECLARE @FZIP nvarchar(10);
DECLARE @FZIP_FIRST nvarchar(5);
DECLARE @FZIP_EXT nvarchar(4);
DECLARE @STLABEL nvarchar(30);
DECLARE @FIRM_ADDRESS nvarchar(400);
DECLARE @FUACPREFIX nvarchar(12);
DECLARE @FUID nvarchar(32);
DECLARE @FHOSTS nvarchar (max);
DECLARE @FPROGRAM smallint;

BEGIN

DECLARE @SELECT_FIRMLIST_TMP TABLE
(   FID int,
    FNAME nvarchar(200),
    FPARENTID int,
    FPARENTNAME nvarchar(200),
    STID char(2),
    FSTREET1 nvarchar(200),
    FSTREET2 nvarchar(150),
    FCITY nvarchar(30),
    FZIP nvarchar(10),
    FZIP_FIRST nvarchar(5),
    FZIP_EXT nvarchar(4),
    STLABEL nvarchar(30),
    FIRM_ADDRESS nvarchar(400),
    FUACPREFIX nvarchar(12),
    FUID nvarchar(32),
    FHOSTS nvarchar (max),
    FPROGRAM smallint
)


DECLARE SELECT_FIRMLIST CURSOR FOR
	SELECT
      TBL1__0.FID,
      TBL1__0.FNAME,
      TBL1__0.FPARENTID,
      TBL1__1.FNAME AS PARENTNAME,
      COALESCE(TBL1__0.STID, 'AL'), 
      TBL1__0.FSTREET1,
      TBL1__0.FSTREET2,
      TBL1__0.FCITY,
      COALESCE(TBL1__0.FZIP, '') AS FZIP,
      TBLSTATES.STLABEL,
      COALESCE(TBL1__0.FSTREET1, '') + COALESCE(', '+TBL1__0.FSTREET2,  '') AS FIRM_ADDRESS,
      TBL1__0.FUACPREFIX,
      TBL1__0.FUID,
      TBL1__0.FHOSTS,
      TBL1__0.FPROGRAM
	FROM TBL1__ TBL1__0
      LEFT OUTER JOIN TBL1__ TBL1__1 ON (TBL1__0.FPARENTID = TBL1__1.FID)
      LEFT OUTER JOIN TBLSTATES ON (TBL1__0.STID = TBLSTATES.STID)
	WHERE (TBL1__0.FID <> -10) AND (COALESCE(TBL1__0.FPARENTID, -1)= @P_PARENT)

	

OPEN SELECT_FIRMLIST
FETCH NEXT FROM SELECT_FIRMLIST 
INTO @FID, @FNAME, @FPARENTID, @FPARENTNAME, @STID, @FSTREET1, @FSTREET2, @FCITY, @FZIP, @STLABEL, @FIRM_ADDRESS, @FUACPREFIX, @FUID, @FHOSTS, @FPROGRAM 

WHILE @@FETCH_STATUS = 0 
	BEGIN
      SET @FZIP_EXT = NULL;

      if (LEN(@FZIP)>5) 
        BEGIN
          SET @FZIP_FIRST = STR(@FZIP, 1, 5);
          SET @FZIP_EXT = STR(@FZIP, 7, 10);
        end
      ELSE
        SET @FZIP_FIRST = @FZIP;

	INSERT INTO @SELECT_FIRMLIST_TMP (FID, FNAME, FPARENTID, FPARENTNAME, STID, FSTREET1, FSTREET2, FCITY, FZIP, FZIP_FIRST, FZIP_EXT, STLABEL, FIRM_ADDRESS, FUACPREFIX, FUID, FHOSTS, FPROGRAM)
	VALUES (@FID, @FNAME, @FPARENTID, @FPARENTNAME, @STID, @FSTREET1, @FSTREET2, @FCITY, @FZIP, @FZIP_FIRST, @FZIP_EXT, @STLABEL, @FIRM_ADDRESS, @FUACPREFIX, @FUID, @FHOSTS, @FPROGRAM)
	
	FETCH NEXT FROM SELECT_FIRMLIST 
	INTO @FID, @FNAME, @FPARENTID, @FPARENTNAME, @STID, @FSTREET1, @FSTREET2, @FCITY, @FZIP, @STLABEL, @FIRM_ADDRESS, @FUACPREFIX, @FUID, @FHOSTS, @FPROGRAM	
    
    END
    
CLOSE SELECT_FIRMLIST
DEALLOCATE SELECT_FIRMLIST

SELECT * FROM @SELECT_FIRMLIST_TMP;

END
31 июл 12, 17:35    [12942545]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Alexandr Kr.
Member

Откуда: Украина, Харьков
Сообщений: 165
Crayzer,

Б-р-р-р. А почему не так?
INSERT INTO @SELECT_FIRMLIST_TMP (FID, FNAME, FPARENTID, FPARENTNAME, STID, FSTREET1, FSTREET2, FCITY, FZIP, FZIP_FIRST, FZIP_EXT, STLABEL, FIRM_ADDRESS, FUACPREFIX, FUID, FHOSTS, FPROGRAM)

Select * ,case when (LEN(FZIP)>5) then  STR(FZIP, 1, 5)  else FZIP end  as FZIP_FIRST,
case when (LEN(FZIP)>5) then  STR(@FZIP, 7, 10) else null end  as FZIP_FZIP_EXT
 from(
SELECT
       ...

	FROM TBL1__ TBL1__0
      LEFT OUTER JOIN TBL1__ TBL1__1 ON (TBL1__0.FPARENTID = TBL1__1.FID)
      LEFT OUTER JOIN TBLSTATES ON (TBL1__0.STID = TBLSTATES.STID)
	WHERE (TBL1__0.FID <> -10) AND (COALESCE(TBL1__0.FPARENTID, -1)= @P_PARENT)
) a	
31 июл 12, 17:46    [12942616]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Alexandr Kr.
Member

Откуда: Украина, Харьков
Сообщений: 165
Порядок полей только необходимо правильный указать.
31 июл 12, 17:47    [12942625]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Alexandr Kr. , спасибо, сейчас попробую...
31 июл 12, 17:49    [12942638]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Я так понимаю, что "слоение" (т.е. количество вложенных) селектов может быть любым? Главное, в каждом последующем задавать AS что?
31 июл 12, 18:50    [12942946]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Alexandr Kr.
Member

Откуда: Украина, Харьков
Сообщений: 165
Crayzer
Я так понимаю, что "слоение" (т.е. количество вложенных) селектов может быть любым? Главное, в каждом последующем задавать AS что?


Подозреваю что есть ограничение. Вопрос зачем большое количество?
31 июл 12, 18:54    [12942956]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Ну это была одна из самых простых процедур )))
Там дальше вообще мрак + Exec других процедур и получение данных из них. Вполне подозреваю, что можно обойтись дополнительным селектом в текущей процедуре, не дергая другие. Но в любом случае, больше 5 скорее всего не наберется ))))
31 июл 12, 18:57    [12942967]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
ПаWWWлОдАрЕц
Member

Откуда: NSK-PVL
Сообщений: 135
Может быть курсоры заменить на чтото типа этого:
--запоминаем начальные значения переменных
while 1 = 1
	begin
	-- проверка условия окончания цикла
	...
	end

т.е. использовать циклы.
Уменьшение времени выполнения должно сократиться однозначно. Хотя многое конечно зависит от объема данных.
1 авг 12, 08:45    [12944147]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Попробовал все это счастье провернуть в цикле.
Ребята из майкрософта радуют....
Скорость работы цикла ни капельки не отличается от скорости работы курсора.... т.е. 20 записей/сек
ппц товаристчи...
1 авг 12, 16:18    [12947477]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Crayzer
Попробовал все это счастье провернуть в цикле.
Ребята из майкрософта радуют....
Скорость работы цикла ни капельки не отличается от скорости работы курсора.... т.е. 20 записей/сек
ппц товаристчи...
Ну правильно, и то, и другое - тормоз. Раз вы ими решаете свои задачи, то виноваты именно ребята из майкрософта. Кто же еще?

Сообщение было отредактировано: 1 авг 12, 16:21
1 авг 12, 16:20    [12947494]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Гавриленко Сергей Алексеевич
Дело в том, что чем-то другим провернуть сие действие довольно проблемматично....
Вот почему Firebird в цикле не тормозит, а это счастье ужасает своей скоростью?
1 авг 12, 16:26    [12947533]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Crayzer
Гавриленко Сергей Алексеевич
Дело в том, что чем-то другим провернуть сие действие довольно проблемматично....
Проблема-то в чем?
Crayzer
Вот почему Firebird в цикле не тормозит, а это счастье ужасает своей скоростью?
Потому что MSSQL не FireBird. Но раз MSSQL тормозит, пишите на FireBird'е, не мучайтесь.
1 авг 12, 16:29    [12947556]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Многоуважаемый Гавриленко Сергей Алексеевич из москоу сити, если Вам так хочется развести холивар Firebird vs MSSQL, то Вы не по адресу.
Я просто констатировал факт, что MSSQL риальне тормозит в курсорах и в циклах. Хотя за прошедшее время мне удалось допилить цикл до скорости 1790 записей за 3 секунды.На Firebird, к сожалению, писать не получится, ибо контора требует MSSQL...
1 авг 12, 16:51    [12947729]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Crayzer
Я просто констатировал факт, что MSSQL риальне тормозит в курсорах и в циклах. Хотя за прошедшее время мне удалось допилить цикл до скорости 1790 записей за 3 секунды.На Firebird, к сожалению, писать не получится, ибо контора требует MSSQL...
А я до вас хочу донести факт, что не надо писать на MSSQL как на FireBird. И, глядишь, за 3 секунды порядка на 3 записей больше обрабатываться будет.
1 авг 12, 16:54    [12947752]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31991
Crayzer
Я просто констатировал факт, что MSSQL риальне тормозит в курсорах и в циклах. Хотя за прошедшее время мне удалось допилить цикл до скорости 1790 записей за 3 секунды.На Firebird,
Ну может и тормозит в курсорах и в циклах. Поэтому и нужно писать без них. Странно в реляционной субд не использовать реляционые операции.
1 авг 12, 16:55    [12947770]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Crayzer
Member

Откуда:
Сообщений: 37
Гавриленко Сергей Алексеевич , Вы бы лучше чего умного и по делу сказали...
1 авг 12, 16:56    [12947775]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Crayzer
Гавриленко Сергей Алексеевич , Вы бы лучше чего умного и по делу сказали...
Я все умное и по делу уже сказал.
1 авг 12, 16:57    [12947788]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Glory
Member

Откуда:
Сообщений: 104751
Crayzer
Я просто констатировал факт, что MSSQL риальне тормозит в курсорах и в циклах.

Вы констатировали _свое мнение_.
Понятие "факт" включает в себя нечто другое.

Crayzer
если Вам так хочется развести холивар Firebird vs MSSQL, то Вы не по адресу

Зачем вы тогда приплели к разговору Firebird ?
1 авг 12, 17:56    [12948233]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Crayzer
Alexandr Kr.
Crayzer
Я так понимаю, что "слоение" (т.е. количество вложенных) селектов может быть любым? Главное, в каждом последующем задавать AS что?


Подозреваю что есть ограничение. Вопрос зачем большое количество?


Ну это была одна из самых простых процедур )))


Нет сейчас времени вчитываться в Ваш конкретный случай, но: напомню, что кроме вложенных селектов есть еще такое средство, как apply. Который удобен для разных вещей, и среди прочего - для сложных вычислений над результатами запроса.

Т.е. вместо того, чтобы писать как-нибудь так,
select
  ...много полей...,
  (вторая матрешка от X) as X
from (
  select
    ...много полей...,
    (первая матрешка от X) as X
  from (
    select
      ...много полей...,
      x
    from
      ...основной запрос...
    )х
  )x

можно использовать apply, т.е. писать что-нибудь вроде
select
  ...много полей...
  calc.X
from
  ...основной запрос...
outer apply (
  select
    (вторая матрешка от X) as X
  from (
    select
      (первая матрешка от X)
    )calc(X)
  )calc(X)
который и проще, и гибче в использовании. Особенно это заметно, если по ситуации одно и то же условие может определять порядок обработки нескольких разных полей, т.е. вместо нескольких case-блоков с одним и тем же условием в select-части запроса можно использовать один
select обрабтка1 a1, обработка2 a2, ... where условие
в apply.
1 авг 12, 18:08    [12948331]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Гавриленко Сергей Алексеевич
Crayzer
Гавриленко Сергей Алексеевич , Вы бы лучше чего умного и по делу сказали...
Я все умное и по делу уже сказал.

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

К топикстартеру: почитайте про разницу между STATIC, DYNAMIC, FAST_FORWARD и прочими типами курсоров, не оставляйте тип по умолчанию - он 100% будет самый медленный :)
1 авг 12, 18:20    [12948419]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Shlippenbaranus
К топикстартеру: почитайте про разницу между STATIC, DYNAMIC, FAST_FORWARD и прочими типами курсоров, не оставляйте тип по умолчанию - он 100% будет самый медленный :)


Да, и не ссорьте с форуманами: они умные люди, но очень не любят сравнения MSSQL с альтернативными продуктами, когда оно не в пользу первого. Болеют за дело :)
1 авг 12, 18:23    [12948441]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Shlippenbaranus
Не все. Сказали б уже человеку, что курсоры бывают разного типа, и скорость их выполнения может отличаться на порядок.

К топикстартеру: почитайте про разницу между STATIC, DYNAMIC, FAST_FORWARD и прочими типами курсоров, не оставляйте тип по умолчанию - он 100% будет самый медленный :)
Да хоть "волшебный" тип курсора, все равно медленно.
1 авг 12, 18:24    [12948442]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Гавриленко Сергей Алексеевич
Shlippenbaranus
Не все. Сказали б уже человеку, что курсоры бывают разного типа, и скорость их выполнения может отличаться на порядок.

К топикстартеру: почитайте про разницу между STATIC, DYNAMIC, FAST_FORWARD и прочими типами курсоров, не оставляйте тип по умолчанию - он 100% будет самый медленный :)
Да хоть "волшебный" тип курсора, все равно медленно.


Дак никто ж и не спорит. Но это первое, что может сделать человек, не переписывая все. Прирост производительности может быть очень заметный, и его ему хватит.
1 авг 12, 18:29    [12948470]     Ответить | Цитировать Сообщить модератору
 Re: Модификация данных "на лету"  [new]
Ken@t
Member

Откуда: 大地
Сообщений: 3265
Shlippenbaranus,
Какие курсоры , какие cross apply ? Вы ч0 , всё сводится к банальному кэйсу.
SELECT
      TBL1__0.FID,
      TBL1__0.FNAME,
      TBL1__0.FPARENTID,
      TBL1__1.FNAME AS PARENTNAME,
      COALESCE(TBL1__0.STID, 'AL'), 
      TBL1__0.FSTREET1,
      TBL1__0.FSTREET2,
      TBL1__0.FCITY,
      COALESCE(TBL1__0.FZIP, '') AS FZIP,
      ,CASE WHEN LEN(COALESCE(TBL1__0.FZIP, '')) > 5 THEN  STR(FZIP, 1, 5) ELSE @FZIP END FZIP_FIRST 
      ,CASE WHEN LEN(COALESCE(TBL1__0.FZIP, '')) > 5 THEN  STR(@FZIP, 7, 10)) ELSE NULL END @FZIP_EXT 
      TBLSTATES.STLABEL,
      COALESCE(TBL1__0.FSTREET1, '') + COALESCE(', '+TBL1__0.FSTREET2,  '') AS FIRM_ADDRESS,
      TBL1__0.FUACPREFIX,
      TBL1__0.FUID,
      TBL1__0.FHOSTS,
      TBL1__0.FPROGRAM
	FROM TBL1__ TBL1__0
      LEFT OUTER JOIN TBL1__ TBL1__1 ON (TBL1__0.FPARENTID = TBL1__1.FID)
      LEFT OUTER JOIN TBLSTATES ON (TBL1__0.STID = TBLSTATES.STID)
	WHERE (TBL1__0.FID <> -10) AND (COALESCE(TBL1__0.FPARENTID, -1)= @P_PARENT)

За отсутствие указания схемы у обьектов, руки бы оторвал.
1 авг 12, 18:31    [12948482]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить