Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Производительность Функции и JOIN  [new]
DmitryVT
Member

Откуда: VRN
Сообщений: 192
Добрый день господа

исходя из того что я еще (к моему сожалению) новичок, прошу разъяснить немного о производительности и нагрузки на сервер.

Суть вопроса состоит в следующем: сравнение функции и JOIN к таблице

ФУНКЦИЯ:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go


ALTER FUNCTION [dbo].[GetStatus] 
(
	@param varchar(10) 
)
RETURNS VARCHAR(50)
AS
BEGIN
  DECLARE @ZNACH varchar(50)
  if @param = '00'  set @ZNACH = 'Пустой заказ'
  if @param = '02'  set @ZNACH = 'Созданный внешне'
  if @param = '04'  set @ZNACH = 'Созданный внутренне'
  if @param = '08'  set @ZNACH = 'Конвертированный'
  if @param = '09'  set @ZNACH = 'Незапущенный'
  if @param = '-1'  set @ZNACH = 'Неизвестный'
  if @param = '11'  set @ZNACH = 'Част. Предвар. зарезерв.'
  if @param = '12'  set @ZNACH = 'Предв. зарезерв.'
  if @param = '13'  set @ZNACH = 'Обновленный для план.склада'
  if @param = '14'  set @ZNACH = 'Част. зарезерв.'
  if @param = '15'  set @ZNACH = 'Част. зарезерв./Част. отобран'
  if @param = '16'  set @ZNACH = 'Част. зарезерв./Част. отгружен'
  if @param = '17'  set @ZNACH = 'Зарезервированный'
  if @param = '18'  set @ZNACH = 'Замененный'
  if @param = '19'  set @ZNACH = 'Запущенный'
  if @param = '-2'  set @ZNACH = 'Вне синхранизации'
  if @param = '51'  set @ZNACH = 'В состоянии отбора'
  if @param = '52'  set @ZNACH = 'Част. отобран'
  if @param = '53'  set @ZNACH = 'Част. отобран / Част. отгружен'
  if @param = '55'  set @ZNACH = 'Отбор завершен'
  if @param = '57'  set @ZNACH = 'Отобран / Част. отгружен'
  if @param = '61'  set @ZNACH = 'Упаковывается'
  if @param = '68'  set @ZNACH = 'Упаковка завершена'
  if @param = '75'  set @ZNACH = 'В позиции'
  if @param = '78'  set @ZNACH = 'Проявлен'
  if @param = '82'  set @ZNACH = 'В состоянии загрузки'
  if @param = '88'  set @ZNACH = 'Загружен'
  if @param = '92'  set @ZNACH = 'Част. отгружен'
  if @param = '95'  set @ZNACH = 'Отгрузка завершена'
  if @param = '96'  set @ZNACH = 'Доставленный - принятый'
  if @param = '97'  set @ZNACH = 'Доставленный - отвергн.'
  if @param = '98'  set @ZNACH = 'Отменен внешне'
  if @param = '99'  set @ZNACH = 'Отменен внутренне'
	
  RETURN @ZNACH
END


и собственно таблица, содержит аналогичные расшифровки статусов:

