0

В начале был один набор таблиц для всех третьих сторон и дб был хорош .... потом ...Would кратно повторяется СУЩЕСТВУЕТ заявления, которые находятся в нескольких соединенных с видом получить оптимизированный в SQL Server

Один из наши сторонние стороны нуждались в некоторых из своих данных, поэтому, чтобы скрыть все остальные решения для клиентских данных, нужно было создать еще один набор таблиц (!!!), где мы будем дублировать данные только для этой третьей стороны и предоставлять доступ только к их набору зеркальных столы .... пока другой третья сторона не попросила того же ... а затем еще ... а затем я вошел ...

ATM Я подумываю о введении набора Views на третью сторону, которая сидит в своей третьей стороне Schema и делать подвыборы из исходных таблиц ... Чтобы определить в новом Views, который записывает, чтобы показать, кому я планирую представить таблицу RecordOwner. Где бы у меня были столбцы PK и owner для записей, которые должны отображаться в этом конкретном наборе представлений. (Другим вариантом было бы добавить в «главную» таблицу, в которой PK добавит столбец владельца и будет идентифицировать владельца оттуда .... но я считаю это менее гибким ...)

Мои представления выглядели бы примерно так (имена приведены только для иллюстрации):

CREATE VIEW [3rdPartyTable] 
AS 
    SELECT * 
    FROM [OriginalTable] ot 
    WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
       WHERE [Id] = ot.[Id] AND [Owner] = 'Owner1') 

CREATE VIEW [3rdPartyTable2] 
AS 
    SELECT * 
    FROM [OriginalTable2] ot 
    WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
        WHERE [Id] = ot.[MasterId] AND [Owner] = 'Owner1') 

Я думал о производительности, поскольку в этих оригинальных таблицах имеется немало записей. Когда каждая третья сторона будет запускать свои запросы и присоединиться к их мнение будет SQL Server быть достаточно умны, чтобы оптимизировать несколько идентичных повторен

where exists (select 1 from [RecordOwner] 
       where [Id] = ot.[MasterId] and [Owner] = 'Owner1') 

или нет?

EDIT: Рассмотрим следующий запрос третьим участником DEV пишет:

SELECT * from [3rdPartyTable2] t2 
inner join [3rdPartyTable3] t3 on t2.MasterId = t3.Masterid 

это тогда бы перевести

SELECT * FROM 
    (SELECT * FROM [OriginalTable2] ot 
    where exists (select 1 from [RecordOwner] where [Id] = ot.[MasterId] and [Owner] = 'Owner1')) t2 
inner join 
    (SELECT * FROM [OriginalTable3] ot 
    where exists (select 1 from [RecordOwner] where [Id] = ot.[MasterId] and [Owner] = 'Owner1')) t3 
on t2.MasterId = t3.Masterid 

и обе таблицы имеют PK на MasterId.

Будет ли SQL Server достаточно умен, чтобы оптимизировать несколько повторяющихся статей EXISTS во взглядах?

+0

Я предполагаю, что 'Id' /' MasterId' - это идентификатор GUID, а не поле Identity?! В противном случае вы столкнетесь с перекрытием. Во всяком случае, если PK 'RecordOwner' является' Owner' и 'MasterId', то почему бы просто не использовать' JOIN' вместо 'WHERE EXISTS()'? В каждом случае я смущен, почему вы ожидаете, что сервер волшебным образом «объединит» те разные ссылки на таблицу «RecordOwner»? Значения 'ot2' НИЧЕГО не имеют общего с теми, что от' ot3' .... Тем не менее, я бы не стал слишком беспокоиться о производительности, сохраняя при этом, что эти копии таблиц в синхронизации для каждого клиента потребуют гораздо больших усилий и Ресурсы. – deroby

ответ

0

TL; DR; Мнения, которые построены с использованием JOINS, равны или быстрее, чем те, которые построены с использованием EXISTS (и они оптимизированы на LEFT OUTER JOINS).

Как подтверждение ответа @ Gordon, я экспериментировал, делал просмотры, индексы и заполнял 93% данных записи PK в базе данных, вы можете видеть из плана выполнения, что при объединении трех таблиц он выполнял 3 сканирования. ..

enter image description here

накладные (~ 3% за соединение) минимальна, хотя ...

EDIT: Ран другой набор планов тестирования и выполнения идентичны при соединении с видом на LEFT OUTER JOIN но при выполнении INNER JOINS вид ы, которые построены с использованием JOIN, а затем EXISTS превосходят последние ...

Пример зрения с РЕГИСТРИРУЙТЕСЬ:

CREATE VIEW [dbo].[Summary2] 
AS 
SELECT st.* 
    FROM [OriginalSummary] st 
    inner join [RecordOwner] ro on ro.[Id] = st.[MasterId] and [Owner] = 'corp1' 

enter image description here

Пример зрения с EXISTS:

CREATE VIEW [dbo].[Summary] 
AS 
SELECT * 
FROM [OriginalSummary] ot 
WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
       WHERE [Id] = ot.[MasterId] AND [Owner] = 'corp1') 
GO 

enter image description here

0

Это слишком длинный комментарий.

О чем вы говорите? Выражения exists используют коррелированные подзапросы. Следовательно, каждый из них представляет собой отдельный и другой запрос, потому что они ссылаются на разные таблицы во внешнем запросе.

С индексом на RecordOwner(Id, Owner) производительность должна быть в порядке. Однако вы должны проверить его.

Вы также можете рассмотреть возможность написания отдельного вида для каждого клиента. Клиентам может быть более удобный доступ к тому, что называется table_client, а не в зависимости от скрытых механизмов безопасности.

+0

Привет Гордон, представьте себе третий участник пишет выберите 'select * from [3rdPartyTable2] t2 внутреннее соединение [3rdPartyTable3] t3 на t2.MasterId = t3.Masterid' это, то будет переводить ' (SELECT * FROM [OriginalTable2 ] ot где существует (выберите 1 из [RecordOwner], где [Id] = ot. [MasterId] и [Owner] = 'Owner1')) внутреннее соединение (SELECT * FROM [OriginalTable3] ot Где существует (выберите 1 из [RecordOwner], где [Id] = ot. [MasterId] и [Owner] = 'Owner1')) 'обе таблицы имеют PK в основной записи –

+0

@MatasVaitkevicius. , , Я серьезно сомневаюсь, что SQL Server или любая другая база данных оптимизируют один из «существующих». –

Смежные вопросы