Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Что быстрее? like vs substring()  [new]
Glory
Member

Откуда:
Сообщений: 104751
Гость333
Вот простейшее репро.

Вот именно, что простейший. Имхо
29 авг 13, 12:56    [14770516]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Glory
Member

Откуда:
Сообщений: 104751
Eugene_p1
Glory
пропущено...

Потому что что 1(одно) поле и 2(два) значения для сравнения
Здесь может быть только сканирование индекса. И то, если это индекс нужен для остальных частей запроса.

Поэтому я и задал этот вопрос. Если не трудно, ответьте пожалуйста

Вы серьезно думаете, что использование только функций или только выражений сделает каждый запрос быстрым ?

Eugene_p1
Практический вопрос: как правильно сделать?

Начать с правильной схемы данных ? например, хранить все valueN в одном поле
И не хранить NULL-ы

Сообщение было отредактировано: 29 авг 13, 13:04
29 авг 13, 13:02    [14770554]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Eugene_p1
Практический вопрос: как правильно сделать?

CASE 
WHEN (IsNull(value1,0) <> 0 or  IsNull(value2,0) <> 0   or  IsNull(value4,0) <> 0  or  IsNull(value5,0) <> 0 or  IsNull(value6,0) <> 0) THEN 1
WHEN (IsNull(value7,0) <> 0 or  IsNull(value8,0) <> 0   or  IsNull(value9,0) <> 0  or  IsNull(value10,0) <> 0 or  IsNull(value11,0) <> 0) THEN 2
WHEN ... THEN 3
WHEN ... THEN 4
END as Type

Так это же не "в части where"?
29 авг 13, 13:04    [14770564]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Glory
Вы серьезно думаете, что использование только функций или только выражений сделает каждый запрос быстрым ?

Начать с правильной схемы данных ? например, хранить все valueN в одном поле
И не хранить NULL-ы

Уважаемый Glory.
Проблема в том, что "мопед не мой", т.е. я имею огромную, медленно работающую корпоративную систему, к которой отношусь нынче как пользователь. Пожаловался на медленную работу - в мои руки попал запрос. Посмотрел - ужаснулся, понял, почему всё работает медленно.
Теперь я пытаюсь переписать запрос, чтобы он заработал быстрее. К сожалению, у меня нет доступа к системе, и менять схему данных я врядли смогу. :) Буду писать вслепую, программисты потом отладят.

Поэтому у меня большая просьба ко всем: если вы сможете подсказать мне best practices по затронутым в теме условиям (в т.ч. case) - буду очень благодарен. Постараюсь выжать, что можно.

Тут такое дело - помогаю себе сам.
29 авг 13, 13:15    [14770643]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Гость333
Так это же не "в части where"?

Мне кажется целесообразным переместить её в CASE, т.к. там 3 отдельных запроса на value1-6, value7-11, value12-18.
29 авг 13, 13:18    [14770665]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Glory
Member

Откуда:
Сообщений: 104751
Eugene_p1
Поэтому у меня большая просьба ко всем: если вы сможете подсказать мне best practices по затронутым в теме условиям (в т.ч. case) - буду очень благодарен. Постараюсь выжать, что можно.

Чтобы потом вы сказали
- это я не могу
- это я не хочу
- а это я не буду ?

Если у вас есть конкретный запрос, то приводите его. Причем целиком. А не задавайте абстрактные вопросы, что будет, если в N-ой строке запроса заменю ISNULL на OR или наоборот
29 авг 13, 13:22    [14770684]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Glory
Чтобы потом вы сказали
- это я не могу
- это я не хочу
- а это я не буду ?

Если у вас есть конкретный запрос, то приводите его. Причем целиком. А не задавайте абстрактные вопросы, что будет, если в N-ой строке запроса заменю ISNULL на OR или наоборот


Ну вообще best practices могут быть полезны не только мне, но и другим читателям. Ну да ладно, конкретный так конкретный.


Это часть запроса, т.к. он очень большой, и на 85% состоит из одинаковых кусочков с разными условиями, объединенных UNION ALL. Комментарии мои.