USE [PRD1]
GO
/****** Object:  Table [dbo].[STATUS]    Script Date: 09/03/2013 12:13:58 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[STATUS](
	[IDSTATUS] [varchar](2) COLLATE Cyrillic_General_CI_AS NOT NULL,
	[DESCR] [varchar](50) COLLATE Cyrillic_General_CI_AS NULL,
 CONSTRAINT [PK_STATUS] PRIMARY KEY CLUSTERED 
(
	[IDSTATUS] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

---------------------------------------------------------------------
insert into status (IDSTATUS,DESCR) values ('00','Пустой заказ')
insert into status (IDSTATUS,DESCR) values ('02','Созданный внешне')
insert into status (IDSTATUS,DESCR) values ('04','Созданный внутренне')
insert into status (IDSTATUS,DESCR) values ('08','Конвертированный')
insert into status (IDSTATUS,DESCR) values ('09','Незапущенный')
insert into status (IDSTATUS,DESCR) values ('-1','Неизвестный')
insert into status (IDSTATUS,DESCR) values ('11','Част. Предвар. зарезерв.')
insert into status (IDSTATUS,DESCR) values ('12','Предв. зарезерв.')
insert into status (IDSTATUS,DESCR) values ('13','Обновленный для план.склада')
insert into status (IDSTATUS,DESCR) values ('14','Част. зарезерв.')
insert into status (IDSTATUS,DESCR) values ('15','Част. зарезерв./Част. отобран')
insert into status (IDSTATUS,DESCR) values ('16','Част. зарезерв./Част. отгружен')
insert into status (IDSTATUS,DESCR) values ('17','Зарезервированный')
insert into status (IDSTATUS,DESCR) values ('18','Замененный')
insert into status (IDSTATUS,DESCR) values ('19','Запущенный')
insert into status (IDSTATUS,DESCR) values ('-2','Вне синхранизации')
insert into status (IDSTATUS,DESCR) values ('51','В состоянии отбора')
insert into status (IDSTATUS,DESCR) values ('52','Част. отобран')
insert into status (IDSTATUS,DESCR) values ('53','Част. отобран / Част. отгружен')
insert into status (IDSTATUS,DESCR) values ('55','Отбор завершен')
insert into status (IDSTATUS,DESCR) values ('57','Отобран / Част. отгружен')
insert into status (IDSTATUS,DESCR) values ('61','Упаковывается')
insert into status (IDSTATUS,DESCR) values ('68','Упаковка завершена')
insert into status (IDSTATUS,DESCR) values ('75','В позиции')
insert into status (IDSTATUS,DESCR) values ('78','Проявлен')
insert into status (IDSTATUS,DESCR) values ('82','В состоянии загрузки')
insert into status (IDSTATUS,DESCR) values ('88','Загружен')
insert into status (IDSTATUS,DESCR) values ('92','Част. отгружен')
insert into status (IDSTATUS,DESCR) values ('95','Отгрузка завершена')
insert into status (IDSTATUS,DESCR) values ('96','Доставленный - принятый')
insert into status (IDSTATUS,DESCR) values ('97','Доставленный - отвергн.')
insert into status (IDSTATUS,DESCR) values ('98','Отменен внешне')
insert into status (IDSTATUS,DESCR) values ('99','Отменен внутренне')



Теперь выполним два запроса - в таблице wh1.orders 76206 row(s)

1. Select O.orderkey, dbo.getstatus(O.status) as status from wh1.orders as O

2. Select O.orderkey, S.DESCR
from wh1.orders as O inner join dbo.STATUS as S
on O.status = S.idstatus

коллега на работе утверждает что, запрос с функцией это полный крах, но рациональный ответ на этот факт получить от него не могу, не смотря на то что он выполнился быстрее чем с JOIN

Из плана видно что функция нагружает, но анализ мне непонятен ((



помогите пожалуйста, ЗАРАНЕЕ ВСЕМ СПАСИБО!!!

К сообщению приложен файл. Размер - 131Kb
3 сен 13, 12:39    [14788819]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
Glory
Member

Откуда:
Сообщений: 104760
DmitryVT
Из плана видно что функция нагружает, но анализ мне непонятен ((

Посмотрите, сколько раз вызывается ваша функция
3 сен 13, 12:46    [14788870]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
DmitryVT
Member

Откуда: VRN
Сообщений: 192
насколько я понимаю что ровно столько, сколько строк в SELECT

отсюда вывод что скалярная функция проигрывает в производительности между с JOIN ??
3 сен 13, 12:52    [14788913]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
DmitryVT
насколько я понимаю что ровно столько, сколько строк в SELECT

отсюда вывод что скалярная функция проигрывает в производительности между с JOIN ??
Если её переделать в inline табличную функцию
и слегка переделать SELECT, то будет совсем другое дело.

Но сравнивать функцию и JOIN - это всё равно, что сравнивать шуруп с подушкой.
Настолько это разные понятия.
3 сен 13, 12:55    [14788934]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
Glory
Member

Откуда:
Сообщений: 104760
DmitryVT
насколько я понимаю что ровно столько, сколько строк в SELECT

Т.е. 76 000 раз
DmitryVT
отсюда вывод что скалярная функция проигрывает в производительности между с JOIN ??

Как вы думаете, быстрее 76тыс раз выполнить функцию или сделать один Merge join ?
3 сен 13, 12:56    [14788939]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
DmitryVT
Member

Откуда: VRN
Сообщений: 192
Спасибо всем, сейчас попробую переделать в табличную функцию (ранее с этим типом несталкиволся)
3 сен 13, 12:57    [14788945]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
DmitryVT
Спасибо всем, сейчас попробую переделать в табличную функцию (ранее с этим типом несталкиволся)
В табличную INLINE
Это важно.

Ещё лучше написать всё в SELECTе без всяких функций.
3 сен 13, 13:02    [14788969]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
DmitryVT
Member

Откуда: VRN
Сообщений: 192
Спасибо огромное, тема закрыта.

буду осваивать новый материал для меня)))
3 сен 13, 13:11    [14789022]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31430
DmitryVT
коллега на работе утверждает что, запрос с функцией это полный крах, но рациональный ответ на этот факт получить от него не могу, не смотря на то что он выполнился быстрее чем с JOIN

Из плана видно что функция нагружает, но анализ мне непонятен ((
Теоретически функция должна работать быстрее. Теоретически для выполнения расчётов в вашей функции должно хватить нескольких команд (и соответственно тактов) процессора.

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

Так что для справочников можно использовать инлайн-табличные функции, инлайн-табличные функции (когда их сделают в MSSQL), либо просто таблицы-справочники, которые ещё и удобнее для разработки, поддержки, сопровождения.
3 сен 13, 14:52    [14789654]     Ответить | Цитировать Сообщить модератору
 Re: Производительность Функции и JOIN  [new]
Гость333
Member

Откуда:
Сообщений: 3683
DmitryVT
он выполнился быстрее чем с JOIN

"Он" — это запрос с функцией?
А можете выложить раскладку по запросам по SET STATISTICS IO ON и SET STATISTICS TIME ON?
3 сен 13, 15:07    [14789737]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить