Re[41]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: iHateLogins  
Дата: 01.07.09 00:18
Оценка:
Здравствуйте, Ikemefula, Вы писали:

ВВ>>Обычно вообще-то переход, скажем, на 10g превращается в масштабный и сложный проект и вовсе не потому, что там "бизнес-логика" в базе.

I>Поясни.

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

Именно поэтому у многих сейчас работает оракл даже 8-й версии, хотя на дворе уже 11-я. Стоимость перехода неоправданно высока, такова жизнь.
Re[41]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: iHateLogins  
Дата: 01.07.09 00:21
Оценка: -1
Здравствуйте, gandjustas, Вы писали:

G>Еще раз: главное абстрагировать BL от хранилища.


Как вам другая задача: абстрагировать BL от языка программирования. Возьмётесь?
Re[14]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: iHateLogins  
Дата: 01.07.09 00:24
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

Y>>Я отвечал на вполне конкретное заявление и iHateLogins вполне однозначно сказал то что сказал. Там не было ничего ни про массовые колличества ни про всегда плохо.


НС>А давай мы не будем пытаться превратно трактовать, а прямо у него спросим — считает ли iHateLogins, что юнит-тесты это всегда плохо?


Нет, я так не считаю. В некоторых проектах, связанных с мат. вычислениями, я использовал юнит-тесты по полной и это мне помогло сэкономить кучу времени при тестировании.
Re[42]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.07.09 00:52
Оценка:
Здравствуйте, iHateLogins, Вы писали:

ВВ>>>Обычно вообще-то переход, скажем, на 10g превращается в масштабный и сложный проект и вовсе не потому, что там "бизнес-логика" в базе.

I>>Поясни.

HL>Переход с одной версии БД на другую в случае оракла — это очень нетривиальное занятие, т.к. изменения могут быть критичными для функционирования

HL>приложения, ряд запросов возможно придётся переписать, какой-то функционал больше не поддерживается, зато появился новый итд итд итд.

Меня интересует "вовсе не потому, что там "бизнес-логика" в базе", а ты пояснил как раз про бизнеслогику в базе
Re[14]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: yuriylsh  
Дата: 01.07.09 01:03
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, yuriylsh, Вы писали:


Y>>Я отвечал на вполне конкретное заявление и iHateLogins вполне однозначно сказал то что сказал. Там не было ничего ни про массовые колличества ни про всегда плохо.


НС>А давай мы не будем пытаться превратно трактовать,


Точно, давай не будем.

НС>а прямо у него спросим — считает ли iHateLogins, что юнит-тесты это всегда плохо?


Спрашивай, если хочеться. Мне абсолютно не интересно, что он по этому поводу считает. К словам, на которые я отвечал этот вопрос не имеет никакого отношения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Luck in life always exists in the form of an abstract class that cannot be instantiated directly and needs to be inherited by hard work and dedication.
Re[43]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: iHateLogins  
Дата: 01.07.09 01:32
Оценка:
Здравствуйте, Ikemefula, Вы писали:

ВВ>>>>Обычно вообще-то переход, скажем, на 10g превращается в масштабный и сложный проект и вовсе не потому, что там "бизнес-логика" в базе.

I>>>Поясни.

HL>>Переход с одной версии БД на другую в случае оракла — это очень нетривиальное занятие, т.к. изменения могут быть критичными для функционирования

HL>>приложения, ряд запросов возможно придётся переписать, какой-то функционал больше не поддерживается, зато появился новый итд итд итд.

I>Меня интересует "вовсе не потому, что там "бизнес-логика" в базе", а ты пояснил как раз про бизнеслогику в базе


Даже если логики (транзакций) в базе нет, наверняка там есть вьюхи, индексы, оптимизированные для спец. запросов, вычисляемые колонки с индексами на них для лучшей производительности, ETL для аналитики, итд итд. Всё это перенести с одной БД на другую — это совсем не тривиальное занятие.
Re[33]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: iHateLogins  
Дата: 01.07.09 01:34
Оценка: +1
Здравствуйте, Ikemefula, Вы писали:


___>>СУБД — да это определяется сразу. А вот перекидывать с одной СУБД на другую — тот еще гемор — заказчик посылается в лес.

I>Интересный подход однако, посылать заказчика. Жалко в ЖКХ где работает мой отец, об этом не знали. А то MSSQL выдохся и перешли на Оракл.

Ну так если не знать как оптимизировать SQL Server, то переход на оракл не поможет. Это раз.
А во-вторых, лучше бы ЖКХ лучше занималось своими непосредственными задачами и уважало своих клиентов (владельцев квартир), а не занималось откатной хернёй с переходом на оракл (который стоит где-то в 20 раз дороже SQL Server).
Re[30]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.07.09 03:28
Оценка:
Здравствуйте, iHateLogins, Вы писали:
HL>Такой подход как у _d_m_ будет как раз самым быстрым.
Это, интересно, почему? Ты полагаешь, что SQL Server сам не умеет выкидывать промежуточные результаты на диск?
Единственное, где это может 100% помочь — когда один и тот же подзапрос используется дважды в рамках одной транзакции. Кросс-запросную оптимизацию сиквел, естественно, не делает.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[33]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 04:08
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, _d_m_, Вы писали:


___>>СУБД — да это определяется сразу. А вот перекидывать с одной СУБД на другую — тот еще гемор — заказчик посылается в лес.


I>Интересный подход однако, посылать заказчика.


Мы не собираемся прыгать аки горные козлики с одной СУБД на другую. Тем более нет прецендентов с производительностью, багами, или необходимостью каких-то супервозможностей и фич в другой СУБД. Поэтому резонный вопрос: а на каком основании переход на другую СУБД? Но клиентам глубоко побоку на СУБД, их интересует возможности продукта, а как оно там реализовано. Если клиент выдвигает неадекватные требования — есть другие клиенты.

I>Жалко в ЖКХ где работает мой отец, об этом не знали. А то MSSQL выдохся и перешли на Оракл.


Я не знаю как там в вашей местности с ЖКХ, но у нас ЖКХ это просто кровососы.
Re[31]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 04:10
Оценка: +1
Здравствуйте, criosray, Вы писали:

HL>>Такой подход как у _d_m_ будет как раз самым быстрым.


C>Да уж... если уже писать глупости, так по полной не зная меры?


Прекрати некропостинг, если есть что по существу — пиши. Иначе "лучше жевать чем говорить".
Re[31]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 04:14
Оценка: +1 :)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, iHateLogins, Вы писали:

HL>>Такой подход как у _d_m_ будет как раз самым быстрым.
S>Это, интересно, почему? Ты полагаешь, что SQL Server сам не умеет выкидывать промежуточные результаты на диск?

Может. Но все таки, еще раз: практическими экспирементами выявлено, это самый производительный вариант для любой комбинации входных параметров.
Re[24]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 04:22
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, _d_m_, Вы писали:


___>>Только плюс линку. Но заниматься преждевременной оптимизацией — "красивый рукопашный скрипт" — зло. Запросы надо писать так, как-будто ничего не знаешь про работу движка СУБД.


НС>Ага. И с линком это получается намного лучше.


___>>Классно. Но это хак. Оптимизатор СУБД должен этим заниматься.


НС>Не, ну ты можешь конечно ждать, когда оптимизатор станет идеальным. Лично я предпочитаю смотреть на то, что есть в наличии.


Отвечу всем: ну не будем переписывать проект с нуля, т.к. линк такой вот прекрасный. Хватает и того, что есть без линка. Тем более: то он разрабатывается, то его там вроде хотели закрыть, а то опять он ожил. А MS SQL и его оптимизатор будут, и оптимизатор будут подтягивать.

___>>PS: Речь изначально шла не об этом. Сначала gandjustas ляпнул ерунду (или коряво выразился), которую всем понять было только как: кэширование и индексы работают только для линк-запросов.


НС>Ну, касательно ляпанья gandjustas все вопросы к нему, он много тут такой пурги несет, что одной больше, одной меньше ...


Re[28]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 04:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, _d_m_, Вы писали:



___>>Ну это для детей. Для оптимизатора isnull — черный ящик.

S>Ок. Теперь для взрослых:
S>
S>select count(*) from sysobjects where id = @id or @id is null
S>


Если ты про = @Товар or @Товар is null, то он ваще не играет никакой роли. Писать отдельный запрос ради этого редкого частного случая смысла нет. Скорость приемлимая, и ради того чтобы юзер ждал 1 секунду вместо 5... оно того не стоит.
Re[31]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 05:06
Оценка:
Здравствуйте, criosray, Вы писали:

C>Здравствуйте, _d_m_, Вы писали:



___>>Это очень эффективный запрос. Проверено множеством тестом, вариациями, реальными данными и временем.


C>Покажите план запроса.


       |--Sort(ORDER BY:([Expr1060] ASC))
            |--Compute Scalar(DEFINE:([Expr1050]=[Звездный].[dbo].[УдобочитаемаяПартия]([Expr1040],[Expr1041],[Expr1042],N' '), [Expr1051]=[Звездный].[dbo].[ПолучитьБазовуюЕдиницу]([Expr1038]), [Expr1052]=CASE WHEN [@флПрихЦена]=(1) THEN [Expr1044] ELSE NULL END, [Expr1053]=CASE WHEN [@флПрихЦена]=(1) THEN [Звездный].[dbo].[ТоварЗакупЦена_NonRLS]([Expr1038],[@НаДату]) ELSE NULL END, [Expr1054]=CASE WHEN [@флРасхЦена]=(1) THEN [Звездный].[dbo].[ТоварЦена_NonRLS]([Expr1038],[@НаДату],default) ELSE NULL END, [Expr1059]=isnull([Expr1057],(0.000)), [Expr1060]=CASE WHEN [@флСортПоГруппам]=(1) THEN [Expr1048] ELSE [Expr1049] END))
                 |--Hash Match(Right Outer Join, HASH:([рт].[Товар], [рт].[Склад])=([Expr1038], [Expr1039]), RESIDUAL:([Звездный].[dbo].[РезервыТоваров].[Товар] as [рт].[Товар]=[Expr1038] AND [Звездный].[dbo].[РезервыТоваров].[Склад] as [рт].[Склад]=[Expr1039]))
                      |--Stream Aggregate(GROUP BY:([рт].[Склад], [рт].[Товар]) DEFINE:([Expr1057]=SUM([Звездный].[dbo].[РезервыТоваров].[Резерв] as [рт].[Резерв])))
                      |    |--Clustered Index Scan(OBJECT:([Звездный].[dbo].[РезервыТоваров].[кпк_РезервыТоваров.Склад.Товар.ИдТипаДок.КодДок] AS [рт]), ORDERED FORWARD)
                      |--Sequence Project(DEFINE:([Expr1049]=rank))
                           |--Segment
                                |--Segment
                                     |--Sort(ORDER BY:([т].[Наименование] ASC, [Expr1039] ASC))
                                          |--Sequence Project(DEFINE:([Expr1048]=rank))
                                               |--Segment
                                                    |--Segment
                                                         |--Sort(ORDER BY:([Expr1047] ASC, [т].[Наименование] ASC, [Expr1039] ASC))
                                                              |--Compute Scalar(DEFINE:([Expr1047]=[Звездный].[dbo].[ф_ТоварыГруппыПолныйПуть]([Звездный].[dbo].[Товары].[КодРодителя] as [т].[КодРодителя])))
                                                                   |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1038], [Expr1080]) WITH UNORDERED PREFETCH)
                                                                        |--Filter(WHERE:([Expr1043]<>(0.0)))
                                                                        |    |--Stream Aggregate(GROUP BY:([Expr1038], [Expr1039], [Expr1040], [Expr1041], [Expr1042]) DEFINE:([Expr1043]=SUM(isnull([Expr1017],(0.000))+isnull([Expr1036],(0.000))), [Expr1044]=SUM(isnull([Expr1018],($0.0000))+isnull([Expr1037],($0.0000)))))
                                                                        |         |--Sort(ORDER BY:([Expr1038] ASC, [Expr1039] ASC, [Expr1040] ASC, [Expr1041] ASC, [Expr1042] ASC))
                                                                        |              |--Compute Scalar(DEFINE:([Expr1038]=isnull([Expr1013],[Expr1032]), [Expr1039]=isnull([Expr1012],[Expr1031]), [Expr1040]=isnull([Expr1014],[Expr1033]), [Expr1041]=isnull([Expr1015],[Expr1034]), [Expr1042]=isnull([Expr1016],[Expr1035])))
                                                                        |                   |--Concatenation
                                                                        |                        |--Nested Loops(Left Outer Join, OUTER REFERENCES:([пдт].[Склад], [пдт].[Товар], [пдт].[ИдТипаДокаПартии], [пдт].[КодДокаПартии], [пдт].[НомерПартии]))
                                                                        |                        |    |--Table Spool
                                                                        |                        |    |    |--Compute Scalar(DEFINE:([пдт].[Склад]=[Звездный].[dbo].[пГДвиженияТоваров].[Склад] as [пдт].[Склад], [пдт].[Товар]=[Звездный].[dbo].[пГДвиженияТоваров].[Товар] as [пдт].[Товар], [пдт].[ИдТипаДокаПартии]=[Звездный].[dbo].[пГДвиженияТоваров].[ИдТипаДокаПартии] as [пдт].[ИдТипаДокаПартии], [пдт].[КодДокаПартии]=[Звездный].[dbo].[пГДвиженияТоваров].[КодДокаПартии] as [пдт].[КодДокаПартии], [пдт].[НомерПартии]=[Звездный].[dbo].[пГДвиженияТоваров].[НомерПартии] as [пдт].[НомерПартии], [Expr1010]=[Expr1010], [Expr1011]=[Expr1011]))
                                                                        |                        |    |         |--Compute Scalar(DEFINE:([Expr1010]=CASE WHEN [Expr1075]=(0) THEN NULL ELSE [Expr1076] END, [Expr1011]=CASE WHEN [Expr1077]=(0) THEN NULL ELSE [Expr1078] END))
                                                                        |                        |    |              |--Stream Aggregate(GROUP BY:([пдт].[Склад], [пдт].[Товар], [пдт].[ИдТипаДокаПартии], [пдт].[КодДокаПартии], [пдт].[НомерПартии]) DEFINE:([Expr1075]=COUNT_BIG([Звездный].[dbo].[пГДвиженияТоваров].[ДвижениеОстатка] as [пдт].[ДвижениеОстатка]), [Expr1076]=SUM([Звездный].[dbo].[пГДвиженияТоваров].[ДвижениеОстатка] as [пдт].[ДвижениеОстатка]), [Expr1077]=COUNT_BIG([Звездный].[dbo].[пГДвиженияТоваров].[ДвижениеСебест] as [пдт].[ДвижениеСебест]), [Expr1078]=SUM([Звездный].[dbo].[пГДвиженияТоваров].[ДвижениеСебест] as [пдт].[ДвижениеСебест])))
                                                                        |                        |    |                   |--Sort(DISTINCT ORDER BY:([пдт].[Склад] ASC, [пдт].[Товар] ASC, [пдт].[ИдТипаДокаПартии] ASC, [пдт].[КодДокаПартии] ASC, [пдт].[НомерПартии] ASC, [пдт].[Квартал] ASC, [пдт].[флНПвСебест] ASC, [пдт].[СтавкаНДСвСебест] ASC))
                                                                        |                        |    |                        |--Nested Loops(Left Semi Join, WHERE:(@тСкладыУчастники.[Склад] as [с].[Склад]=[Звездный].[dbo].[пГДвиженияТоваров].[Склад] as [пдт].[Склад]))
                                                                        |                        |    |                             |--Nested Loops(Inner Join, OUTER REFERENCES:([гмм].[Товар], [Expr1074]) OPTIMIZED WITH UNORDERED PREFETCH)
                                                                        |                        |    |                             |    |--Nested Loops(Inner Join, OUTER REFERENCES:([вгт].[Группа]))
                                                                        |                        |    |                             |    |    |--Clustered Index Scan(OBJECT:(@ВеткаГруппТоваров AS [вгт]))
                                                                        |                        |    |                             |    |    |--Clustered Index Seek(OBJECT:([Звездный].[dbo].[ТоварыГруппыММ].[кпк_ТоварыГруппыММ.Группа.Товар] AS [гмм]), SEEK:([гмм].[Группа]=@ВеткаГруппТоваров.[Группа] as [вгт].[Группа]) ORDERED FORWARD)
                                                                        |                        |    |                             |    |--Index Seek(OBJECT:([Звездный].[dbo].[пГДвиженияТоваров].[инд_пГДвиженияТоваров.Товар.Квартал.Склад] AS [пдт]), SEEK:([пдт].[Товар]=[Звездный].[dbo].[ТоварыГруппыММ].[Товар] as [гмм].[Товар] AND [пдт].[Квартал] <= [@Квартал]),  WHERE:([Звездный].[dbo].[пГДвиженияТоваров].[Товар] as [пдт].[Товар]=[@Товар] OR [@Товар] IS NULL) ORDERED FORWARD)
                                                                        |                        |    |                             |--Clustered Index Scan(OBJECT:(@тСкладыУчастники AS [с]))
                                                                        |                        |    |--Filter(WHERE:([Звездный].[dbo].[пГДвиженияТоваров].[Товар] as [пдт].[Товар]=[Звездный].[dbo].[ДвиженияТоваров].[Товар] as [дт].[Товар] AND [Звездный].[dbo].[пГДвиженияТоваров].[Склад] as [пдт].[Склад]=[Звездный].[dbo].[ДвиженияТоваров].[Склад] as [дт].[Склад] AND [Звездный].[dbo].[пГДвиженияТоваров].[ИдТипаДокаПартии] as [пдт].[ИдТипаДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[ИдТипаДокаПартии] as [дт].[ИдТипаДокаПартии] AND [Звездный].[dbo].[пГДвиженияТоваров].[КодДокаПартии] as [пдт].[КодДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[КодДокаПартии] as [дт].[КодДокаПартии] AND [Звездный].[dbo].[пГДвиженияТоваров].[НомерПартии] as [пдт].[НомерПартии]=[Звездный].[dbo].[ДвиженияТоваров].[НомерПартии] as [дт].[НомерПартии]))
                                                                        |                        |         |--Table Spool
                                                                        |                        |              |--Compute Scalar(DEFINE:([дт].[Склад]=[Звездный].[dbo].[ДвиженияТоваров].[Склад] as [дт].[Склад], [дт].[Товар]=[Звездный].[dbo].[ДвиженияТоваров].[Товар] as [дт].[Товар], [дт].[ИдТипаДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[ИдТипаДокаПартии] as [дт].[ИдТипаДокаПартии], [дт].[КодДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[КодДокаПартии] as [дт].[КодДокаПартии], [дт].[НомерПартии]=[Звездный].[dbo].[ДвиженияТоваров].[НомерПартии] as [дт].[НомерПартии], [Expr1029]=[Expr1029], [Expr1030]=[Expr1030]))
                                                                        |                        |                   |--Stream Aggregate(GROUP BY:([дт].[Склад], [дт].[Товар], [дт].[ИдТипаДокаПартии], [дт].[КодДокаПартии], [дт].[НомерПартии]) DEFINE:([Expr1029]=SUM([Звездный].[dbo].[ДвиженияТоваров].[ДвижениеОстатка] as [дт].[ДвижениеОстатка]), [Expr1030]=SUM([Звездный].[dbo].[ДвиженияТоваров].[ДвижениеСебест] as [дт].[ДвижениеСебест])))
                                                                        |                        |                        |--Sort(DISTINCT ORDER BY:([дт].[Склад] ASC, [дт].[Товар] ASC, [дт].[ИдТипаДокаПартии] ASC, [дт].[КодДокаПартии] ASC, [дт].[НомерПартии] ASC, [дт].[ИдДвижения] ASC))
                                                                        |                        |                             |--Nested Loops(Left Semi Join, WHERE:(@тСкладыУчастники.[Склад] as [с].[Склад]=[Звездный].[dbo].[ДвиженияТоваров].[Склад] as [дт].[Склад]))
                                                                        |                        |                                  |--Nested Loops(Inner Join, OUTER REFERENCES:([гмм].[Товар], [Expr1079]) OPTIMIZED WITH UNORDERED PREFETCH)
                                                                        |                        |                                  |    |--Nested Loops(Inner Join, OUTER REFERENCES:([вгт].[Группа]))
                                                                        |                        |                                  |    |    |--Clustered Index Scan(OBJECT:(@ВеткаГруппТоваров AS [вгт]))
                                                                        |                        |                                  |    |    |--Clustered Index Seek(OBJECT:([Звездный].[dbo].[ТоварыГруппыММ].[кпк_ТоварыГруппыММ.Группа.Товар] AS [гмм]), SEEK:([гмм].[Группа]=@ВеткаГруппТоваров.[Группа] as [вгт].[Группа]) ORDERED FORWARD)
                                                                        |                        |                                  |    |--Index Seek(OBJECT:([Звездный].[dbo].[ДвиженияТоваров].[инд_ДвиженияТоваров.Товар.Склад.ТочкаВремени..ХХХ] AS [дт]), SEEK:([дт].[Товар]=[Звездный].[dbo].[ТоварыГруппыММ].[Товар] as [гмм].[Товар]),  WHERE:([Звездный].[dbo].[ДвиженияТоваров].[ТочкаВремени] as [дт].[ТочкаВремени]>=[@ТочкаРаздела] AND [Звездный].[dbo].[ДвиженияТоваров].[ТочкаВремени] as [дт].[ТочкаВремени]<[@НаДату] AND ([Звездный].[dbo].[ДвиженияТоваров].[Товар] as [дт].[Товар]=[@Товар] OR [@Товар] IS NULL)) ORDERED FORWARD)
                                                                        |                        |                                  |--Clustered Index Scan(OBJECT:(@тСкладыУчастники AS [с]))
                                                                        |                        |--Compute Scalar(DEFINE:([Expr1012]=NULL, [Expr1013]=NULL, [Expr1014]=NULL, [Expr1015]=NULL, [Expr1016]=NULL, [Expr1017]=NULL, [Expr1018]=NULL))
                                                                        |                             |--Hash Match(Right Anti Semi Join, HASH:([пдт].[Товар], [пдт].[Склад], [пдт].[ИдТипаДокаПартии], [пдт].[КодДокаПартии], [пдт].[НомерПартии])=([дт].[Товар], [дт].[Склад], [дт].[ИдТипаДокаПартии], [дт].[КодДокаПартии], [дт].[НомерПартии]), RESIDUAL:([Звездный].[dbo].[пГДвиженияТоваров].[Товар] as [пдт].[Товар]=[Звездный].[dbo].[ДвиженияТоваров].[Товар] as [дт].[Товар] AND [Звездный].[dbo].[пГДвиженияТоваров].[Склад] as [пдт].[Склад]=[Звездный].[dbo].[ДвиженияТоваров].[Склад] as [дт].[Склад] AND [Звездный].[dbo].[пГДвиженияТоваров].[ИдТипаДокаПартии] as [пдт].[ИдТипаДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[ИдТипаДокаПартии] as [дт].[ИдТипаДокаПартии] AND [Звездный].[dbo].[пГДвиженияТоваров].[КодДокаПартии] as [пдт].[КодДокаПартии]=[Звездный].[dbo].[ДвиженияТоваров].[КодДокаПартии] as [дт].[КодДокаПартии] AND [Звездный].[dbo].[пГДвиженияТоваров].[НомерПартии] as [пдт].[НомерПартии]=[Звездный].[dbo].[ДвиженияТоваров].[НомерПартии] as [дт].[НомерПартии]))
                                                                        |                                  |--Table Spool
                                                                        |                                  |--Table Spool
                                                                        |--Clustered Index Seek(OBJECT:([Звездный].[dbo].[Товары].[кпк_Товары.Код] AS [т]), SEEK:([т].[Код]=[Expr1038]),  WHERE:([Звездный].[dbo].[Товары].[флУпрУчет] as [т].[флУпрУчет]=[@ТипУчета] OR [@ТипУчета] IS NULL) ORDERED FORWARD)



К сожалению, в удобочитаемом виде не получается — картинка не вмещается в монитор, а сам сохранить сам план — русские буквы косячатся.
Re[29]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.07.09 05:12
Оценка:
Здравствуйте, _d_m_, Вы писали:
___>Если ты про = @Товар or @Товар is null, то он ваще не играет никакой роли. Писать отдельный запрос ради этого редкого частного случая смысла нет. Скорость приемлимая, и ради того чтобы юзер ждал 1 секунду вместо 5... оно того не стоит.
Ну ок. Вас всё устраивает — не мне вас учить программировать.
Но не удивляйтесь, когда кто-то другой будет добиваться "приемлимой" скорости не многократными экспериментами и тяжкими усилиями, а просто наколбасит запрос на линке, и всё взлетит с первого раза.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[41]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.07.09 05:15
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, Воронков Василий, Вы писали:


G>>>И достигнуть этого можно двумя способами.

G>>>1)Перенести всю BL на SQL, что практически смертельно в случае смены БД, так как придется перекраивать кучу кода.
G>>>2)Использовать правильные инструменты для работы с БД, которые позволяют BL абстрагировать от хранилища, тогда и смена БД пройдет гладко.

ВВ>>Для тех в танке повторяю — вынесение BL из БД вовсе не означает "легкости смены СУБД", если, конечно же, речь не идет о хоум-пейджах.


I>Не спорь с ним, он сикп освоил


Завидуешь?
Re[42]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.07.09 05:17
Оценка:
Здравствуйте, iHateLogins, Вы писали:

HL>Здравствуйте, gandjustas, Вы писали:


G>>Еще раз: главное абстрагировать BL от хранилища.


HL>Как вам другая задача: абстрагировать BL от языка программирования. Возьмётесь?


В буржуйляндии забористая трава, однако.
Re[30]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: _d_m_  
Дата: 01.07.09 05:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, _d_m_, Вы писали:

___>>Если ты про = @Товар or @Товар is null, то он ваще не играет никакой роли. Писать отдельный запрос ради этого редкого частного случая смысла нет. Скорость приемлимая, и ради того чтобы юзер ждал 1 секунду вместо 5... оно того не стоит.
S>Ну ок. Вас всё устраивает — не мне вас учить программировать.
S>Но не удивляйтесь, когда кто-то другой будет добиваться "приемлимой" скорости не многократными экспериментами и тяжкими усилиями, а просто наколбасит запрос на линке, и всё взлетит с первого раза.

Да не вопрос. Начинать новый проект — linq в руки и вперед. Но переписывать проект начатый в 2001 году мы не станем.
Re[31]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.07.09 06:03
Оценка: +4
Здравствуйте, _d_m_, Вы писали:
___>Да не вопрос. Начинать новый проект — linq в руки и вперед. Но переписывать проект начатый в 2001 году мы не станем.
Еще раз: никто вас не уговаривает переписывать работающий восход с закатом. Напомню, что вы пытаетесь убедить нас, что и в новых проектах вот эти ваши дорогостоящие приседания на неприспособленном для программирования языке и есть руль. А линк — так, погулять вышел. Вот это и есть основное заблуждение.

Заранее хочу оговориться, а то в таких религиозных спорах часто приходится занимать несколько утрированную позицию: я не считаю конкретную реализацию Link2Sql панацеей. Она страдает множеством недостатков; и особо смелые парни из числа опытных собаководов сейчас полощут мозг команде авторов Linq на тему "вы всё сделали не так, иначе бы провайдер линка было бы легко написать". Но сам подход линка к решению задачи значительно лучше, чем подход T-SQL.

Понимаете, было время, когда опытные ассемблерщики смеялись над, скажем, С++. "Что он вам там наоптимизирует? Я вот заколбашу здесь rep scansd — и всё полетит, а где оно в C++?".
Но годы шли; смех сильно поутих после того, как оказалось, что и rep scansd, и прочее вполне себе подвластно компилятору. Более того, смеяться стали программисты на C++ — потому что они натравили новые компиляторы на старые программы и получили 150% прироста производительности. А ассемблерный код как был оптимальным для 80386, так для него оптимальным и остался. Отдельные кадры из числа особо упёртых продолжали смеяться над "корявым кодом", который генерировали компиляторы, даже в 2005 году. Лица этих отдельных кадров сильно вытягивались после просмотра результатов забега "корявого" кода под профайлером — rep scansd сливал. Оказалось, что Intel C/C++ Compiler знает об особенностях потрошков современных CPU немножко больше, чем среднестатистический ассемблерщик.

Такая же штука ожидает нас и в SQL. Понимаете, SQL — это ассемблер. Есть оптимизации, которые SQL Server не проводит и никогда не будет проводить. В простых случаях он справляется очень хорошо; но и ассемблер в простых случаях инкрементирует каунтер не шибко плохо. Но в сложных случаях руки оптимизатора связаны тем уровнем семантики, который ему видим. И в этом смысле линк позволяет развязать смысловую составляющую запроса и те кирпичики, из которых он сделан.

Классический пример — Skip(m).Take(n). Запрос, который вы нарулите вручную для MS SQL 2000, уже не будет самым эффективным на MS SQL 2005. И MS SQL 2005 не станет за вас переписывать его на оконные функции. А вот линк — станет. Потому, что линк видит суть запроса, а не нагромождение select top from select top.

И таких примеров в реальной жизни — очень и очень много. Вот вы помянули RLS. Очень часто в RLS есть режим "администратора", который типа видит всё. В классике вы будете делать джойн с таблицей ACL, оборудованный чем-то типа OR @userLevel == Admin. И сиквел будет честно сканировать ACL, просаживая производительность на порядок. А на linq приджойнивание ACL таблицы будет происходить в динамике, в зависимости от уровня доступа. И ненужные подзапросы даже не будут генерироваться.

В итоге, чем сложнее логика запроса — тем сильнее в нём будет рулить Linq. Вы совершенно напрасно пытаетесь показать те примеры, для которых линк и изобретался. Убийцы линка — это "простые" запросы, которые не пролезают через провайдера. Типа CTE. Вот в них можно положить линк на лопатки путём ручного кодирования.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Юнит-тесты: пожалуй, лучше в "О жизни"
От: Константин Б. Россия  
Дата: 01.07.09 06:46
Оценка: :)
Здравствуйте, landerhigh, Вы писали:

L>Здравствуйте, iHateLogins, Вы писали:


HL>>или вот еще:

HL>>
HL>>[TestMethod]
HL>>public void TestCustomerObject()
HL>>{
HL>>   Customer c = new Customer();
HL>>   c.ID = 1;
HL>>   c.Name = "Vasya";
HL>>   c.Create();
HL>>   Customer c2 = GetCustomerByID(1);
HL>>   Assert.AreEqual(c.Name, c2.Name);
HL>>}
HL>>


L>Отлично.


L>1. Если конструктор Customer() кинет исключение, тест не пройдет.

L>2. Если Create() кинет исключение, тест не пройдет
L>3. Если GetCustomerById() вернет что-то отличное от ожидаемого, тест провалится.
L>4. Если впоследствии кто-то умный решит играться регистром имен в конструкторах, сеттерах или еще где, тест свалится

L>Нормальный тест.


Любой интеграционный тест использующий Customer и GetCustomerById проверит то же самое. Зачем отдельный юнит-тест?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.