Какие изменения нужно внести?

statcode(varchar(6))

SELECT 
a.int1, 
a.statcode, 
(SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an) as [блок], 
'Федеральные Налоги' as [уровень],
'НДС' as [Налог], --зависит от 2 первых символов statcode - это код налога
'' as [детализация],
companyname(a.an) as [предприятие], --функцию, наверное, нужно убрать? ;)
case when a.int3 = 66 AND len(a.statcode) = 6 AND substring(a.statcode, 2, 1) <> '' 
AND a.statcode NOT LIKE '00000%'  AND a.statcode NOT LIKE '093000' AND a.statcode NOT LIKE '094000' AND a.statcode NOT LIKE '140000'AND a.statcode NOT LIKE '141000'
AND a.statcode NOT LIKE '142000'AND a.statcode NOT LIKE '143000'AND a.statcode NOT LIKE '144000'
THEN (SELECT name FROM n_subj s WHERE s.subj = substring(a.statcode,5,2)) end as [бюджет] , --бюджет выбирается по последним 2 символам statcode, это код.
'Налоги' as [категория], 
-- в зависимости от категории берутся 3 набора valueX (X=12456, 8-13, 18-23), видно в последней части запроса
value1 as [сальдо], value2 as [начислено], value4 as [оплата], value5 as [возврат], value6 as [зачет] 

FROM #basic a
WHERE  a.statcode LIKE '01%' AND (IsNull(value1,0) <> 0 or IsNull(value2,0) <> 0   or  IsNull(value4,0) <> 0  or  IsNull(value5,0) <> 0 or  IsNull(value6,0) <> 0 )


UNION ALL
SELECT a.int1, a.statcode,(SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an) as [блок], 'Региональные Налоги и сборы' as [уровень],
'Налог на имущество' as [Налог],
'' as [детализация],
companyname(a.an) as [предприятие],
case when a.int3 = 66 AND len(a.statcode) = 6
AND substring(a.statcode, 2, 1) <> ''
AND a.statcode NOT LIKE '00000%' AND a.statcode NOT LIKE '093000' AND a.statcode NOT LIKE '094000' AND a.statcode NOT LIKE '140000'AND a.statcode NOT LIKE '141000'
AND a.statcode NOT LIKE '142000'AND a.statcode NOT LIKE '143000'AND a.statcode NOT LIKE '144000'
THEN (SELECT name FROM n_subj s WHERE s.subj = substring(a.statcode,5,2)) end as [бюджет] ,
'Налоги' as [категория],
value1 as [сальдо], value2 as [начислено], value4 as [оплата], value5 as [возврат], value6 as [зачет]
FROM #basic a
WHERE  a.statcode LIKE '11%' AND (IsNull(value1,0) <> 0 or  IsNull(value2,0) <> 0   or  IsNull(value4,0) <> 0  or  IsNull(value5,0) <> 0 or  IsNull(value6,0) <> 0)


UNION ALL

SELECT a.int1, a.statcode,(SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an) as [блок], 'Региональные Налоги и сборы' as [уровень],
'Налог на имущество' as [Налог],
'' as [детализация],
companyname(a.an) as [предприятие],
case when a.int3 = 66 AND len(a.statcode) = 6
AND a.statcode NOT LIKE '00000%' AND a.statcode NOT LIKE '093000' AND a.statcode NOT LIKE '094000' AND a.statcode NOT LIKE '140000'AND a.statcode NOT LIKE '141000'
AND a.statcode NOT LIKE '142000'AND a.statcode NOT LIKE '143000'AND a.statcode NOT LIKE '144000'
THEN (SELECT name FROM n_subj s WHERE s.subj = substring(a.statcode,5,2)) end as [бюджет] ,
'Пени' as [категория],
value8 as [сальдо], value9 as [начислено], value11 as [оплата], value12 as [возврат], value13 as [зачет]
FROM #basic a
WHERE  a.statcode LIKE '11%'  AND (IsNull(value8,0) <> 0 or  IsNull(value9,0) <> 0   or  IsNull(value11,0) <> 0  or  IsNull(value12,0) <> 0 or  IsNull(value13,0) <> 0)


UNION ALL

 итд итп
29 авг 13, 14:46    [14771248]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Glory
Member

Откуда:
Сообщений: 104751
Eugene_p1
итд итп

Изучите UNPIVOT
29 авг 13, 14:50    [14771266]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Glory
Изучите UNPIVOT


Сейчас почитаю.
Я условия (анализ statcode) хотел в case запихнуть. Целесообразно?
Что еще нужно здесь изменить?
29 авг 13, 14:58    [14771305]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
Eugene_p1,
если "итд итп" отличается только строками

value8 as [сальдо], value9 as [начислено], value11 as [оплата], value12 as [возврат], value13 as [зачет]
...
WHERE  a.statcode LIKE '11%'  AND (IsNull(value8,0) <> 0 or  IsNull(value9,0) <> 0   or  IsNull(value11,0) <> 0  or  IsNull(value12,0) <> 0 or  IsNull(value13,0) <> 0)

, то я бы условие перенес в область select и избавился бы от union all
29 авг 13, 15:04    [14771344]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Eugene_p1,
раз вы из временной таблицы выборки делаете, то такие вещи как (IsNull(value1,0) <> 0 or IsNull(value2,0) <> 0 or IsNull(value4,0) <> 0 or IsNull(value5,0) <> 0 or IsNull(value6,0) <> 0) можно ведь заранее обсчитать. и это SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an тоже можно заранее вставлять во временную. И если имеет смысл покрывающий индекс по условиям запроса, учитывая, что (IsNull(value1,0) <> 0 or IsNull(value2,0) <> 0 or IsNull(value4,0) <> 0 or IsNull(value5,0) <> 0 or IsNull(value6,0) <> 0) уже посчитано.
29 авг 13, 15:07    [14771362]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Glory
Member

Откуда:
Сообщений: 104751
Eugene_p1
Я условия (анализ statcode) хотел в case запихнуть. Целесообразно?

Целесобразно сделать справочник для statcode. Откуда и брать названия
29 авг 13, 15:09    [14771381]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Eugene_p1
Я условия (анализ statcode) хотел в case запихнуть. Целесообразно?

Ну, к примеру, первый и второй селекты отличаются только условием — a.statcode LIKE '01%' либо a.statcode LIKE '11%' и значениями столбцов [уровень] и [Налог].

Поэтому их целесообразно соединить в один селект, примерно так:
SELECT ...,
       CASE WHEN a.statcode LIKE '01%' THEN 'Федеральные Налоги' ELSE 'Региональные Налоги и сборы' END as [уровень],
       CASE WHEN a.statcode LIKE '11%' THEN 'НДС' ELSE 'Налог на имущество' END as [Налог],
       ...
FROM #basic a
WHERE a.statcode LIKE '[01]1%' AND ...

В итоге вместо двух сканирований таблицы #basic получается одно сканирование.

Функция companyname(), действительно, может давать очень сильную просадку по производительности.

А сколько строк в таблице #basic? И сколько селектов объединено в запросе?
29 авг 13, 15:11    [14771389]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Мистер Хенки
и это SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an тоже можно заранее вставлять во временную

Какая же это переменная, это коррелированный подзапрос :-)
29 авг 13, 15:13    [14771403]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Гость333
Ну, к примеру, первый и второй селекты отличаются только условием — a.statcode LIKE '01%' либо a.statcode LIKE '11%' и значениями столбцов [уровень] и [Налог].
Поэтому их целесообразно соединить в один селект, примерно так:
В итоге вместо двух сканирований таблицы #basic получается одно сканирование.

Именно так я и предполагал сделать. Или есть еще более оптимальные варианты?

Гость333
Функция companyname(), действительно, может давать очень сильную просадку по производительности.
А сколько строк в таблице #basic? И сколько селектов объединено в запросе?

select'ов около 50, строк неизвестно, но думаю, сильно больше миллиона.
29 авг 13, 15:15    [14771418]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Гость333
Какая же это переменная, это коррелированный подзапрос :-)

временная

я, кстати, думал эту таблицу приджойнить.
29 авг 13, 15:17    [14771431]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Eugene_p1
Гость333
Какая же это переменная, это коррелированный подзапрос :-)

временная

А, извиняюсь, был невнимателен.

А текст функции companyname можно увидеть?
29 авг 13, 15:19    [14771448]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Гость333
А текст функции companyname можно увидеть?

CREATE function [dbo].[companyname] (@vcode int)  
returns varchar(255)  
as  
begin  
 declare @name varchar(255)  
 select @name = case when vcode = 0 then '...' else name  end  
  from  dbo.analitics (nolock)  
  where vcode = @vcode  
return (isnull(@name,''))  
end
29 авг 13, 15:23    [14771482]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Гость333
Мистер Хенки
и это SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an тоже можно заранее вставлять во временную

Какая же это переменная, это коррелированный подзапрос :-)

так а что мешает добавить segment к временной таблице и делать SELECT TOP 1 segment FROM _nalog n WHERE n.ucode =a.an на этапе формирования временной таблицы. Ну особого ничего это не даст, конечно. Вот верно тут про функцию заметили, что она может приводить к неоптимальным планам. Кстати,
case when a.int3 = 66 AND len(a.statcode) = 6
AND substring(a.statcode, 2, 1) <> ''
AND a.statcode NOT LIKE '00000%' AND a.statcode NOT LIKE '093000' AND a.statcode NOT LIKE '094000' AND a.statcode NOT LIKE '140000'AND a.statcode NOT LIKE '141000'
AND a.statcode NOT LIKE '142000'AND a.statcode NOT LIKE '143000'AND a.statcode NOT LIKE '144000'
THEN (SELECT name FROM n_subj s WHERE s.subj = substring(a.statcode,5,2)) end as [бюджет]
это же обычный левый джойн с кучей предикатв соединения, зачем его так записывать?
29 авг 13, 15:25    [14771491]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Eugene_p1
Гость333
А текст функции companyname можно увидеть?

CREATE function [dbo].[companyname] (@vcode int)  
returns varchar(255)  
as  
begin  
 declare @name varchar(255)  
 select @name = case when vcode = 0 then '...' else name  end  
  from  dbo.analitics (nolock)  
  where vcode = @vcode  
return (isnull(@name,''))  
end

вам лучше избавиться от этой функции или заменить ее табличной встроенной функцией
CREATE function [dbo].[companyname] (@vcode int)  
returns table
return  
(

 select top 1 isNull(case when vcode = 0 then '...' else name  end,''  ) name
  from  dbo.analitics (nolock)  
  where vcode = @vcode  
)  
29 авг 13, 15:31    [14771527]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Glory
Целесобразно сделать справочник для statcode. Откуда и брать названия

Вот, кстати, спасибо. Действительно.
29 авг 13, 15:33    [14771552]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Мистер Хенки
[/src] это же обычный левый джойн с кучей предикатв соединения, зачем его так записывать?

А как его записать?
LEFT JOIN n_subj s ON s.subj = substring(a.statcode,5,2)) AND a.statcode NOT LIKE '00000%' AND a.statcode NOT LIKE '09[34]000' AND a.statcode NOT LIKE '14[01234]000'

?
29 авг 13, 15:37    [14771589]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Мистер Хенки
вам лучше избавиться от этой функции или заменить ее табличной встроенной функцией

Я собирался сделать LEFT JOIN
29 авг 13, 15:38    [14771598]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Подпольщег
Guest
Народ, а в MSSQL запросы вида
LIKE '%abc%def%'

индексы используют?
29 авг 13, 15:58    [14771746]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее? like vs substring()  [new]
Eugene_p1
Member

Откуда: Москва
Сообщений: 295
Подпольщег,

нет
29 авг 13, 16:11    [14771840]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить