Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как можно было обойти distinct для создания индексированного представления? / 13 сообщений из 13, страница 1 из 1
28.03.2020, 14:31
    #39941870
palladin600
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
Доброго времени суток!

В БД нашёл одно узкое место, решил причесать и добавить view, и вот упёрся в один момент, который не годится для индексированного представления. Сами тестовые данные такие:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
--тип деталей
declare @DetailTypes table(TypeID int, [Name] nvarchar(10))
insert into @DetailTypes(TypeID, [Name])
select 1, N'Гайка' union all
select 2, N'Шайба' union all
select 3, N'Винт'

--модификация деталей
declare @DetailModifications table(ID int, DetailTypeID int)
insert into @DetailModifications(ID, DetailTypeID)
select 1, 1 union all
select 2, 2 union all
select 3, 1 union all
select 4, 1 union all
select 5, 3

--общий перечень деталей
declare @AllDetails table([ID] int, [ModificationID] int)
insert into @AllDetails(ID, [ModificationID])
select 1, 2 union all	--шайба
select 2, 2 union all	--шайба
select 3, 1 union all	--гайка
select 4, 3 union all	--гайка
select 5, 5 union all	--винт
select 6, 1 union all	--гайка
select 7, 5				--винт

--отделы
declare @Departaments table(ID int, [Name] nvarchar(10))
insert into @Departaments(ID, [Name])
select 1, N'Отдел1' union all
select 2, N'Отдел2' union all
select 3, N'Отдел3' 

--рабочие
declare @Workers table(ID int, DepartamentID int, [Name] nvarchar(10))
insert into @Workers(ID, DepartamentID, [Name])
select 1, 1, N'Ларионов' union all
select 2, 1, N'Свирский' union all
select 3, 1, N'Фелистович' union all
select 4, 3, N'Фёдоров' union all
select 5, 3, N'Будницкий' union all
select 6, 2, N'Некрашевич' 

--дежурный журнал отдела качества
declare @QualityList table(WorkerID int, DetailID int, IsDefect bit)
insert into @QualityList(WorkerID, DetailID, IsDefect)
select 2, 2, 0 union all	--свирский из Отдела1 сделал шайбу без дефекта *
select 2, 2, 0 union all	--свирский из Отдела1 сделал шайбу без дефекта *
select 4, 5, 0 union all	--фёдоров из Отдела3 сделал винт без дефекта *
select 4, 6, 0 union all	--фёдоров из Отдела3 сделал гайку без дефекта *
select 5, 2, 1 union all	--будницкий из Отдела3 сделал шайбу с дефектом *
select 1, 1, 1 union all	--ларионов из Отдела1 сделал шайбу с дефектом *
select 3, 5, 1 union all	--фелистович из Отдела1 сделал винт с дефектом *
select 1, 4, 0 union all	--ларионов из Отдела1 сделал гайку без дефекта *
select 6, 5, 0 union all	--некрашевич из Отдела2 сделал винт без дефекта *
select 6, 1, 1				--некрашевич из Отдела2 сделал шайбу с дефектом *


Из журнала мне нужно получить сводку, в каком отделе присутствуют уникальные детали по каждому отделу без брака на момент запроса.
Эти данные я получаю так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select distinct d.[Name], dt.[Name] from @QualityList ql inner join 
	@Workers w ON ql.WorkerID = w.ID inner join
	@Departaments d ON w.DepartamentID = d.ID inner join
	@AllDetails ad ON ql.DetailID = ad.ID inner join
	@DetailModifications dm ON ad.ModificationID = dm.ID inner join
	@DetailTypes dt ON dm.DetailTypeID = dt.TypeID
	where not ql.IsDefect = 1
	order by 1


на выходе отдаются записи:
Код: plaintext
1.
2.
3.
4.
Отдел1	Гайка
Отдел1	Шайба
Отдел2	Винт
Отдел3	Винт
Отдел3	Гайка
журнал отдела качества большой, и к нему надо часто обращаться, и это поднагибает запрос. Чтобы отобрать аггрегированные данные я задумал организовать индексированное представление, но как известно, в таком представлении не может присутствовать такой оператор как distinct.
Вопрос в студию, а можно переписать запрос без использования distinct для моего случая?
...
Рейтинг: 0 / 0
28.03.2020, 14:33
    #39941871
Гавриленко Сергей Алексеевич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
Никак. Делайте отдельную сгруппированную таблицу, поддерживайте ее наряду с основными данными.
...
Рейтинг: 0 / 0
28.03.2020, 14:52
    #39941872
palladin600
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
Гавриленко Сергей Алексеевич
Никак. Делайте отдельную сгруппированную таблицу, поддерживайте ее наряду с основными данными .


Скажите, что имеется в виду под словом "поддерживайте"? Т.е. помимо внесения данных в основную таблицу-журнал, надо будет ещё контролировать внесение данные в дополнительную таблицу? Мне кажется, это сложно придумать. На клиентах придётся доделывать после импорта данных ещё один запрос, который сносит в сгруппированной таблице текущие данные, и затем инсертит уже актуальные. А можно ли настроить автоматическую какую-то зависимость попадания туда данных?

Если не использовать триггеры, то я ещё слышал про Track Data Changes, или это уже крайности?
...
Рейтинг: 0 / 0
28.03.2020, 15:07
    #39941874
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
palladin600,

distinct = group by по всем полям. Такие индексированные вью создавать можно.
...
Рейтинг: 0 / 0
28.03.2020, 17:46
    #39941895
palladin600
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
msLex, а можно попросить кусочек кода, чтобы зацепиться. А то, что-то совсем не двигается.
...
Рейтинг: 0 / 0
28.03.2020, 19:09
    #39941908
SERG1257
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2, COUNT_BIG(*) AS COUNT from yourquery
group by d.[Name] , dt.[Name] 
...
Рейтинг: 0 / 0
28.03.2020, 22:45
    #39941924
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
SERG1257
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2, COUNT_BIG(*) AS COUNT from yourquery
group by d.[Name] , dt.[Name] 

Можно даже без COUNT
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2 from yourquery
group by d.[Name] , dt.[Name] 
...
Рейтинг: 0 / 0
29.03.2020, 09:12
    #39941959
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
palladin600,

я настоятельно рекомендую вам отказаться от этой затеи. Вы ещё не дошли до главного сюрприза -- когда в таблицы будет вестись параллельная вставка, вы начнете ловить нехилые дедлоки из-за индексированного вью.
...
Рейтинг: 0 / 0
29.03.2020, 10:42
    #39941971
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
alexeyvg
SERG1257
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2, COUNT_BIG(*) AS COUNT from yourquery
group by d.[Name] , dt.[Name] 


Можно даже без COUNT
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2 from yourquery
group by d.[Name] , dt.[Name] 


Нельзя. Это требование индексированные вью.
...
Рейтинг: 0 / 0
29.03.2020, 10:53
    #39941973
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
...
Рейтинг: 0 / 0
29.03.2020, 13:21
    #39942007
Mr. X
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
palladin600,

Под вашу задачу подойдут обычные индексы с условием и без, колоночные, возможно. Через матвью тоже можно, но они накладывает логические (синтаксис) и физические ограничения (обновление одного матвью из разных таблиц-источников).
...
Рейтинг: 0 / 0
29.03.2020, 13:33
    #39942011
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
Mr. X
palladin600,

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


Вы забываете, что имеете дело с MSSQL, а не ORACLE. И вопрос не слове "матвью", в механизме БД, по которому все это работает.
...
Рейтинг: 0 / 0
29.03.2020, 19:20
    #39942058
palladin600
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как можно было обойти distinct для создания индексированного представления?
SERG1257
Код: sql
1.
2.
select d.[Name] as name1, dt.[Name] as name2, COUNT_BIG(*) AS COUNT from yourquery
group by d.[Name] , dt.[Name] 

что интересно, такое ощущение что запрос с group by срабатывает заметно быстрее, чем с использованием distinct . Но может и показалось...
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как можно было обойти distinct для создания индексированного представления? / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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