powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Best practice по сведению двух CTE
23 сообщений из 98, страница 4 из 4
Best practice по сведению двух CTE
    #39564286
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileДля набегающего итога?
Окно >> Сэлфджоин >> ОТВ >> Курсор
Поскольку твой 2008 не может решить задачу окном, то тебе нужен самоджойн.
Почему лучше, потому, что быстрее. Просто быстрее во всех случаях.

как раз в 2008-ом нарастающий итог быстрее всего считается курсором
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564298
slovnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamoto,

снова эти непохожие примеры про гвозди, шо ж их тут так любят?
я описал проблему и спросил как её решить.

новичок - он на то и новичок, что не знает что и где искать.
для вашего чсв важно считать меня неграмотным - наздоровье, я неграмотный.

кто хотел помочь - помог уже.
вон комментом ниже подробно объясняют, дают полезную информацию.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564304
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123 как раз в 2008-ом нарастающий итог быстрее всего считается курсором
Исследования в студию.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564306
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileВ моей картине мира есть ровно ДВА случая, когда нужно использовать именно ОТВ.

В моей наоборот... Я теперь только через CTE пишу.. удобнее же...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
;WITH
SummaData AS
(
  SELECT
    t.Data,
    SUM(t.Amount) AS Amount
  FROM
    TableA AS t
  GROUP BY
    t.Data
),
CountData AS
(
  SELECT
    t.Data,
    COUNT(*) AS Cnt
  FROM
    TableB AS t
  GROUP BY
    t.Data
),
MergeData AS
(
  SELECT
    sd.Data,
    sd.Amount,
    cd.Cnt,
    ROW_NUMBER() OVER (PARTITION BY sd.Amount ORDER BY (SELECT NULL)) AS rown
  FROM
    SummaData AS sd
    JOIN CountData AS cd
      ON cd.Data = sd.Data
)
  SELECT
    md.Data,
    md.Amount,
    md.Cnt
  FROM
    MergeData AS md
  WHERE
    md.rown = 1


Напишите это без CTE
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
SELECT
  md.Data,
  md.Amount,
  md.Cnt
FROM
(
  SELECT
    sd.Data,
    sd.Amount,
    cd.Cnt,
    ROW_NUMBER() OVER (PARTITION BY sd.Amount ORDER BY (SELECT NULL)) AS rown
  FROM
  (
    SELECT
      t.Data,
      SUM(t.Amount) AS Amount
    FROM
      TableA AS t
    GROUP BY
      t.Data
  ) AS sd
    JOIN
    (
      SELECT
        t.Data,
        COUNT(*) AS Cnt
      FROM
        TableB AS t
      GROUP BY
        t.Data
    ) AS cd
      ON cd.Data = sd.Data
) AS md
WHERE
  md.rown = 1



Такие вещи очень хороши с OVER т.к. результат оконки нельзя использовать в WHERE в текущем контексте, поэтому если надо потом отфильтровать то надо оборачивать в подзапросы... А это удобнее с CTE

Важно только понимать что подзапросы не будут выполнятся в том порядке в котором они идут в CTE, а сервер после разворота сам решит...
Новички обычно на этом и спотыкаются.. Даже... Я не раз слышал от коллег работающих довольно долго с SQL но не хотящих вдаваться в подробности кухни MSSQL, что они когда так пишут всерьез думают что сервер и один раз выполнит и типа положит в буфер результат, чтобы N раз обратится.. и порядок выполнения тоже.... А потом удивляются откуда там 20 млрд reads и cpu умирает...
После чего мне хотелось сказать -50% к премии.. Жаль нет полномочий
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564307
slovnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileЧто значит чем лучше мой вариант чем ЦТЕ.

Вопрос в том, для решения какой задачи лучше?

Для набегающего итога?
Окно >> Сэлфджоин >> ОТВ >> Курсор
Поскольку твой 2008 не может решить задачу окном, то тебе нужен самоджойн.
Почему лучше, потому, что быстрее. Просто быстрее во всех случаях.

Для инкапсуляции "промежуточных наборов данных"?
Это опять же бабушка на двое сказала. Лично я не люблю СТЕ из-за ограничений, которые они накладывают на написание кода. СТЕ ты обязан использовать СРАЗУ после объявления, и никак иначе. Понятно почему, потому, что это (кроме случая с рекурсией) простой синтаксический сахар, который развернется, в итоге в тоже что и
Код: sql
1.
SELECT  FROM (SELECT FROM) Z

.

Работу СТЕ ты не можешь, например, легко проверить во время написания процедуры, в отличие от #таблицы.

Ласт, бат нот лист, весь синтаксис ОТВ довольно необычен для скуль кода, и прямо скажем, режет глаз, особенно когда один за другим идет ворох ОТВшек- сложно распутывать.

Таким образом именно для меня ОТВ вообще ничем не лучше других способов вращать данные, при этом наличиствуют очевидные недостатки.


В моей картине мира есть ровно ДВА случая, когда нужно использовать именно ОТВ.

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

Очередной очень ценный коммент.
Если быстее - то не вопрос что лучше.

Насчёт как на глаз - мне интуитивно как раз CTE легче читается. Особенно когда тянет из разных баз.

И главное, так и не понял, как обойти unbounded preceding в 2008?
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564310
slovnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteВажно только понимать что подзапросы не будут выполнятся в том порядке в котором они идут в CTE, а сервер после разворота сам решит...
Новички обычно на этом и спотыкаются.. Даже... Я не раз слышал от коллег работающих довольно долго с SQL но не хотящих вдаваться в подробности кухни MSSQL, что они когда так пишут всерьез думают что сервер и один раз выполнит и типа положит в буфер результат, чтобы N раз обратится.. и порядок выполнения тоже.... А потом удивляются откуда там 20 млрд reads и cpu умирает...

А откуда знаем как именно выполняется, чтоб избежать "20 млрд reads и cpu умирает".
Где почитать про это?
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564313
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВажно только понимать что подзапросы не будут выполнятся в том порядке в котором они идут в CTE, а сервер после разворота сам решит...
Ага, и в какой то момент твоя логика встанет колом, потому, что поменялось качество данных, слетела статистика, инопланетяне облучили твой сервак из космоса и так далее.

И человек, который подхватывает твою разработку, 10 раз проклянет тебя, за эти твои ОТВ.


авторНапишите это без CTE

SELECT .. INTO #SmallFilterTable
SELECT .. INTO #AggregateTable
SELECT .. INTO #IDs
...

SELECT ... FROM #IDs MERGE JOIN #SmallFilterTable LOOP JOIN #AggregateTable ... MaintTable OPTION(F ORCE ORDER )
;-)

Чего в твоих ЦТЕ попросту не взлетит.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564324
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileавторНапишите это без CTE

SELECT .. INTO #SmallFilterTable
SELECT .. INTO #AggregateTable
SELECT .. INTO #IDs
...

SELECT ... FROM #IDs MERGE JOIN #SmallFilterTable LOOP JOIN #AggregateTable ... MaintTable OPTION(F ORCE ORDER )
;-)

Чего в твоих ЦТЕ попросту не взлетит.

Так есть же голова... Смотрим.. Большой запрос с 20 подзапросами.. Данных в таблицах под 100 млн... Оптимизатор не может подобрать оптимальный толковый план..
Смотрим по частям и видим что можно часть данных перекинуть во времянки, положить туда индексов, и уже над ними проводить действия... И это будет быстрее...
Я же не говорю, что CTE везде и всегда... На все есть голова, знания, и опыт, чтобы понимать когда и что применять...
Но в большинстве случаев когда данных в среднем до 1 млн, оптимизатор отлично справляется... У нас есть View которая инкапсулирует в себе ценовые предложения для клиента с учетом скидок, наценок, правил и.т.п. View - Это одна большая инструкция, без времянок.. Подзапросов CTE там около 20 штук... Если их оформить одним запросом, то сам черт ногу сломит... А не View нельзя, потому что на нее маппится Entity Framework который считает ее метаобъектом и может над ней строить запросы используя свою объектную модель...

slovnetА откуда знаем как именно выполняется, чтоб избежать "20 млрд reads и cpu умирает".
Где почитать про это?

SET STATISTICS IO ON
SET STATISTICS TIME ON
Плюс планы запросов, плюс профайлер + понимание теории построения индексов и внутренних операторов MSSQL при построении плана, плюс понимание логического конвейера обработки запросов...
+ опыт.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564346
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileYasha123 как раз в 2008-ом нарастающий итог быстрее всего считается курсором
Исследования в студию.
репро приводит то, кто несет фигню.
но специально для вас вот, пожалуйста:
Best approaches for running totals – updated for SQL Server 2012
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564355
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123Cammomileпропущено...

Исследования в студию.
репро приводит то, кто несет фигню.
но специально для вас вот, пожалуйста:
Best approaches for running totals – updated for SQL Server 2012 Вы грамотно не выделили последнее предложение
Все же не самым быстрым, а с минимальным количеством чтений. По крайней мере, в этом репро у курсора четвертое место по скорости.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564363
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinamotoYasha123пропущено...

репро приводит то, кто несет фигню.
но специально для вас вот, пожалуйста:
Best approaches for running totals – updated for SQL Server 2012 Вы грамотно не выделили последнее предложение
Все же не самым быстрым, а с минимальным количеством чтений. По крайней мере, в этом репро у курсора четвертое место по скорости.
товарищ, вы о чем?
мы говорим о 2008 -ом?
значит, window functions-решения мы отметаем, так?
ААрон отмел CTE и quirky update, и даже написано почему.

ну и наконец, Камомиля утветждал, что "самоджойн быстрее всего".
ну так вот вам картинкой время выполнения курсора и "самоджойна".
вы правда не видите, что быстрее?
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564367
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для тех, кто не видит, что речь о 2008
+ cursor vs Сэлфджоин
Yasha123CammomileДля набегающего итога?
Окно >> Сэлфджоин >> ОТВ >> Курсор
Поскольку твой 2008 не может решить задачу окном, то тебе нужен самоджойн .
Почему лучше, потому, что быстрее. Просто быстрее во всех случаях .

как раз в 2008-ом нарастающий итог быстрее всего считается курсором
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564388
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНапишите это без CTE
SELECT .. INTO #SmallFilterTable
SELECT .. INTO #AggregateTable
SELECT .. INTO #IDs
...


Да, (если возможно) лучше без сложных CTE.
Времменые таблицы - оч. полезная вещь.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564390
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123Minamotoпропущено...
Вы грамотно не выделили последнее предложение
Все же не самым быстрым, а с минимальным количеством чтений. По крайней мере, в этом репро у курсора четвертое место по скорости.
товарищ, вы о чем?
мы говорим о 2008 -ом?
значит, window functions-решения мы отметаем, так?
ААрон отмел CTE и quirky update, и даже написано почему.

ну и наконец, Камомиля утветждал, что "самоджойн быстрее всего".
ну так вот вам картинкой время выполнения курсора и "самоджойна".
вы правда не видите, что быстрее?
О том, что он является самым быстрым при исключении ненадежных способов, которые, теоретически, могут дать неверные результаты (но это не точно). Но не "самым быстрым", о чем заявляли вы.
Если бы вы сразу сказали, что "курсор быстрее самоджойна", и привели бы точно такое же обоснование - вопросов бы не было )
Я лишь зацепился за фразу "It has the highest duration of the "faster" solutions".
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564394
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite А не View нельзя, потому что на нее маппится Entity Framework который считает ее метаобъектом и может над ней строить запросы используя свою объектную модель...

Типичная ситуация, когда херовое проектирование тянет за собой плохой код. Это аргумент не в защиту СТЕ, это аргумент против того рукожопа, который 20 СТЕ свел в одно представление.



Yasha123 , окей, картинка убедительная. Я в 2008 не работал уже лет 6.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564396
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правда, остается вопрос, почему по защите аргумента "в 2008 курсой быстрее" ты приводишь статью про "2012", но это мы оставим на твоей совести.

Протестировать сам я не могу, за неимением 2008р2 под рукой, а в сети, увы, не смог найти подобного исследования.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564405
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
slovnet
И главное, так и не понял, как обойти unbounded preceding в 2008?

Ну вот видишь, по последним данным от Ящьки123, самое быстрое в твоем случае, это курсор. Если, конечно, у тебя не стоит задача написать функцию. Тогда курсор не подойдет.

под спойлером самоджойн если ты не разобрался
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
DECLARE 
  @Orders TABLE (
  ID int identity (1,1) 
, OrdNo varchar(20) 
, Date datetime
, PartName varchar(20) 
, OrdQty int) 

INSERT INTO @Orders VALUES 
 ('Заказ1',	'01/02/18',	'Part1',	5)
,('Заказ2',	'01/01/18',	'Part1',	8)
,('Заказ3',	'01/05/18',	'Part1',	3)
,('Заказ4',	'01/01/17',	'Part2',	10)
,('Заказ5',	'01/01/19',	'Part2',	6)


SELECT
O.OrdNo
, O.OrdQty 
, RunningTotal = SUM(ISNULL(O2.OrdQty, 0)) 

, O.Date
, O.Id


FROM @Orders O 
LEFT JOIN @Orders O2 ON O2.ID <= O.ID
GROUP BY O.OrdNo
, O.OrdQty 
, O.Date
, O.Id
ORDER BY O.ID 

...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564406
slovnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cammomile,

slovnetИ главное, так и не понял, как обойти unbounded preceding в 2008?

Так можно в 2008 сделать самоджойном или нет?
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564407
slovnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cammomile,

Спасибо.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564428
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinamotoО том, что он является самым быстрым при исключении ненадежных способов, которые, теоретически, могут дать неверные результаты (но это не точно). Но не "самым быстрым", о чем заявляли вы.
Если бы вы сразу сказали, что "курсор быстрее самоджойна" , и привели бы точно такое же обоснование - вопросов бы не было )
Я лишь зацепился за фразу "It has the highest duration of the "faster" solutions".
у меня вообще-то приведена цитата того,
что я опровергаю.
и на картинке у меня подчеркнуто именно то, что относится к запрашиваемому репро.

товарищ попросил "исследования в студию"
в ответ на мою реплику о курсоре, который в 2008-ом быстрее.

а почему я ему не рассказываю о "ненадежных способов, которые, теоретически, могут дать неверные результаты (но это не точно)",
это мое личное дело
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564431
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CammomileНу вот видишь, по последним данным от Ящьки123
исследование не мое, а Аарона.
а имя не корежь, оно не мое, так звали моего покойного кота.
но если тебе доставляет удовольствие,
то да, наверняка он в гробу перевернулся от такого к нему внимания
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564433
Cammomile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123... а имя не корежь...
но при этом
Yasha123... ну и наконец, Камомиля утветждал...


За собой следи, для начала.
...
Рейтинг: 0 / 0
Best practice по сведению двух CTE
    #39564521
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторо курсоре, который в 2008-ом быстрее

Собственно, я в этом и не сомневался, т.к. данные формируются за один проход в отличие от других способов.
...
Рейтинг: 0 / 0
23 сообщений из 98, страница 4 из 4
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Best practice по сведению двух CTE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]