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

Откуда:
Сообщений: 56
Привет всем, пожалуйста поделитесь личным опытом работы.
Мне на данный момент интересно в каких случаях его использовать, а в каких все таки темп данные.
На сколько быстрее и быстрее ли вообще.
1 июн 14, 17:19    [16102938]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ckey
быстрее ли вообще

CTE - это синтаксическая обертка
Никакого особого ускорения она не дает.
Просто позволяет написать более компактный код.
1 июн 14, 17:32    [16102964]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Ckey
Привет всем, пожалуйста поделитесь личным опытом работы.
Личный опыт? Вы о чём?
Это маленькие базовые вещи языка. Это базовые знания каждого работника этой отрасли, а не консультация о выборе сложных технологических решений.

Планы, смотрите планы. В плане всё видно как на ладони. Вы должны знать как что работает.

Ckey
Мне на данный момент интересно в каких случаях его использовать, а в каких все таки темп данные.
В каждом случае по разному. Естественно.
Гвоздь - высоко-технологический микроскоп.
6 соток вскопать - тяжёлый трактор с огромным прицепом в десятки плугов.
Подмести плац - лом.

Ckey
На сколько быстрее и быстрее ли вообще.
На сколько быстрее тёплое чем мягкое?
У каждой задачи своя семантическая структура. Цикличного выполнения в таблице нету.

WHILE ?
TSQL (со своими IF WHILE и др. хренью) - интерпретируемый язык. Команда за командой парсится и эмулируется.
А запросы компилируются (в нужный практически машинный код), но логику работы скомпилированного кода можно увидеть через планы.

У текущего CTE есть один недостаток, в рекурсивной части он выполняет строку за строкой. Берётся очередная строка из буфера и результат ложится в него. Это видно в плане.
Если сравнить с таким же принципом работы через WHILE, то TSQL естественно медленее (чем CTE).
Если логика иная, то тут может быть ровно наоборот.

Если вы про то, что некоторую логику (сложное представление данных) вы используете повторно в запросе, то далеко не факт, что имеет смысл сохранять результат во временную таблицу. А если учесть, что вы ничего не знаете о планах, то скорее вы чаще будете ошибаться в выборе эффективного способа обработки данных.
Запись данных намного дороже чем чтение. Повторно считать может быть на порядок быстрее чем записать результат. А с другой стороны иногда/частенько скуль может догадаться и делать сам спуллинг вычисленных данных в буфера (хотя многие спецы требуют расширить и улучшить эти механизмы), если посчитает это необходимым.

Но есть другая проблема, эта сама запись логики в запросе. Плохая формализация приводит к неправильным вещам и запутыванию не только других разрабов, но и самого скуля. Мне лично уже не нравится тот факт что что-то в запросе повторяется. Нет, я не хочу сказать что этого вообще не встречается, а то что у нубов (и императивистов) это встречается чаще, там где этого не точно не нужно, а я бы сказал неправильно.

Старайтесь писать формализовано и компактно, отдайте скулю его работу - строить алгоритм вычисления результата. Если что-то будет работать неприемлемо - лишь тогда можете применять иные варианты.
Хотя планы вы всё ровно обязаны смотреть и изучать иные подходы, чтобы дорасти до специалиста в этой области.

И ещё одно. Помимо того что можно варьировать между CPU и Memory для достижения оптимальности. Также варьируются местом и временем когда это используется. Что-то заранее, что-то опосля, в максимальном и немыслимом диапазоне возможностей. Но также варьируется тем представлением (форматом/видом) данных, который более подходит для решения всех задач в комплексе.
Можно к примеру избавится от цикличной обработки данных используя иные структуры и типы данных (HierarchyID как простой пример), или построить иную структура таблиц и индексов, или даже совсем по другому построить весь программный комплекс. Но это сложно показать в маленьком посте.
2 июн 14, 01:43    [16103989]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
babona
Member [заблокирован]

Откуда: Батуринск
Сообщений: 1816
Mnior,

давно не было?
3 июн 14, 10:06    [16110502]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
CTE хорошо или плохо? Есть случаи, когда без него не обойтись. Есть случаи, когда можно с ним, а когда можно без него. Он даёт модульность, повышает читаемость кода.

Есть люди, которые его не любят.

Есть люди, которые долго сидят на хранилищах данных, вроде меня, и знают MDX, где оператор WITH впервые появился, и мы им вертим как хотим.

Давайте проведём опрос. Стоило ли тут использовать CTE
ALTER VIEW [Dictionary].[vw_Dim_PriceRange]
AS
WITH Price_Starts AS 
(
	SELECT 0 AS Price_Start UNION ALL  
	SELECT 500 UNION ALL 
	SELECT 1000 UNION ALL
	SELECT 1500 UNION ALL 
	SELECT 2000 UNION ALL
	SELECT 2500 UNION ALL 
	SELECT 3000 UNION ALL
	SELECT 4000 UNION ALL 
	SELECT 5000 UNION ALL 
	SELECT 6000 UNION ALL 
	SELECT 7000 UNION ALL 
	SELECT 8000 UNION ALL
	SELECT 9000 UNION ALL
	SELECT 10000 UNION ALL
	SELECT 15000 
), 
Price_Ranges AS 
(
	SELECT 
		Price_Start, 
		LEAD(Price_Start, 1) OVER (ORDER BY Price_Start) AS Price_End, 
		ROW_NUMBER() OVER (ORDER BY Price_Start) AS Price_Range_OrderBy
	FROM Price_Starts
) 
SELECT 
	Price_Start, 
	ISNULL(Price_End, 0x7FFFFFFF) AS Price_End,
	Price_Range_OrderBy, 
	Price_Name = CONCAT(CAST(Price_Start AS VARCHAR(MAX)), ISNULL(' - ' + CAST(Price_End AS VARCHAR(MAX)), N' и выше')) 
FROM 
	Price_Ranges

UNION ALL 

SELECT 
	-1 AS Price_Start, 
	-1 AS Price_End,
	99 AS Price_Range_OrderBy, 
	N'Нет данных'
3 июн 14, 12:49    [16111994]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
Glory
Member

Откуда:
Сообщений: 104760
a_voronin
CTE хорошо или плохо? Есть случаи, когда без него не обойтись.

Интересно, как же без него раньше жили то ...

a_voronin
Он даёт модульность, повышает читаемость кода.

А производительность ?
3 июн 14, 12:57    [16112042]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Как раз на производительность CTE само по себе не влияет. Запрос с одним и тем же планом можно написать как с CTE, так или без него. Производительность определяется умением писать запрос, а CTE это лишь способ записи.
3 июн 14, 14:42    [16113021]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
a_voronin
Стоило ли тут использовать CTE
Тут нет рекурсивного СТЕ (R-CTE).

А говорить про не-рекурсивное CTE (NR-CTE) vs подзапросы бессмысленно.
Компилятор скуля практически получает идентичные запросы на вход при любой форме записи.
Аналогично с VIEW.

Лично я вообще стараюсь не громоздить подзапросы, ибо банально не читабельно.
3 июн 14, 15:56    [16113709]     Ответить | Цитировать Сообщить модератору
 Re: CTE хорошо или плохо и в каких случаях  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
a_voronin,

Практически весь мой пост 16103989 касался рекурсивного варианта.
3 июн 14, 15:57    [16113715]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить