powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Наши за рубежом [закрыт для гостей] / Что происходит на рынке DB вакансий в ЕС?
25 сообщений из 375, страница 15 из 15
Что происходит на рынке DB вакансий в ЕС?
    #21644891
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford 
Да, именно про стоимостную оптимизацию и говорю. Видимо нужен пример т.к. ходит кругами

Например для простоты возьмем такой:
Код
1.
2.
3.
4.
5.
6.
select Postcode from dbo.Cities
where Name = 'Moscow'
union
select Postode from dbo.Cities a
join dbo.Streets b on a.StreetId = b.StreetId
where b.StreetName = 'Rare street'
Предлополжим, что первая часть запроса...
Если бы у бабушки были...

Конечно, оптимизаторы, бывает, ошибаются. На моей практике это происходит гораздо реже, чем не ошибаются.

Чаще всего ошибки связаны с тем, что от оптимизатора скрыли часть информации:
- старая/вообще несобранная статистика
- отсутствие информации об уникальности поля/набора полей
- не указана информация о зависимости между полями/таблицами (даже когда contraint'ы not forced, они дают очень важную задачу оптимизатору).

Вторая причина "плохого" плана - плохой физический дизайн.
- отсутствие нужного индекса
- отсутствие партиционирования там, где это надо
- отсутствие правильной упорядоченности данных (==колокации в страницах).
...

Далеко не самая последняя причина - _неверная_ логика запроса. Разновидность - запрос, использующий некоторые умолчания, известные программисту, де-факто наблюдаемые в данных, но не отражённые в логическом дизайне базы.

Чаще бывает наоборот - прибегает в мыле разработчик - "у вас база плохая! неправильный план генерит" (хорошо, когда про планы вообще знает). Тыкаешь его мордочкой, что нет, всё верно. Хотя вот лично мне приходилось регистрировать баги оптимизатора у вендора. Правили.
stenford 
Как вы-же совершенно правильно говорите, оптимизатор попытается схлопнуть оба запроса, и в итоге ...
Он попытается схлопнуть, когда это выгодно.
stenford 
... при использовании ORM таких запросов в общем случае не будет. Будет 2 разных метода, один на поиск по городам, другой - по улицам.
Это как раз то, про что вам говорили - вместо 1000 запросов будет 2000 запросов (например, в секунду). В два раза больше накладных расходов на коммуникацию (для коротких запросов - подчас самая затратная часть).
stenford 
В результате у меня будет один скан на города, и 3 джойна с индексами по улицам. В случае использования хранимки будет 3 скана со сравнением по каждой записи из таблицы с улицами.
С увеличением сложности запросов и хранимок разница будет только возрастать
Это обычное, но неверное убеждение, что "вот я то лучше построю план "руками", прямо указав, что делать сначала, что потом".
1. Оптимизатор часто обладает информацией, о которой вы и помыслить не можете.
2. Распределение данных в базу у разработчика может (обязательно будет!) отличаться от того, что имеем в продуктиве.
3. Самое главное, распределение имеет свойство изменяться со временем. Лет через 5 (10? больше?). Когда ваше приложение уже станет легаси, а вы уйдёте куда-нибудь заниматься более современными технологиями. Вот тогда, когда жёстко зашитый в приложение план станет катастрофически неэффективным, оно выстрелит, и наступит ...

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

Правильния работа с базой - одно логическое дейстивие/выборка - один запрос. Работать целиком с Data set'ами.
ОРМы часто толкают к нарушению этих принципов.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645760
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Megabyte 
Это в вашем случае использования ОРМ будет 2 отдельных запроса\метода, что как бы не очень хорошо!
это в случае одиночного вызова такой логики будет нехорошо. Я потому в примере и написал, что вызов идет для 3-х случаев с разными улицами. И нехорошо тут уже становится вашей хранимке))
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645782
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CawaSPb 
Конечно, оптимизаторы, бывает, ошибаются. На моей практике это происходит гораздо реже, чем не ошибаются.
мой поинт тут совсем не в ошибке оптимизатора, мы предполагаем что оптимизатор как-раз сделал свою работу хорошо и для введенных параметров выбрал нужный план. Беда не в оптимизаторе, а в параметре, который вызвал скан. План-то для скана корректный. Но он закэшировался, и теперь каждый последующий вызов идет со сканом
CawaSPb 
Это как раз то, про что вам говорили - вместо 1000 запросов будет 2000 запросов (например, в секунду). В два раза больше накладных расходов на коммуникацию (для коротких запросов - подчас самая затратная часть).
у меня будет 1 скан (с соединениями по улицам) + 2000 запросов на улицы, где будет простой джойн за пару миллисекунд, а у вас - 1000 сканов таблицы. А в ней может с пару десятков лямов записей лежать. Действительно будете озабочены расходами на коммуникацию?
CawaSPb 
Это обычное, но неверное убеждение, что "вот я то лучше построю план "руками", прямо указав, что делать сначала, что потом".
1. Оптимизатор часто обладает информацией, о которой вы и помыслить не можете.
2. Распределение данных в базу у разработчика может (обязательно будет!) отличаться от того, что имеем в продуктиве.
3. Самое главное, распределение имеет свойство изменяться со временем. Лет через 5 (10? больше?). Когда ваше приложение уже станет легаси, а вы уйдёте куда-нибудь заниматься более современными технологиями. Вот тогда, когда жёстко зашитый в приложение план станет катастрофически неэффективным, оно выстрелит, и наступит ...

Правильния работа с базой - одно логическое дейстивие/выборка - один запрос. Работать целиком с Data set'ами.
ОРМы часто толкают к нарушению этих принципов.
ORM'ы не строят планы "руками", и никуда его не "зашивают". Они вызывают мелкие точечные запросы, которые обычно весьма эффективны. А вот громозкие хранимки начинают страдать от ожирения плана, их начинают подкручивать, оптимизировать и прочее что и дает повод иметь на окладе ДБА :)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645793
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CawaSPb 
Конечно, оптимизаторы, бывает, ошибаются. На моей практике это происходит гораздо реже, чем не ошибаются.

Чаще всего ошибки связаны с тем, что от оптимизатора скрыли часть информации:
- старая/вообще несобранная статистика
- отсутствие информации об уникальности поля/набора полей
- не указана информация о зависимости между полями/таблицами (даже когда contraint'ы not forced, они дают очень важную задачу оптимизатору).

Вторая причина "плохого" плана - плохой физический дизайн.
- отсутствие нужного индекса
- отсутствие партиционирования там, где это надо
- отсутствие правильной упорядоченности данных (==колокации в страницах).
...
Правильния работа с базой - одно логическое дейстивие/выборка - один запрос. Работать целиком с Data set'ами.
ОРМы часто толкают к нарушению этих принципов.
+100500
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645808
Фотография Megabyte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford 
ORM'ы не строят планы "руками", и никуда его не "зашивают". Они вызывают мелкие точечные запросы, которые обычно весьма эффективны.
Улыбнули. :)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645847
sti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Цитата 
... мелкие точечные запросы...
Спойлер
(@p__linq__0 int,@p__linq__1 uniqueidentifier,@p__linq__2 nvarchar(4000),@p__linq__3 nvarchar(4000),@p__linq__5 nvarchar(4000),@p__linq__4 nvarchar(4000),@p__linq__6 nvarchar(4000),@p__linq__7 nvarchar(4000),@p__linq__8 nvarchar(4000),@p__linq__9 nvarchar(4000),@p__linq__10 nvarchar(4000),@p__linq__11 nvarchar(4000),@p__linq__12 nvarchar(4000),@p__linq__13 nvarchar(4000),@p__linq__14 nvarchar(4000),@p__linq__15 nvarchar(4000),@p__linq__16 uniqueidentifier,@p__linq__17 uniqueidentifier,@p__linq__18 uniqueidentifier,@p__linq__19 uniqueidentifier,@p__linq__20 uniqueidentifier)
SELECT
[UnionAll8].[Id] AS [C1],
[UnionAll8].[Id1] AS [C2],
[UnionAll8].[Id2] AS [C3],
[UnionAll8].[Id3] AS [C4],
[UnionAll8].[Id4] AS [C5],
[UnionAll8].[Id5] AS [C6],
[UnionAll8].[Id6] AS [C7],
[UnionAll8].[Id7] AS [C8],
[UnionAll8].[Id8] AS [C9],
[UnionAll8].[C2] AS [C10],
[UnionAll8].[Number] AS [C11],
[UnionAll8].[C3] AS [C12],
[UnionAll8].[C4] AS [C13],
[UnionAll8].[C5] AS [C14],
[UnionAll8].[C6] AS [C15],
[UnionAll8].[C7] AS [C16],
[UnionAll8].[C8] AS [C17],
[UnionAll8].[C9] AS [C18],
[UnionAll8].[C10] AS [C19],
[UnionAll8].[Number1] AS [C20],
[UnionAll8].[C11] AS [C21],
[UnionAll8].[Value] AS [C22],
[UnionAll8].[C12] AS [C23],
[UnionAll8].[Value1] AS [C24],
[UnionAll8].[C13] AS [C25],
[UnionAll8].[C14] AS [C26],
[UnionAll8].[Number2] AS [C27],
[UnionAll8].[Number3] AS [C28],
[UnionAll8].[FirstName] AS [C29],
[UnionAll8].[MiddleName] AS [C30],
[UnionAll8].[LastName] AS [C31],
[UnionAll8].[C15] AS [C32],
[UnionAll8].[C16] AS [C33],
[UnionAll8].[BirthDate] AS [C34],
[UnionAll8].[C17] AS [C35],
[UnionAll8].[C18] AS [C36],
[UnionAll8].[C1] AS [C37],
[UnionAll8].[C19] AS [C38],
[UnionAll8].[BirthDate1] AS [C39],
[UnionAll8].[C20] AS [C40],
[UnionAll8].[FirstName1] AS [C41],
[UnionAll8].[LastName1] AS [C42],
[UnionAll8].[C21] AS [C43],
[UnionAll8].[C22] AS [C44],
[UnionAll8].[C23] AS [C45],
[UnionAll8].[C24] AS [C46],
[UnionAll8].[C25] AS [C47],
[UnionAll8].[C26] AS [C48],
[UnionAll8].[C27] AS [C49],
[UnionAll8].[C28] AS [C50],
[UnionAll8].[C29] AS [C51],
[UnionAll8].[C30] AS [C52],
[UnionAll8].[C31] AS [C53],
[UnionAll8].[C32] AS [C54],
[UnionAll8].[C33] AS [C55],
[UnionAll8].[C34] AS [C56],
[UnionAll8].[C35] AS [C57],
[UnionAll8].[C36] AS [C58],
[UnionAll8].[C37] AS [C59],
[UnionAll8].[C38] AS [C60],
[UnionAll8].[C39] AS [C61],
[UnionAll8].[C40] AS [C62],
[UnionAll8].[C41] AS [C63],
[UnionAll8].[C42] AS [C64],
[UnionAll8].[C43] AS [C65],
[UnionAll8].[C44] AS [C66],
[UnionAll8].[C45] AS [C67],
[UnionAll8].[C46] AS [C68],
[UnionAll8].[C47] AS [C69],
[UnionAll8].[C48] AS [C70],
[UnionAll8].[C49] AS [C71],
[UnionAll8].[C50] AS [C72],
[UnionAll8].[C51] AS [C73],
[UnionAll8].[C52] AS [C74],
[UnionAll8].[C53] AS [C75],
[UnionAll8].[C54] AS [C76],
[UnionAll8].[C55] AS [C77],
[UnionAll8].[C56] AS [C78],
[UnionAll8].[C57] AS [C79],
[UnionAll8].[C58] AS [C80],
[UnionAll8].[C59] AS [C81],
[UnionAll8].[C60] AS [C82],
[UnionAll8].[C61] AS [C83],
[UnionAll8].[C62] AS [C84],
[UnionAll8].[C63] AS [C85],
[UnionAll8].[C64] AS [C86],
[UnionAll8].[C65] AS [C87],
[UnionAll8].[C66] AS [C88],
[UnionAll8].[C67] AS [C89]
FROM (SELECT
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Project12].[Id1] AS [Id],
[Project12].[Id2] AS [Id1],
[Project12].[Id3] AS [Id2],
[Project12].[Id4] AS [Id3],
[Project12].[Id5] AS [Id4],
[Project12].[Id6] AS [Id5],
[Project12].[Id7] AS [Id6],
[Project12].[Id8] AS [Id7],
[Project12].[Id] AS [Id8],
[Project12].[C2] AS [C2],
[Project12].[Number] AS [Number],
CASE WHEN ([Project12].[isDeleted] = 1) THEN N'Delete' ELSE N'Insert' END AS [C3],
N'DE' AS [C4],
@p__linq__6 AS [C5],
N'Individual' AS [C6],
@p__linq__7 AS [C7],
@p__linq__8 AS [C8],
CASE WHEN ([Project12].[isDeleted] = 1) THEN N'Inactive' ELSE N'Active' END AS [C9],
[Project12].[C1] AS [C10],
[Project12].[Number] AS [Number1],
CASE WHEN ([Project12].[Value] IS NOT NULL) THEN N'STO' END AS [C11],
[Project12].[Value] AS [Value],
CASE WHEN ([Project12].[Value1] IS NOT NULL) THEN N'STO' END AS [C12],
[Project12].[Value1] AS [Value1],
CAST( [Project12].[CreateDate] AS datetime2) AS [C13],
CAST( [Project12].[LastChange] AS datetime2) AS [C14],
[Project12].[Number] AS [Number2],
[Project12].[Number] AS [Number3],
[Project12].[FirstName] AS [FirstName],
[Project12].[MiddleName] AS [MiddleName],
[Project12].[LastName] AS [LastName],
CASE WHEN (N'F' = [Project12].[Gender]) THEN N'FEMALE' WHEN (N'M' = [Project12].[Gender]) THEN N'MALE' ELSE N'NOTSET' END AS [C15],
CASE WHEN (@p__linq__9 = N'AT' OR [Project12].[Title] IN (N'Dr.',N'Prof.',N'Prof. Dr.')) THEN [Project12].[Title] END AS [C16],
[Project12].[BirthDate] AS [BirthDate],
CAST( [Project12].[CreateDate] AS datetime2) AS [C17],
CAST( [Project12].[LastChange] AS datetime2) AS [C18],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C19],
[Join7].[BirthDate] AS [BirthDate1],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS varchar(1)) WHEN (N'M' = [Join7].[Gender]) THEN N'MALE' WHEN (N'F' = [Join7].[Gender]) THEN N'FEMALE' ELSE N'NOTSET' END AS [C20],
[Join7].[FirstName] AS [FirstName1],
[Join7].[LastName] AS [LastName1],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS datetime2) ELSE CAST( [Join7].[LastChange] AS datetime2) END AS [C21],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS datetime2) ELSE CAST( [Join7].[CreateDate] AS datetime2) END AS [C22],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS varchar(1)) WHEN ([Join7].[BirthDate] IS NOT NULL) THEN CAST( DATEPART (year, [Join7].[BirthDate]) AS nvarchar(max)) END AS [C23],
CASE WHEN ([Join7].[FK_CustomerId] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE N'UNKNOWN' END AS [C24],
CAST(NULL AS uniqueidentifier) AS [C25],
CAST(NULL AS uniqueidentifier) AS [C26],
CAST(NULL AS int) AS [C27],
CAST(NULL AS varchar(1)) AS [C28],
CAST(NULL AS varchar(1)) AS [C29],
CAST(NULL AS varchar(1)) AS [C30],
CAST(NULL AS varchar(1)) AS [C31],
CAST(NULL AS varchar(1)) AS [C32],
CAST(NULL AS varchar(1)) AS [C33],
CAST(NULL AS varchar(1)) AS [C34],
CAST(NULL AS varchar(1)) AS [C35],
CAST(NULL AS datetime2) AS [C36],
CAST(NULL AS datetime2) AS [C37],
CAST(NULL AS uniqueidentifier) AS [C38],
CAST(NULL AS uniqueidentifier) AS [C39],
CAST(NULL AS int) AS [C40],
CAST(NULL AS int) AS [C41],
CAST(NULL AS varchar(1)) AS [C42],
CAST(NULL AS datetime2) AS [C43],
CAST(NULL AS datetime2) AS [C44],
CAST(NULL AS int) AS [C45],
CAST(NULL AS varchar(1)) AS [C46],
CAST(NULL AS varchar(1)) AS [C47],
CAST(NULL AS datetime2) AS [C48],
CAST(NULL AS datetime2) AS [C49],
CAST(NULL AS int) AS [C50],
CAST(NULL AS varchar(1)) AS [C51],
CAST(NULL AS varchar(1)) AS [C52],
CAST(NULL AS datetime2) AS [C53],
CAST(NULL AS datetime2) AS [C54],
CAST(NULL AS int) AS [C55],
CAST(NULL AS int) AS [C56],
CAST(NULL AS varchar(1)) AS [C57],
CAST(NULL AS datetime2) AS [C58],
CAST(NULL AS datetime2) AS [C59],
CAST(NULL AS int) AS [C60],
CAST(NULL AS varchar(1)) AS [C61],
CAST(NULL AS varchar(1)) AS [C62],
CAST(NULL AS int) AS [C63],
CAST(NULL AS varchar(1)) AS [C64],
CAST(NULL AS varchar(1)) AS [C65],
CAST(NULL AS datetime2) AS [C66],
CAST(NULL AS datetime2) AS [C67]
FROM (SELECT
[Project10].[Id] AS [Id],
[Project10].[Number] AS [Number],
[Project10].[FirstName] AS [FirstName],
[Project10].[MiddleName] AS [MiddleName],
[Project10].[LastName] AS [LastName],
[Project10].[Gender] AS [Gender],
[Project10].[Title] AS [Title],
[Project10].[BirthDate] AS [BirthDate],
[Project10].[isDeleted] AS [isDeleted],
[Project10].[CreateDate] AS [CreateDate],
[Project10].[LastChange] AS [LastChange],
[Project10].[Id1] AS [Id1],
[Project10].[Id2] AS [Id2],
[Project10].[Id3] AS [Id3],
[Project10].[Value] AS [Value],
[Project10].[Id4] AS [Id4],
[Project10].[Id5] AS [Id5],
[Project10].[Id6] AS [Id6],
[Project10].[Value1] AS [Value1],
[Project10].[Id7] AS [Id7],
[Project10].[Id8] AS [Id8],
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[CustomerParameter] AS [Extent11]
INNER JOIN [dbo].[Parameter] AS [Extent12] ON [Extent11].[FK_ParameterId] = [Extent12].[Id]
WHERE ([Project10].[Id] = [Extent11].[FK_CustomerId]) AND ([Extent12]. = @p__linq__4) )) THEN [Project10].[CustomValue] END AS [C1], [Project10].[C1] AS [C2] FROM ( SELECT [Project8].[Id] AS [Id], [Project8].[Number] AS [Number], [Project8].[FirstName] AS [FirstName], [Project8].[MiddleName] AS [MiddleName], [Project8].[LastName] AS [LastName], [Project8].[Gender] AS [Gender], [Project8].[Title] AS [Title], [Project8].[BirthDate] AS [BirthDate], [Project8].[isDeleted] AS [isDeleted], [Project8].[CreateDate] AS [CreateDate], [Project8].[LastChange] AS [LastChange], [Project8].[Id1] AS [Id1], [Project8].[Id2] AS [Id2], [Project8].[Id3] AS [Id3], [Project8].[Value] AS [Value], [Project8].[Id4] AS [Id4], [Project8].[Id5] AS [Id5], [Project8].[Id6] AS [Id6], [Project8].[Value1] AS [Value1], [Limit4].[Id] AS [Id7], [Limit4].[CustomValue] AS [CustomValue], [Limit4].[Id1] AS [Id8], [Project8].[C1] AS [C1] FROM (SELECT [Project6].[Id] AS [Id], [Project6].[Number] AS [Number], [Project6].[FirstName] AS [FirstName], [Project6].[MiddleName] AS [MiddleName], [Project6].[LastName] AS [LastName], [Project6].[Gender] AS [Gender], [Project6].[Title] AS [Title], [Project6].[BirthDate] AS [BirthDate], [Project6].[isDeleted] AS [isDeleted], [Project6].[CreateDate] AS [CreateDate], [Project6].[LastChange] AS [LastChange], [Project6].[Id1] AS [Id1], [Project6].[Id2] AS [Id2], [Project6].[Id3] AS [Id3], [Project6].[Value] AS [Value], [Limit3].[Id] AS [Id4], [Limit3].[Id1] AS [Id5], [Limit3].[Id2] AS [Id6], [Limit3].[Value] AS [Value1], [Project6].[C1] AS [C1] FROM (SELECT [Project4].[Id] AS [Id], [Project4].[Number] AS [Number], [Project4].[FirstName] AS [FirstName], [Project4].[MiddleName] AS [MiddleName], [Project4].[LastName] AS [LastName], [Project4].[Gender] AS [Gender], [Project4].[Title] AS [Title], [Project4].[BirthDate] AS [BirthDate], [Project4].[isDeleted] AS [isDeleted], [Project4].[CreateDate] AS [CreateDate], [Project4].[LastChange] AS [LastChange], [Limit2].[Id] AS [Id1], [Limit2].[Id1] AS [Id2], [Limit2].[Id2] AS [Id3], [Limit2].[Value] AS [Value], [Project4].[C1] AS [C1] FROM (SELECT [Project3].[Id] AS [Id], [Project3].[Number] AS [Number], [Project3].[FirstName] AS [FirstName], [Project3].[MiddleName] AS [MiddleName], [Project3].[LastName] AS [LastName], [Project3].[Gender] AS [Gender], [Project3].[Title] AS [Title], [Project3].[BirthDate] AS [BirthDate], [Project3].[isDeleted] AS [isDeleted], [Project3].[CreateDate] AS [CreateDate], [Project3].[LastChange] AS [LastChange], [Project3].[C1] AS [C1] FROM ( SELECT [Project1].[Id] AS [Id], [Project1].[Number] AS [Number], [Project1].[FirstName] AS [FirstName], [Project1].[MiddleName] AS [MiddleName], [Project1].[LastName] AS [LastName], [Project1].[Gender] AS [Gender], [Project1].[Title] AS [Title], [Project1].[BirthDate] AS [BirthDate], [Project1].[isDeleted] AS [isDeleted], [Project1].[CreateDate] AS [CreateDate], [Project1].[LastChange] AS [LastChange], (SELECT TOP (1) [Extent2].[Id] AS [Id] FROM [dbo].[CustomerProgram] AS [Extent2] WHERE (0 = [Extent2].[isDeleted]) AND ([Project1].[Id] = [Extent2].[FK_CustomerId]) AND (@p__linq__1 = [Extent2].[FK_ProgramId])) AS [C1] FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Number] AS [Number], [Extent1].[FirstName] AS [FirstName], [Extent1].[MiddleName] AS [MiddleName], [Extent1].[LastName] AS [LastName], [Extent1].[Gender] AS [Gender], [Extent1].[Title] AS [Title], [Extent1].[BirthDate] AS [BirthDate], [Extent1].[isDeleted] AS [isDeleted], [Extent1].[CreateDate] AS [CreateDate], [Extent1].[LastChange] AS [LastChange] FROM [dbo].[Customer] AS [Extent1] WHERE ( NOT (([Extent1].[isDeleted] = 1) AND (2 = @p__linq__0))) AND ([Extent1].[Id] IN (cast('08909057-84e7-4eb6-8c5b-580b4732c82a' as uniqueidentifier))) ) AS [Project1] ) AS [Project3] ) AS [Project4] OUTER APPLY (SELECT TOP (1) [Extent3].[Id] AS [Id], [Extent4].[Id] AS [Id1], [Extent5].[Id] AS [Id2], [Extent5].[Value] AS [Value] FROM [dbo].[CustomerParameter] AS [Extent3] INNER JOIN [dbo].[Parameter] AS [Extent4] ON [Extent3].[FK_ParameterId] = [Extent4].[Id] LEFT OUTER JOIN [dbo].[ParameterValue] AS [Extent5] ON [Extent3].[FK_ParameterValueId] = [Extent5].[Id] WHERE ([Project4].[Id] = [Extent3].[FK_CustomerId]) AND ([Extent4].[code] = @p__linq__2) ) AS [Limit2] ) AS [Project6] OUTER APPLY (SELECT TOP (1) [Extent6].[Id] AS [Id], [Extent7].[Id] AS [Id1], [Extent8].[Id] AS [Id2], [Extent8].[Value] AS [Value] FROM [dbo].[CustomerParameter] AS [Extent6] INNER JOIN [dbo].[Parameter] AS [Extent7] ON [Extent6].[FK_ParameterId] = [Extent7].[Id] LEFT OUTER JOIN [dbo].[ParameterValue] AS [Extent8] ON [Extent6].[FK_ParameterValueId] = [Extent8].[Id] WHERE ([Project6].[Id] = [Extent6].[FK_CustomerId]) AND ([Extent7].[code] = @p__linq__3) ) AS [Limit3] ) AS [Project8] OUTER APPLY (SELECT TOP (1) [Extent9].[Id] AS [Id], [Extent9].[FK_ParameterId] AS [FK_ParameterId], [Extent9].[CustomValue] AS [CustomValue], [Extent10].[Id] AS [Id1], [Extent10].[code] AS [code] FROM [dbo].[CustomerParameter] AS [Extent9] INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id] WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10].[code] = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code] = @p__linq__4)
)) THEN [Project10].[CustomValue] END AS [C1],
[Project10].[C1] AS [C2]
FROM ( SELECT
[Project8].[Id] AS [Id],
[Project8].[Number] AS [Number],
[Project8].[FirstName] AS [FirstName],
[Project8].[MiddleName] AS [MiddleName],
[Project8].[LastName] AS [LastName],
[Project8].[Gender] AS [Gender],
[Project8].[Title] AS [Title],
[Project8].[BirthDate] AS [BirthDate],
[Project8].[isDeleted] AS [isDeleted],
[Project8].[CreateDate] AS [CreateDate],
[Project8].[LastChange] AS [LastChange],
[Project8].[Id1] AS [Id1],
[Project8].[Id2] AS [Id2],
[Project8].[Id3] AS [Id3],
[Project8].[Value] AS [Value],
[Project8].[Id4] AS [Id4],
[Project8].[Id5] AS [Id5],
[Project8].[Id6] AS [Id6],
[Project8].[Value1] AS [Value1],
[Limit4].[Id] AS [Id7],
[Limit4].[CustomValue] AS [CustomValue],
[Limit4].[Id1] AS [Id8],
[Project8].[C1] AS [C1]
FROM (SELECT
[Project6].[Id] AS [Id],
[Project6].[Number] AS [Number],
[Project6].[FirstName] AS [FirstName],
[Project6].[MiddleName] AS [MiddleName],
[Project6].[LastName] AS [LastName],
[Project6].[Gender] AS [Gender],
[Project6].[Title] AS [Title],
[Project6].[BirthDate] AS [BirthDate],
[Project6].[isDeleted] AS [isDeleted],
[Project6].[CreateDate] AS [CreateDate],
[Project6].[LastChange] AS [LastChange],
[Project6].[Id1] AS [Id1],
[Project6].[Id2] AS [Id2],
[Project6].[Id3] AS [Id3],
[Project6].[Value] AS [Value],
[Limit3].[Id] AS [Id4],
[Limit3].[Id1] AS [Id5],
[Limit3].[Id2] AS [Id6],
[Limit3].[Value] AS [Value1],
[Project6].[C1] AS [C1]
FROM (SELECT
[Project4].[Id] AS [Id],
[Project4].[Number] AS [Number],
[Project4].[FirstName] AS [FirstName],
[Project4].[MiddleName] AS [MiddleName],
[Project4].[LastName] AS [LastName],
[Project4].[Gender] AS [Gender],
[Project4].[Title] AS [Title],
[Project4].[BirthDate] AS [BirthDate],
[Project4].[isDeleted] AS [isDeleted],
[Project4].[CreateDate] AS [CreateDate],
[Project4].[LastChange] AS [LastChange],
[Limit2].[Id] AS [Id1],
[Limit2].[Id1] AS [Id2],
[Limit2].[Id2] AS [Id3],
[Limit2].[Value] AS [Value],
[Project4].[C1] AS [C1]
FROM (SELECT
[Project3].[Id] AS [Id],
[Project3].[Number] AS [Number],
[Project3].[FirstName] AS [FirstName],
[Project3].[MiddleName] AS [MiddleName],
[Project3].[LastName] AS [LastName],
[Project3].[Gender] AS [Gender],
[Project3].[Title] AS [Title],
[Project3].[BirthDate] AS [BirthDate],
[Project3].[isDeleted] AS [isDeleted],
[Project3].[CreateDate] AS [CreateDate],
[Project3].[LastChange] AS [LastChange],
[Project3].[C1] AS [C1]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[Number] AS [Number],
[Project1].[FirstName] AS [FirstName],
[Project1].[MiddleName] AS [MiddleName],
[Project1].[LastName] AS [LastName],
[Project1].[Gender] AS [Gender],
[Project1].[Title] AS [Title],
[Project1].[BirthDate] AS [BirthDate],
[Project1].[isDeleted] AS [isDeleted],
[Project1].[CreateDate] AS [CreateDate],
[Project1].[LastChange] AS [LastChange],
(SELECT TOP (1)
[Extent2].[Id] AS [Id]
FROM [dbo].[CustomerProgram] AS [Extent2]
WHERE (0 = [Extent2].[isDeleted]) AND ([Project1].[Id] = [Extent2].[FK_CustomerId]) AND (@p__linq__1 = [Extent2].[FK_ProgramId])) AS [C1]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Number] AS [Number],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[MiddleName] AS [MiddleName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Gender] AS [Gender],
[Extent1].[Title] AS [Title],
[Extent1].[BirthDate] AS [BirthDate],
[Extent1].[isDeleted] AS [isDeleted],
[Extent1].[CreateDate] AS [CreateDate],
[Extent1].[LastChange] AS [LastChange]
FROM [dbo].[Customer] AS [Extent1]
WHERE ( NOT (([Extent1].[isDeleted] = 1) AND (2 = @p__linq__0))) AND ([Extent1].[Id] IN (cast('08909057-84e7-4eb6-8c5b-580b4732c82a' as uniqueidentifier)))
) AS [Project1]
) AS [Project3] ) AS [Project4]
OUTER APPLY (SELECT TOP (1)
[Extent3].[Id] AS [Id],
[Extent4].[Id] AS [Id1],
[Extent5].[Id] AS [Id2],
[Extent5].[Value] AS [Value]
FROM [dbo].[CustomerParameter] AS [Extent3]
INNER JOIN [dbo].[Parameter] AS [Extent4] ON [Extent3].[FK_ParameterId] = [Extent4].[Id]
LEFT OUTER JOIN [dbo].[ParameterValue] AS [Extent5] ON [Extent3].[FK_ParameterValueId] = [Extent5].[Id]
WHERE ([Project4].[Id] = [Extent3].[FK_CustomerId]) AND ([Extent4]. = @p__linq__2) ) AS [Limit2] ) AS [Project6] OUTER APPLY (SELECT TOP (1) [Extent6].[Id] AS [Id], [Extent7].[Id] AS [Id1], [Extent8].[Id] AS [Id2], [Extent8].[Value] AS [Value] FROM [dbo].[CustomerParameter] AS [Extent6] INNER JOIN [dbo].[Parameter] AS [Extent7] ON [Extent6].[FK_ParameterId] = [Extent7].[Id] LEFT OUTER JOIN [dbo].[ParameterValue] AS [Extent8] ON [Extent6].[FK_ParameterValueId] = [Extent8].[Id] WHERE ([Project6].[Id] = [Extent6].[FK_CustomerId]) AND ([Extent7].[code] = @p__linq__3) ) AS [Limit3] ) AS [Project8] OUTER APPLY (SELECT TOP (1) [Extent9].[Id] AS [Id], [Extent9].[FK_ParameterId] AS [FK_ParameterId], [Extent9].[CustomValue] AS [CustomValue], [Extent10].[Id] AS [Id1], [Extent10].[code] AS [code] FROM [dbo].[CustomerParameter] AS [Extent9] INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id] WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10].[code] = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code] = @p__linq__2) ) AS [Limit2] ) AS [Project6]
OUTER APPLY (SELECT TOP (1)
[Extent6].[Id] AS [Id],
[Extent7].[Id] AS [Id1],
[Extent8].[Id] AS [Id2],
[Extent8].[Value] AS [Value]
FROM [dbo].[CustomerParameter] AS [Extent6]
INNER JOIN [dbo].[Parameter] AS [Extent7] ON [Extent6].[FK_ParameterId] = [Extent7].[Id]
LEFT OUTER JOIN [dbo].[ParameterValue] AS [Extent8] ON [Extent6].[FK_ParameterValueId] = [Extent8].[Id]
WHERE ([Project6].[Id] = [Extent6].[FK_CustomerId]) AND ([Extent7]. = @p__linq__3) ) AS [Limit3] ) AS [Project8] OUTER APPLY (SELECT TOP (1) [Extent9].[Id] AS [Id], [Extent9].[FK_ParameterId] AS [FK_ParameterId], [Extent9].[CustomValue] AS [CustomValue], [Extent10].[Id] AS [Id1], [Extent10].[code] AS [code] FROM [dbo].[CustomerParameter] AS [Extent9] INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id] WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10].[code] = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code] = @p__linq__3) ) AS [Limit3] ) AS [Project8]
OUTER APPLY (SELECT TOP (1)
[Extent9].[Id] AS [Id],
[Extent9].[FK_ParameterId] AS [FK_ParameterId],
[Extent9].[CustomValue] AS [CustomValue],
[Extent10].[Id] AS [Id1],
[Extent10]. AS [code] FROM [dbo].[CustomerParameter] AS [Extent9] INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id] WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10].[code] = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code] AS FROM [dbo].[CustomerParameter] AS [Extent9] INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id] WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10].[code] = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code]
FROM [dbo].[CustomerParameter] AS [Extent9]
INNER JOIN [dbo].[Parameter] AS [Extent10] ON [Extent9].[FK_ParameterId] = [Extent10].[Id]
WHERE ([Project8].[Id] = [Extent9].[FK_CustomerId]) AND ([Extent10]. = @p__linq__5) ) AS [Limit4] ) AS [Project10] ) AS [Project12] LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange] FROM [dbo].[Customer_CustomerChild] AS [Extent13] INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1) UNION ALL ещё одна портянка UNION ALL ещё одна портянка [/spoiler] Что называется "без комментариев" :-)[code] = @p__linq__5) ) AS [Limit4]
) AS [Project10] ) AS [Project12]
LEFT OUTER JOIN (SELECT [Extent13].[FK_CustomerId] AS [FK_CustomerId], [Extent14].[FirstName] AS [FirstName], [Extent14].[LastName] AS [LastName], [Extent14].[Gender] AS [Gender], [Extent14].[BirthDate] AS [BirthDate], [Extent14].[isDeleted] AS [isDeleted], [Extent14].[CreateDate] AS [CreateDate], [Extent14].[LastChange] AS [LastChange]
FROM [dbo].[Customer_CustomerChild] AS [Extent13]
INNER JOIN [dbo].[CustomerChild] AS [Extent14] ON [Extent14].[Id] = [Extent13].[FK_CustomerChildId] ) AS [Join7] ON ([Project12].[Id] = [Join7].[FK_CustomerId]) AND ([Join7].[isDeleted] <> 1)
UNION ALL
ещё одна портянка
UNION ALL
ещё одна портянка
Что называется "без комментариев" :-)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21645933
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sti 
Что называется "без комментариев" :-)
что получается, когда хранимику напрямую переписывают на ORM ;)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21646088
sti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford 
sti 
Что называется "без комментариев" :-)
что получается, когда хранимику напрямую переписывают на ORM ;)
Разочарую вас, не было никакой хранимки.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21646305
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford 
CawaSPb 
Конечно, оптимизаторы, бывает, ошибаются. На моей практике это происходит гораздо реже, чем не ошибаются.
мой поинт тут совсем не в ошибке оптимизатора, мы предполагаем что оптимизатор как-раз сделал свою работу хорошо и для введенных параметров выбрал нужный план. Беда не в оптимизаторе, а в параметре, который вызвал скан. План-то для скана корректный. Но он закэшировался, и теперь каждый последующий вызов идет со сканом
Всё-таки вы, похоже, не понимаете, как работает оптимизатор. Что значит "и для введённых параметров"? Или я не понимаю того, что вы пишете.
Не бывает так, чтобы запрос сначала бился на подзапросы, и планы составлялись отдельно. План выбирается исходя из оценки стоимости запроса в целом. Крутится это всё то одним боком, то другим, выбирается план с наименьшей общей стоимостью (правды ради, некоторые эвристики таки применяются, NP-полнота задачи оптимизации запроса никуда не девается).
Не бывает так, чтобы способ доступа привязывался к таблице. Он зависит от контекста, используемых критериев выборки и многого другого. Кэшируется финальный план для общего запроса.

Это мы, кстати, ещё не касаемся вопросов параметризации со своими подводными камнями.

Вернёмся к приведённому вами запросу
Код
1.
2.
3.
4.
5.
6.
select Postcode from dbo.Cities
where Name = 'Moscow'
union
select Postode from dbo.Cities a
join dbo.Streets b on a.StreetId = b.StreetId
where b.StreetName = 'Rare street'
способы доступа к dbo.Cities в различных частях объединения скорее всего будут различны. Если уж на то пошло, при наличии явно объявленного referential constraint, обращение к dbo.Cities из второго запроса вообще будет убрано и запрос будет преоьбразован в:
Код
1.
2.
3.
select Postcode from dbo.Cities where Name = 'Moscow'
union
select Postode  from dbo.Streets where StreetName = 'Rare street'
.

Но вообще говоря, исходный запрос выглядит ошибочным. Подскажите, вот это ли вы примерно имели ввиду?
Код
1.
2.
3.
4.
5.
6.
7.
select Postcode, null as Postode
from dbo.Cities
where Name = 'Moscow'
union
select null as Postcode, b.Postode
from dbo.Cities a join dbo.Streets b on a.CityId = b.CityId
where b.StreetName = 'Rare street'
???
stenford 
CawaSPb 
Это как раз то, про что вам говорили - вместо 1000 запросов будет 2000 запросов (например, в секунду). В два раза больше накладных расходов на коммуникацию (для коротких запросов - подчас самая затратная часть).
у меня будет 1 скан (с соединениями по улицам) + 2000 запросов на улицы, где будет простой джойн за пару миллисекунд, а у вас - 1000 сканов таблицы. А в ней может с пару десятков лямов записей лежать. Действительно будете озабочены расходами на коммуникацию?
Давайте тогда уж, чтобы предметно, на какие запросы исходный разложится у вас (с количеством выполнения).
stenford 
ORM'ы не строят планы "руками", и никуда его не "зашивают".
Разбить на несколько мелких действий и прописать порядок их выполнения жёстко в коде - это и есть "зашить". Чуть двигаемся в сторону от элементарщины, и вот для того, чтобы вытащить объект требуется 20 отдельных запросов (20 join'ов в одном запросе - немногим лучше).
stenford 
Они вызывают мелкие точечные запросы, которые обычно весьма эффективны.
Как говаривал коллега по работе - "ватага зайцев гасит льва".
Одна из самых неприятных по производительности ситуаций - куча мелких запросов (в большем количестве, чем это было бы необхо) нападают на базу.
stenford 
А вот громозкие хранимки начинают страдать от ожирения плана, их начинают подкручивать, оптимизировать и прочее что и дает повод иметь на окладе ДБА :)
Хранимки можно использовать самым разным образом.
Лично я не сторонник того, чтобы выносить всю логику запросов в базу и лишать разработчика языка запросов, оставляя лишь некоторый API в виде набора процедур.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21646320
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford 
CawaSPb 
Понятно, что и так, и так можно. Но спор то идёт о том, плохи нынешние ОРМ или нет. Без этого контекста (кого на кого натягиваем) спор ни о чём. Принципиально разные ситуации (возьмите хоть работу с наследованием).
в смысле? Вы о том, что модель может сгенерироваться коряво и типа с ней будет плохо работать?
О том, что она не может сгенерироваться некоряво, кроме вырожденых случаев.
Или это будут "недообъекты", и о полноценном ОО будет неправильно говорить.

Ну вот представьте, дизайните вы приложение, которое будет работать со структурой организации.
Будет там у вас понятие "персона", от которой потянется развесистое дерево наследования - employer, которые в свою очередь бывают manager и не manager и т.д.
Будут ещё customer, которые персоны и которые юрлица.
Вот ОРМ захочет замапить это всё на реляционную структуру. Как лучше поступить для какой-то из иерархий, делать разрежённую таблицу/использовать иерархию таблиц? Всё со своими плюсами и минусами.

Идти от готовой реляционной структуры - ОРМ в лоб выдаст этакую плоскую структуру без наследовани. Объекты будут не объектами в Business Domain, а такими "специальными объектами БД" как в концепции Active Record.

Поэтому я предлагаю - давайте зафиксируем, о чём спорим (если вообще есть о чём, на самом деле), а потом будем разбираться.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21646612
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CawaSPb 
Всё-таки вы, похоже, не понимаете, как работает оптимизатор. Что значит "и для введённых параметров"? Или я не понимаю того, что вы пишете.
Да, вы по-прежнему не поняли что я имел ввиду, но зато я наконец понял что именно вы не поняли.
Вы исходите из того, что у вас есть одна хранимка с большим запросом состоящим из множества подзапросов vs аналогичные-же запросы просто разбитые на составные части ORM'ом. Конечно в этом случае разницы как таковой не будет. Я пытаюсь донести, что подход ORM'а с мелкими запросами кардинально меняет данную каpтину мира т.к. определенные запросы могут быть нужны/не нужны в зависимости от бизнес-логики.
В приведенном мной примере бизнес логика требует не одного запуска хранимки, а трех, с разными улицами, но одним и тем-же городом

Приведенный пример хранимки надо понимать именно как он написан, т.е. для следующей структуры таблиц:
Код
1.
2.
dbo.Cities(Name varchar(50), Postcode varchar(6), StreetId int)
dbo.Streets(StreetName varchar(50), CitiyId int)
Бизнес-логика системы будет требовать следующего вызова данной хранимки:
Код
1.
2.
3.
exec dbo.MyGigFattySproc 'Moscow', 'Rare Street'
exec dbo.MyGigFattySproc 'Moscow', 'More Rare Street'
exec dbo.MyGigFattySproc 'Moscow', 'Yet even more rare Street'
T.е. все почтовые индексы Mосквы плюс улицы Rare Street (даже если она не в москве), затем по каким-то бизнес-причинам Mосквы плюс улицы More Rare Street и так далее пока бизнес-причины не закончатся. Т.е. не получится просто так передать заранее определенный набор улиц, они там по бизнес-правилам как-то вычисляются. Можно подобную ситиацию придумать из финансовой области типа карт и транзакций, просто с улицами понятнее.
Так вот если 'Moscow' вызывает скан таблицы, то у вас на выходе будет 3 скана с соединениями по улицам. У меня 4 запроса, один со сканом на города, и 3 легких джойна на улицы т.к. юзаются 2 разных метода - поиск по городам и поиск по улицам. ORM не надо запрашивать города еще раз т.к. они уже в кэше обьектов. Ситуация не улучшится даже если вам удасться запихать необходимую бизнес-логику в саму хранимку (сделав ее еще толще), т.к. кэширование городов во временной таблице вы сами (совершенно справедливо) назвали бардаком.
CawaSPb 
Одна из самых неприятных по производительности ситуаций - куча мелких запросов (в большем количестве, чем это было бы необхо) нападают на базу.
а какие собственно неприятности это вызывает, кроме дополнительной нагрузки на сеть?
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21646615
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CawaSPb 
Будет там у вас понятие "персона", от которой потянется развесистое дерево наследования - employer, которые в свою очередь бывают manager и не manager и т.д.
Будут ещё customer, которые персоны и которые юрлица.
Вот ОРМ захочет замапить это всё на реляционную структуру. Как лучше поступить для какой-то из иерархий, делать разрежённую таблицу/использовать иерархию таблиц? Всё со своими плюсами и минусами.
нет абсолютно никаких проблем выбрать такой вариант модели/таблиц какой нравится. Все 3 типа (одна таблица на иерархию с дескриминаторами, по таблице на тип или по таблице на экземпляр) можно сделать указав необходимые параметры при создании модели/базы. По умолчанию установлен первый вариант
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21658144
Firey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Времена поменялись, поменялись технологии, поменялся сам подход. ТС советую смотреть в сторону Data Engineering, если он действительно сильный DEV и не хочет терять годами накопленный опыт. Будет сложно, непонятно, страшно, но в конце-концов смена профиля откроет новые горизонты и новые возможности
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21658310
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Firey 
...ТС советую смотреть в сторону Data Engineering, если он действительно сильный DEV и не хочет терять годами накопленный опыт. Будет сложно, непонятно, страшно, но в конце-концов смена профиля откроет новые горизонты и новые возможности
Разве Data Engineering в реальности это просто не Hardcore ETL ? (вместе со всеми вытекающими, т.е. сторонние инструменты и множество разных СУБД о которых DBA раньше и не слышал, ну и только потом Data Modelling и пр.)? Ну разве что Load и немного Transform от ETL пригодятся. Т.е. по факту "годами накопленный опыт" на таком пути всё равно хммм.. в довольно большой части станет бесполезен. Кроме того на практике ETL ещё и довольно дешевый сегмент IT (из-за большой конкуренции и засильем "специалистов" на рынке труда т.к. сильно высокой квалификации не требуется)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21658697
Firey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv 
Firey 
...ТС советую смотреть в сторону Data Engineering, если он действительно сильный DEV и не хочет терять годами накопленный опыт. Будет сложно, непонятно, страшно, но в конце-концов смена профиля откроет новые горизонты и новые возможности
Разве Data Engineering в реальности это просто не Hardcore ETL ? (вместе со всеми вытекающими, т.е. сторонние инструменты и множество разных СУБД о которых DBA раньше и не слышал, ну и только потом Data Modelling и пр.)? Ну разве что Load и немного Transform от ETL пригодятся. Т.е. по факту "годами накопленный опыт" на таком пути всё равно хммм.. в довольно большой части станет бесполезен. Кроме того на практике ETL ещё и довольно дешевый сегмент IT (из-за большой конкуренции и засильем "специалистов" на рынке труда т.к. сильно высокой квалификации не требуется)
И да, и нет. В реальности это работа на стыке классической ETL разработки, экспертизы в DWH и Big Data, опыта с Open Source продуктами и Cloud сервисами, разработки на Scala или Python и еще много чего. Очень горячая тема по нынешним временам!
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21658871
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Firey,

ну вот в принципе как всё быстро пришло к тому что собственно опыта DBA там и близко нет =)
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21659239
Firey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv 
Firey,

ну вот в принципе как всё быстро пришло к тому что собственно опыта DBA там и близко нет =)
Ну так ТС сразу сказал, что он DB Dev, не ДБА. Последней категории я бы особенно советовал расширять область компетенции и уходить в те же девопсы, например. Ибо на рынке труда все очень грустно, в частности по Ораклу, а будет и еще грустнее
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21659313
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Firey,

ну да, мимо просмотрел, просто тема началась за DBA
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21660178
Glebanski
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Любопытно, как фанаты ORM будут оптимизировать доступ к базе , если этой базой пользуется не только их аппликуха. А еще какой-нить сервис, который через ODATA гамнозапросы генерит... Скажите еще "странный сценарий"
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21660297
PinkCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
N.P.
По теме.

Если явно выраженная сезонность в активности ХРюш в европе.
Как уже сказали выше - минус средина лета, минус рождественские каникулы - и еще 2-3-4 недели до и после.
Есть еще пара минимумов, но они не столь экстремальные.
Оценка - чисто статистическая, по количеству контактов ХРюш по мылу и по телефоны за многие годы.

Кроме сезонности еще есть общий цикл развития при капитализме.
Теорию вы должны помнить - период развития, достижение насыщения, кризис перепроизводства... и все по новой.
Цикличность по развитию в Европе - 9-12 лет, с небольшой тенденцией к сокращению периода.

Последний глубокий кризис начался резким спадом в 2008 году.
Сейчас - прошло уже 10 лет - идет новый кризис.
Пока нет события, которое было бы достойно назваться Начало Кризиса 2018, это не значит что кризиса нет.
Кризис - есть! И уже не маленький. Уже закрываются мелкие и даже средние бизнесы. Причем - довольно активно.

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

Это - начало.
Следующие лет 5-6 будет очень плохо с работой.
Так что если кто-то имеет виды на работу в европе - либо все бросать и хватать любую постоянную работу,
либо не дергаться и ждать следующего подъема.
Не ведитесь на 2-х летние контракты - через два года тут будет полная задница.
Как-то так.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21660435
Glebanski
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PinkCat,

Несомненно, исследование достойное доверия. Сарказм.
ЗЫ: жена - хрюша
ЗЫ : если в линкедин не стоит галочка, то рекрутеры тебе и не пишут.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21660795
LenaV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
слово Хрюша для меня может звучать либо лаского, либо оскорбительно,
но никогда не нейтрально.
никак не могу понять,
почему общение с этими работниками вызывает такие глубокие эмоции,
что им даже слово специальное придумали.

вот у дба'ев никакой кликухи нет.
дба и все тут :(
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21660943
Фотография burgos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LenaV,

Так ДБА само по себе звучит как кликуха. :)))
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21661070
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vikkiv 
Firey 
...ТС советую смотреть в сторону Data Engineering, если он действительно сильный DEV и не хочет терять годами накопленный опыт. Будет сложно, непонятно, страшно, но в конце-концов смена профиля откроет новые горизонты и новые возможности
Разве Data Engineering в реальности это просто не Hardcore ETL ? (вместе со всеми вытекающими, т.е. сторонние инструменты и множество разных СУБД о которых DBA раньше и не слышал, ну и только потом Data Modelling и пр.)? Ну разве что Load и немного Transform от ETL пригодятся. Т.е. по факту "годами накопленный опыт" на таком пути всё равно хммм.. в довольно большой части станет бесполезен. Кроме того на практике ETL ещё и довольно дешевый сегмент IT (из-за большой конкуренции и засильем "специалистов" на рынке труда т.к. сильно высокой квалификации не требуется)
OoCc жена в прошлой жизни была Дата Инженером. Работала в отделе с 16-ю риск аналистами. Девелоперам не интересны данные, риск аналистам - непонятны данные, а дата инженер это тот кто отвечает за полноту-чистоту-постоянство данных. Каждый проект по созданию риск модели включал время для дата инженера - для дизайна набора данных отвечающем задачам модели.
...
Рейтинг: 0 / 0
Что происходит на рынке DB вакансий в ЕС?
    #21662484
PinkCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Glebanski,

ЗЫ: жена - хрюша
-----
Разве мне есть дело до ТВОЕЙ жены?

ЗЫ : если в линкедин не стоит галочка, то рекрутеры тебе и не пишут.
-----
Мне пишут и звонят несмотря на:
- отсутствие профиля в ЛинкедИн.
- всем сказано, что Я не ищу новую работу.
Просто страна маленькая и все спецы наперечет...
...
Рейтинг: 0 / 0
25 сообщений из 375, страница 15 из 15
Форумы / Наши за рубежом [закрыт для гостей] / Что происходит на рынке DB вакансий в ЕС?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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