powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как можно было обойти distinct для создания индексированного представления?
13 сообщений из 13, страница 1 из 1
Как можно было обойти distinct для создания индексированного представления?
    #39941870
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток!

В БД нашёл одно узкое место, решил причесать и добавить 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
Как можно было обойти distinct для создания индексированного представления?
    #39941871
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никак. Делайте отдельную сгруппированную таблицу, поддерживайте ее наряду с основными данными.
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39941872
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гавриленко Сергей Алексеевич
Никак. Делайте отдельную сгруппированную таблицу, поддерживайте ее наряду с основными данными .


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

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

distinct = group by по всем полям. Такие индексированные вью создавать можно.
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39941895
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex, а можно попросить кусочек кода, чтобы зацепиться. А то, что-то совсем не двигается.
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39941908
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] 
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39941924
Фотография 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
Как можно было обойти distinct для создания индексированного представления?
    #39941959
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
palladin600,

я настоятельно рекомендую вам отказаться от этой затеи. Вы ещё не дошли до главного сюрприза -- когда в таблицы будет вестись параллельная вставка, вы начнете ловить нехилые дедлоки из-за индексированного вью.
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39941971
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Как можно было обойти distinct для создания индексированного представления?
    #39941973
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39942007
Mr. X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
palladin600,

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

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


Вы забываете, что имеете дело с MSSQL, а не ORACLE. И вопрос не слове "матвью", в механизме БД, по которому все это работает.
...
Рейтинг: 0 / 0
Как можно было обойти distinct для создания индексированного представления?
    #39942058
palladin600
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
13 сообщений из 13, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как можно было обойти distinct для создания индексированного представления?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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