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

Откуда:
Сообщений: 1090
Столкнулся со странной проблемой предсказания статистики рядов с использованием CASE WHEN. Здесь я приведу маленький подзапрос (не оригинал, просто упростил его по максимуму, по сути он бессмыслен), проблема которого в том, что SQL Server думает что в результате получается одна запись, после чего с этим подзапросом начинает использовать nested loop'ы и общий запрос не выполняется никогда:

              SELECT t0.k0 AS jkey0
               FROM
                 (SELECT t0."Picking_skuPickingDetail" AS k0,
                            SUM(t0."Picking_quantityPickingDetail") AS e0
                     FROM Picking_pickingDetail t0
                     GROUP BY t0."Picking_skuPickingDetail") t0
               LEFT JOIN
                 (SELECT t0."Picking_skuPickingOrderDetail" AS k0,
                         SUM(t0."Picking_quantityPickingOrderDetail") AS e0
                  FROM Picking_pickingOrderDetail t0
                  GROUP BY t0."Picking_skuPickingOrderDetail") t1 ON t1.k0=t0.k0
               WHERE (CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL)


План:
8620(!)1	1(!)	  |--Filter(WHERE:(CASE WHEN [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL THEN [Expr1005]-[Expr1001] ELSE NULL END IS NOT NULL))
8621	1	8621	       |--Hash Match(Left Outer Join, HASH:([t0].[Picking_skuPickingDetail])=([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]))
0	0	8621	            |--Compute Scalar(DEFINE:([Expr1001]=CASE WHEN [Expr1019]=(0) THEN NULL ELSE [Expr1020] END))
8621	1	8621	            |    |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]) DEFINE:([Expr1019]=COUNT_BIG([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail]), [Expr1020]=SUM([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail])))
53721	1	53721	            |         |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0]))
0	0	8859	            |--Compute Scalar(DEFINE:([Expr1005]=[Expr1003]))
0	0	8859	                 |--Compute Scalar(DEFINE:([Expr1003]=CASE WHEN [Expr1021]=(0) THEN NULL ELSE [Expr1022] END))
8859	1	8859	                      |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]) DEFINE:([Expr1021]=COUNT_BIG([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail]), [Expr1022]=SUM([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail])))
56755	1	56755	                           |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0]))


При этом, если изменить условие на (CASE WHEN t0.k0 IS NOT NULL THEN t1.e0 ELSE t0.e0 END IS NOT NULL), план становится гораздо лучше:

8620	1	8039,342	  |--Filter(WHERE:(CASE WHEN [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL THEN [Expr1005] ELSE [Expr1001] END IS NOT NULL))	WHERE:(CASE WHEN [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL THEN [Expr1005] ELSE [Expr1001] END IS NOT NULL)
8621	1	8621	       |--Hash Match(Left Outer Join, HASH:([t0].[Picking_skuPickingDetail])=([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]))	HASH:([t0].[Picking_skuPickingDetail])=([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail])
0	0	8621	            |--Compute Scalar(DEFINE:([Expr1001]=CASE WHEN [Expr1019]=(0) THEN NULL ELSE [Expr1020] END))	DEFINE:([Expr1001]=CASE WHEN [Expr1019]=(0) THEN NULL ELSE [Expr1020] END)
8621	1	8621	            |    |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]) DEFINE:([Expr1019]=COUNT_BIG([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail]), [Expr1020]=SUM([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail])))	HASH:([t0].[Picking_skuPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail])
53721	1	53721	            |         |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0]))	OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0])
0	0	8859	            |--Compute Scalar(DEFINE:([Expr1005]=[Expr1003]))	DEFINE:([Expr1005]=[Expr1003])
0	0	8859	                 |--Compute Scalar(DEFINE:([Expr1003]=CASE WHEN [Expr1021]=(0) THEN NULL ELSE [Expr1022] END))	DEFINE:([Expr1003]=CASE WHEN [Expr1021]=(0) THEN NULL ELSE [Expr1022] END)
8859	1	8859	                      |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]) DEFINE:([Expr1021]=COUNT_BIG([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail]), [Expr1022]=SUM([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail])))	HASH:([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail])
56755	1	56755	                           |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0]))	OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0])


Из веселого, если добавить JOIN Stock_sku t2 ON t2.key0 = t0.k0 (key0 единственный primary key), а по k0 идет группировка, то есть соединение 1 к 1 при этом t2 больше нигде не используется:

              SELECT t0.k0 AS jkey0
               FROM
                 (SELECT t0."Picking_skuPickingDetail" AS k0,
                            SUM(t0."Picking_quantityPickingDetail") AS e0
                     FROM Picking_pickingDetail t0
                     GROUP BY t0."Picking_skuPickingDetail") t0
				 JOIN Stock_sku t2 ON t2.key0 = t0.k0
               LEFT JOIN
                 (SELECT t0."Picking_skuPickingOrderDetail" AS k0,
                         SUM(t0."Picking_quantityPickingOrderDetail") AS e0
                  FROM Picking_pickingOrderDetail t0
                  GROUP BY t0."Picking_skuPickingOrderDetail") t1 ON t1.k0=t0.k0
               WHERE (CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL)


План опять таки становится адекватным:

8620	1	7725,397	  |--Filter(WHERE:(CASE WHEN [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL THEN [Expr1006]-[Expr1001] ELSE NULL END IS NOT NULL))
8620	1	8620	       |--Hash Match(Left Outer Join, HASH:([t0].[Picking_skuPickingDetail])=([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]))
8620	1	8620	            |--Hash Match(Inner Join, HASH:([t0].[Picking_skuPickingDetail])=([t2].[key0]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]=[mothercare].[dbo].[Stock_sku].[key0] as [t2].[key0]))
0	0	8621	            |    |--Compute Scalar(DEFINE:([Expr1001]=CASE WHEN [Expr1018]=(0) THEN NULL ELSE [Expr1019] END))
8621	1	8621	            |    |    |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail]) DEFINE:([Expr1018]=COUNT_BIG([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail]), [Expr1019]=SUM([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail])))
53721	1	53721	            |    |         |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0]))
39799	1	39799	            |    |--Index Scan(OBJECT:([mothercare].[dbo].[Stock_sku].[Stock_skuGroupSku_idx] AS [t2]))
0	0	8859	            |--Compute Scalar(DEFINE:([Expr1006]=[Expr1004]))
0	0	8859	                 |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1020]=(0) THEN NULL ELSE [Expr1021] END))
8859	1	8859	                      |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]) DEFINE:([Expr1020]=COUNT_BIG([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail]), [Expr1021]=SUM([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail])))
56755	1	56755	                           |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0]))


Пробовал на SQL Server 2012 Express без с service pack'а и с ним же, и на 2014 где якобы улучшили расчет cardinality. Может кто-нить в курсе как он вообще считается для CASE'а.

PS: Кстати если преобразовать условие в WHERE (t0.k0 IS NOT NULL AND (t1.e0-t0.e0) IS NOT NULL), то план меняется на адекватный как в последнем случае (правда исходная проблема когда CASE WHEN внутри группировочного подзапроса, а сверху идет предикат t0.p0 IS NOT NULL, поэтому такое преобразование не всегда можно выполнить).
3 июн 14, 10:58    [16110912]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Может кто-нить в курсе как он вообще считается для CASE'а.

Как неизвестное выражение.
Потому что оптимизатор не вычисляет ничего.
3 июн 14, 11:00    [16110931]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Nitro_Junkie
Может кто-нить в курсе как он вообще считается для CASE'а.

Как неизвестное выражение.
Потому что оптимизатор не вычисляет ничего.


Забыл написать, что если обернуть CASE WHEN в scalar функцию (то есть условие WHERE dbo.xx(t0.k0, t1.e0, t0.e0) IS NOT NULL) то все так же становится хорошо (как в 3-м случае).

Ну и чуть-чуть меняется case как во втором случае estimate также меняется.

То есть тут как раз наоборот, горе от ума, но вычислить общий случае пока не получается :( . Похоже проблема как раз в CASE WHEN ... ELSE NULL END похоже.
3 июн 14, 11:06    [16111001]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Забыл написать, что если обернуть CASE WHEN в scalar функцию (то есть условие WHERE dbo.xx(t0.k0, t1.e0, t0.e0) IS NOT NULL) то все так же становится хорошо (как в 3-м случае).

А вы лучшесть/хужость как оцениваете ?
3 июн 14, 11:09    [16111028]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Nitro_Junkie,

Хм... Если здесь (и в исходной проблеме) заменить ELSE NULL END, на ELSE 1 END. Все становится хорошо. Мистика.
3 июн 14, 11:10    [16111048]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Nitro_Junkie
Забыл написать, что если обернуть CASE WHEN в scalar функцию (то есть условие WHERE dbo.xx(t0.k0, t1.e0, t0.e0) IS NOT NULL) то все так же становится хорошо (как в 3-м случае).

А вы лучшесть/хужость как оцениваете ?


В соответствии Estimate - Actual... Это самая опасная проблема в планах в принципе, потому как может привести к nested loop'у двух таблиц по 50к записей. Или материализации такого join'а пусть даже с hash join'ом.
3 июн 14, 11:11    [16111069]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
В соответствии Estimate - Actual...

У вас Estimate - Actual не отличаются в приведенных планах
3 июн 14, 11:16    [16111104]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Nitro_Junkie,

Мда... А так надеялись уйти от проблем со статистикой в PostgreSQL, где захардкожена selectivity 0.3 для > <, 0.05 для = (при этом они тупо перемножаются) нет cross - column статистику, и достаточно group by'в сваливаются в статистику 200. И тут на тебе.
3 июн 14, 11:16    [16111105]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Nitro_Junkie
В соответствии Estimate - Actual...

У вас Estimate - Actual не отличаются в приведенных планах


Я там (!) пометил в первом плане. 1-я колонка actual, 3-я estimate
3 июн 14, 11:16    [16111110]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

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

У вас Estimate - Actual не отличаются в приведенных планах


Я там (!) пометил в первом плане. 1-я колонка actual, 3-я estimate

Вы хотите сказать, что самый последний Filter в плане офигительно влияет на производительность ?
3 июн 14, 11:20    [16111132]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

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


Я там (!) пометил в первом плане. 1-я колонка actual, 3-я estimate

Вы хотите сказать, что самый последний Filter в плане офигительно влияет на производительность ?


Офигительно.

Вот исходный запрос:
              (SELECT t0.k0 AS jkey0,
                      t0.k1 AS jkey1,
                      CASE WHEN ABS(COALESCE(t1.e0,0)-COALESCE(t0.e0,0))>0.0005 THEN COALESCE(t1.e0,0)-COALESCE(t0.e0,0) ELSE NULL END AS jprop0,
                                                                                                                                          t0.k1 AS jprop1
               FROM
                 (SELECT t0.k0 AS k0,
                         t1."Picking_pickingOrderPicking" AS k1,
                         CASE WHEN ABS(SUM(t0.e0))>0.0005 THEN SUM(t0.e0) ELSE NULL END AS e0
                  FROM
                    (SELECT t0."Picking_skuPickingDetail" AS k0,
                            t0."Picking_pickingPickingDetail" AS k1,
                            CASE WHEN ABS(SUM(t0."Picking_quantityPickingDetail"))>0.0005 THEN SUM(t0."Picking_quantityPickingDetail") ELSE NULL END AS e0
                     FROM Picking_pickingDetail t0
                     WHERE (t0."Picking_quantityPickingDetail" IS NOT NULL
                            AND t0."Picking_skuPickingDetail" IS NOT NULL
                            AND t0."Picking_pickingPickingDetail" IS NOT NULL)
                     GROUP BY t0."Picking_skuPickingDetail",
                              t0."Picking_pickingPickingDetail") t0
                  JOIN Picking_picking t1 ON t1."key0"=t0.k1
                  WHERE (t0.e0 IS NOT NULL
                         AND t1."Picking_pickingOrderPicking" IS NOT NULL)
                  GROUP BY t0.k0,
                           t1."Picking_pickingOrderPicking") t0
               LEFT JOIN
                 (SELECT t0."Picking_skuPickingOrderDetail" AS k0,
                         t0."Picking_pickingOrderPickingOrderDetail" AS k1,
                         CASE WHEN ABS(SUM(t0."Picking_quantityPickingOrderDetail"))>0.0005 THEN SUM(t0."Picking_quantityPickingOrderDetail") ELSE NULL END AS e0
                  FROM Picking_pickingOrderDetail t0
                  WHERE (t0."Picking_quantityPickingOrderDetail" IS NOT NULL
                         AND t0."Picking_skuPickingOrderDetail" IS NOT NULL
                         AND t0."Picking_pickingOrderPickingOrderDetail" IS NOT NULL)
                  GROUP BY t0."Picking_skuPickingOrderDetail",
                           t0."Picking_pickingOrderPickingOrderDetail") t1 ON t1.k0=t0.k0
               AND t1.k1=t0.k1
               WHERE (t0.e0 IS NOT NULL
                      AND CASE WHEN ABS(COALESCE(t1.e0,0)-COALESCE(t0.e0,0))>0.0005 THEN COALESCE(t1.e0,0)-COALESCE(t0.e0,0) ELSE NULL END IS NOT NULL))


Вот план:

0	0	1	  |--Compute Scalar(DEFINE:([Expr1011]=CASE WHEN abs(CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.000) END-CASE WHEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END IS NOT NULL THEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END ELSE (0.000) END)>(0.0005) THEN CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.000) END-CASE WHEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END IS NOT NULL THEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END ELSE (0.000) END ELSE NULL END))
390	1	1	       |--Filter(WHERE:(CASE WHEN abs(CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.000) END-CASE WHEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END IS NOT NULL THEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END ELSE (0.000) END)>(0.0005) THEN CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.000) END-CASE WHEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END IS NOT NULL THEN CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END ELSE (0.000) END ELSE NULL END IS NOT NULL))
53011(!)	1	1	            |--Nested Loops(Left Outer Join, OUTER REFERENCES:([t0].[Picking_skuPickingDetail], [t1].[Picking_pickingOrderPicking]))
53011	1	1	                 |--Filter(WHERE:(CASE WHEN abs([Expr1004])>(0.0005) THEN [Expr1004] ELSE NULL END IS NOT NULL))
0	0	5573,791	                 |    |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1042]=(0) THEN NULL ELSE [Expr1043] END))
53011	1	5573,791	                 |         |--Stream Aggregate(GROUP BY:([t1].[Picking_pickingOrderPicking], [t0].[Picking_skuPickingDetail]) DEFINE:([Expr1042]=COUNT_BIG(CASE WHEN abs([Expr1001])>(0.0005) THEN [Expr1001] ELSE NULL END), [Expr1043]=SUM(CASE WHEN abs([Expr1001])>(0.0005) THEN [Expr1001] ELSE NULL END)))
53011	1	5573,791	                 |              |--Sort(ORDER BY:([t1].[Picking_pickingOrderPicking] ASC, [t0].[Picking_skuPickingDetail] ASC))
53011	1	5573,791	                 |                   |--Hash Match(Inner Join, HASH:([t1].[key0])=([t0].[Picking_pickingPickingDetail]))
402	1	402	                 |                        |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_picking].[PK__Picking___2B3B219519751BB0] AS [t1]), WHERE:([mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking] IS NOT NULL))
53011	1	16113,3	                 |                        |--Filter(WHERE:(CASE WHEN abs([Expr1001])>(0.0005) THEN [Expr1001] ELSE NULL END IS NOT NULL))
53011	1	53711	                 |                             |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail], [t0].[Picking_pickingPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail]) DEFINE:([Expr1001]=SUM([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail])))
53716	1	53711	                 |                                  |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0]), WHERE:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail] IS NOT NULL))
0	0	1	                 |--Compute Scalar(DEFINE:([Expr1010]=CASE WHEN abs([Expr1007])>(0.0005) THEN [Expr1007] ELSE NULL END))
53011	53011	1	                      |--Stream Aggregate(DEFINE:([Expr1007]=SUM([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail])))
53728	53011	1	                           |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0]), WHERE:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail]=[mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking] AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail] IS NOT NULL))


Выполняется 2 минуты. Из-за nested loop join'а. Если обернуть все CASE WHEN ... ELSE NULL END в функции - 1,5 секунды.

Могу скинуть случай побольше где он вообще не выполнится.
3 июн 14, 11:25    [16111165]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Выполняется 2 минуты. Из-за nested loop join'а. Если обернуть все CASE WHEN ... ELSE NULL END в функции - 1,5 секунды.

Вы хотите сказать, что фильтр по функции делается где-то в середине плана ?
Или что разные тексты запросов могут привести к разным стртегиям соединения ?
3 июн 14, 11:46    [16111347]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Nitro_Junkie
Выполняется 2 минуты. Из-за nested loop join'а. Если обернуть все CASE WHEN ... ELSE NULL END в функции - 1,5 секунды.

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


Внутри плана, а где еще ему выполнятся:

Запрос :
              (SELECT t0.k0 AS jkey0,
                      t0.k1 AS jkey1,
                      dbo.notZero(COALESCE(t1.e0,0)-COALESCE(t0.e0,0)) AS jprop0,
                                                                                                                                          t0.k1 AS jprop1
               FROM
                 (SELECT t0.k0 AS k0,
                         t1."Picking_pickingOrderPicking" AS k1,
                         dbo.notZero(SUM(t0.e0)) AS e0
                  FROM
                    (SELECT t0."Picking_skuPickingDetail" AS k0,
                            t0."Picking_pickingPickingDetail" AS k1,
                            dbo.notZero(SUM(t0."Picking_quantityPickingDetail")) AS e0
                     FROM Picking_pickingDetail t0
                     WHERE (t0."Picking_quantityPickingDetail" IS NOT NULL
                            AND t0."Picking_skuPickingDetail" IS NOT NULL
                            AND t0."Picking_pickingPickingDetail" IS NOT NULL)
                     GROUP BY t0."Picking_skuPickingDetail",
                              t0."Picking_pickingPickingDetail") t0
                  JOIN Picking_picking t1 ON t1."key0"=t0.k1
                  WHERE (t0.e0 IS NOT NULL
                         AND t1."Picking_pickingOrderPicking" IS NOT NULL)
                  GROUP BY t0.k0,
                           t1."Picking_pickingOrderPicking") t0
               LEFT JOIN
                 (SELECT t0."Picking_skuPickingOrderDetail" AS k0,
                         t0."Picking_pickingOrderPickingOrderDetail" AS k1,
                         dbo.notZero(SUM(t0."Picking_quantityPickingOrderDetail")) AS e0
                  FROM Picking_pickingOrderDetail t0
                  WHERE (t0."Picking_quantityPickingOrderDetail" IS NOT NULL
                         AND t0."Picking_skuPickingOrderDetail" IS NOT NULL
                         AND t0."Picking_pickingOrderPickingOrderDetail" IS NOT NULL)
                  GROUP BY t0."Picking_skuPickingOrderDetail",
                           t0."Picking_pickingOrderPickingOrderDetail") t1 ON t1.k0=t0.k0
               AND t1.k1=t0.k1
               WHERE (t0.e0 IS NOT NULL
                      AND dbo.notZero(COALESCE(t1.e0,0)-COALESCE(t0.e0,0)) IS NOT NULL))


План:

53011	1	925,401	  |--Compute Scalar(DEFINE:([Expr1011]=[mothercare].[dbo].[notZero](CONVERT_IMPLICIT(numeric(18,5),CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.00000) END-CASE WHEN [Expr1005] IS NOT NULL THEN [Expr1005] ELSE (0.00000) END,0))))
53011	1	925,401	       |--Filter(WHERE:([mothercare].[dbo].[notZero](CONVERT_IMPLICIT(numeric(18,5),CASE WHEN [Expr1010] IS NOT NULL THEN [Expr1010] ELSE (0.00000) END-CASE WHEN [Expr1005] IS NOT NULL THEN [Expr1005] ELSE (0.00000) END,0)) IS NOT NULL AND [Expr1005] IS NOT NULL))
53011	1	1329,222	            |--Compute Scalar(DEFINE:([Expr1005]=[mothercare].[dbo].[notZero](CONVERT_IMPLICIT(numeric(18,5),[Expr1004],0))))
53011	1	1329,222	                 |--Hash Match(Left Outer Join, HASH:([t0].[Picking_skuPickingDetail], [t1].[Picking_pickingOrderPicking])=([t0].[Picking_skuPickingOrderDetail], [t0].[Picking_pickingOrderPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail]=[mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail]=[mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking]))
53011	1	1329,222	                      |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail], [t1].[Picking_pickingOrderPicking]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] AND [mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking] = [mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking]) DEFINE:([Expr1004]=SUM([Expr1002])))
53011	1	16258,75	                      |    |--Filter(WHERE:([Expr1002] IS NOT NULL))
53011	1	17799,78	                      |         |--Compute Scalar(DEFINE:([Expr1002]=[mothercare].[dbo].[notZero](CONVERT_IMPLICIT(numeric(18,5),[Expr1001],0))))
53011	1	17799,78	                      |              |--Hash Match(Inner Join, HASH:([t1].[key0])=([t0].[Picking_pickingPickingDetail]))
402	1	402	                      |                   |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_picking].[PK__Picking___2B3B219519751BB0] AS [t1]), WHERE:([mothercare].[dbo].[Picking_picking].[Picking_pickingOrderPicking] as [t1].[Picking_pickingOrderPicking] IS NOT NULL))
53011	1	53711	                      |                   |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingDetail], [t0].[Picking_pickingPickingDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail] = [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail]) DEFINE:([Expr1001]=SUM([mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail])))
53716	1	53711	                      |                        |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingDetail].[PK__Picking___2B3B219530710113] AS [t0]), WHERE:([mothercare].[dbo].[Picking_pickingDetail].[Picking_skuPickingDetail] as [t0].[Picking_skuPickingDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_pickingPickingDetail] as [t0].[Picking_pickingPickingDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingDetail].[Picking_quantityPickingDetail] as [t0].[Picking_quantityPickingDetail] IS NOT NULL))
55997	1	56755	                      |--Compute Scalar(DEFINE:([Expr1010]=[mothercare].[dbo].[notZero](CONVERT_IMPLICIT(numeric(18,5),[Expr1007],0))))
55997	1	56755	                           |--Hash Match(Aggregate, HASH:([t0].[Picking_skuPickingOrderDetail], [t0].[Picking_pickingOrderPickingOrderDetail]), RESIDUAL:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail] = [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail]) DEFINE:([Expr1007]=SUM([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail])))
56755	1	56755	                                |--Clustered Index Scan(OBJECT:([mothercare].[dbo].[Picking_pickingOrderDetail].[PK__Picking___2B3B2195227DC2EC] AS [t0]), WHERE:([mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_skuPickingOrderDetail] as [t0].[Picking_skuPickingOrderDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_pickingOrderPickingOrderDetail] as [t0].[Picking_pickingOrderPickingOrderDetail] IS NOT NULL AND [mothercare].[dbo].[Picking_pickingOrderDetail].[Picking_quantityPickingOrderDetail] as [t0].[Picking_quantityPickingOrderDetail] IS NOT NULL))


То есть он все равно ошибается, но не много. Главное nested loop исчезает, потому как перестает думать что где-то 1 запись вместо 53000.
3 июн 14, 11:53    [16111434]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory,

Нескромный вопрос. А у вас когда запрос медленно выполняется \ не выполняется какие мысли в первую очередь?

У меня первая всегда одна (при этом я бы сказал с вероятностью 99,5%) - сервер не угадал со статистикой и запустил : чаще всего nested loop, реже hash join двух таблиц на 50к записей и только потом фильтрацию. Поэтому я всегда декомпозирую до ошибки статистики, все остальное уже вторично.
3 июн 14, 11:58    [16111487]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
А у вас когда запрос медленно выполняется \ не выполняется какие мысли в первую очередь?

Критерии медленности - они разные
Hash Match, например, требует больше ресурсов, чем Nested Loops
А ресурсы - они, как известно, не резиновые
3 июн 14, 12:05    [16111551]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Nitro_Junkie
А у вас когда запрос медленно выполняется \ не выполняется какие мысли в первую очередь?

Критерии медленности - они разные
Hash Match, например, требует больше ресурсов, чем Nested Loops
А ресурсы - они, как известно, не резиновые


Это я в курсе. Но пользователь не "прибегает" с криком у меня запрос на 20% медленнее выполняется. Он прибегает с криком почему у меня запрос 10 минут \ час \ не выполняется. При нехватке же ресурсов у всех начинает тормозить и тогда другие критерии. Но их часто проще решить просто нарастив ресурсы на те же 20-40% (особенно когда в облаке).
3 июн 14, 12:11    [16111623]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Он прибегает с криком почему у меня запрос 10 минут \ час \ не выполняется.

Что еще раз говорит о том, что медленно/быстро есть очень плавающий критерий

- "Медленного" плана вы так и не показали
- А кардиналити для выражения оптимизатор никак не может вычислить
3 июн 14, 12:15    [16111672]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Почему бы не материализовать агрегаты и перестать плясать с бубном? Тем более, что у вас всегда агрегируется вся таблица.
3 июн 14, 12:19    [16111720]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
- "Медленного" плана вы так и не показали
- А кардиналити для выражения оптимизатор никак не может вычислить


Показал же 5 сообщений наверх. Где запрос 2 минуты вместо 1,5 секунды выполняется.

Если никак не может вычислить то почему estimate для условий

CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL
и
CASE WHEN t0.k0 IS NOT NULL THEN t1.e0 ELSE t0.e0 END IS NOT NULL

значительно отличаются?
3 июн 14, 12:27    [16111789]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
invm
Почему бы не материализовать агрегаты и перестать плясать с бубном? Тем более, что у вас всегда агрегируется вся таблица.


Потому как это мина замедленного действия. Да и с ограничениями в INDEXED VIEW ничего особо не материализуешь.

The SELECT statement in the view definition must not contain the following Transact-SQL elements:
COUNT
ROWSET functions (OPENDATASOURCE, OPENQUERY, OPENROWSET, AND OPENXML)
OUTER joins (LEFT, RIGHT, or FULL)
Derived table (defined by specifying a SELECT statement in the FROM clause)
Self-joins
Specifying columns by using SELECT * or SELECT table_name.*
DISTINCT
STDEV, STDEVP, VAR, VARP, or AVG
Common table expression (CTE)
float *, text, ntext, image, XML, or filestream columns
Subquery
OVER clause, which includes ranking or aggregate window functions
Full-text predicates (CONTAIN, FREETEXT)
SUM function that references a nullable expression
ORDER BY
CLR user-defined aggregate function
TOP
CUBE, ROLLUP, or GROUPING SETS operators
MIN, MAX
UNION, EXCEPT, or INTERSECT operators
TABLESAMPLE
Table variables
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT
Sparse column sets
Inline or multi-statement table-valued functions
OFFSET
CHECKSUM_AGG

У меня скажем такие же проблемы с window функциями...
3 июн 14, 12:31    [16111829]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Где запрос 2 минуты вместо 1,5 секунды выполняется.

Офигительно показывать планы от разных запросов
Офигительно рассказывать о времени выполнения

Nitro_Junkie
Если никак не может вычислить то почему estimate для условий
CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL
и
CASE WHEN t0.k0 IS NOT NULL THEN t1.e0 ELSE t0.e0 END IS NOT NULL

значительно отличаются?

Вы разницу между "вычисляет" и "предполагает" понимаете ?
3 июн 14, 12:35    [16111873]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Glory
Офигительно показывать планы от разных запросов
Офигительно рассказывать о времени выполнения


Не совсем понимаю что вы имеете ввиду. Я привел два плана демонстрируя, что если бы MS SQL считал что у CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL cardinality такое же как у db.xx(t0.k0, t1.e0,t0.e0) (что соответствует реальности) то он построил бы план как во втором случае и выполнил бы запрос за 1,5 секунды. А так он выполняет этот запрос за 2 минуты. То есть ошибается.

Nitro_Junkie
Если никак не может вычислить то почему estimate для условий
CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL
и
CASE WHEN t0.k0 IS NOT NULL THEN t1.e0 ELSE t0.e0 END IS NOT NULL

значительно отличаются?

Вы разницу между "вычисляет" и "предполагает" понимаете ?[/quot]

Так меня и интересует как он предполагает cardinality CASE WHEN оператора? Как видим он лезет внутрь него, а не просто CASE WHEN - значит cardinality 1/0.5/0.1 как это делает скажем PostgreSQL.
3 июн 14, 12:40    [16111920]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Nitro_Junkie
Потому как это мина замедленного действия.
А все время агрегировать таблицы целиком не мина?
Nitro_Junkie
Да и с ограничениями в INDEXED VIEW ничего особо не материализуешь.
Не увидел в ваших подзапросах препятствий для материализации.
3 июн 14, 12:42    [16111934]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Материализовывать можно не только индексированными представлениями.
Хотите выбирать быстро - держите данные в готовом виде.
3 июн 14, 12:43    [16111945]     Ответить | Цитировать Сообщить модератору
 Re: Проблемы с cardinality оператора CASE WHEN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Nitro_Junkie
Я привел два плана демонстрируя, что если бы MS SQL считал что у CASE WHEN t0.k0 IS NOT NULL THEN t1.e0-t0.e0 ELSE NULL END IS NOT NULL cardinality такое же как у db.xx(t0.k0, t1.e0,t0.e0) (что соответствует реальности)

Вы про первое сообщение ?
Это в нем один запрос выполняется 2 минуты, а второй 1.5 секунды ?
3 июн 14, 12:44    [16111956]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить