Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите ламеру с индеками:)  [new]
albertik
Member

Откуда:
Сообщений: 128
Доброго времени суток.
Хочу попросить подсказки у более опытных специалистов по MS SQL.
Есть таблица журналирования изменений (по одной на каждую сущность):
CREATE TABLE [dbo].[Sec_Role](
	[idRole] [int] NULL,
	[roleName] [varchar](150) NULL,
	[isBasic] [bit] NULL,
	[history_id_record] [int] IDENTITY(1,1) NOT NULL,
	[history_record_state] [char](1) NULL,
	[history_id_editor] [int] NULL,
	[history_edit_date] [datetime] NULL,
	[history_columns_updated] [varbinary](10) NULL,
	[history_system_user] [varchar](40) NULL,
	[history_app_name] [varchar](40) NULL,
	[history_host_name] [varchar](40) NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_History_Sec_Role] ON [dbo].[Sec_Role]
(
	[idRole] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Поле history_record_state принимает одно из 4х символьных значений, idRole - первичный ключ из оперативной таблицы.
И есть желание (цель) получать из нее дату создания + дату редактирования.
Наваял вот такой запрос:
select e.idRole, c.history_id_editor as idCreator, c.history_edit_date as createDate,
		e.history_id_editor as idEditor, e.history_edit_date as editDate
from Sec_role as c
	inner join 
		(
			select idRole, history_id_editor, history_edit_date
			from Sec_role
			where history_record_State in ('A', 'S')		
		) as e
		on c.idRole = e.idRole
where history_record_State in ('C', 'S')


Результат возвращает нужный, но хочется по максимуму использовать возможности индексов.

За ранее спасибо всем сочувствующим!
24 июл 13, 12:59    [14609867]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
Гость333
Member

Откуда:
Сообщений: 3683
albertik
Наваял вот такой запрос:
select e.idRole, c.history_id_editor as idCreator, c.history_edit_date as createDate,
		e.history_id_editor as idEditor, e.history_edit_date as editDate
from Sec_role as c
	inner join 
		(
			select idRole, history_id_editor, history_edit_date
			from Sec_role
			where history_record_State in ('A', 'S')		
		) as e
		on c.idRole = e.idRole
where history_record_State in ('C', 'S')

Именно такому запросу индексы, скорее всего, не нужны.
Вам всегда нужно получать данные для всех значений idRole?
24 июл 13, 13:25    [14610084]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
albertik
Member

Откуда:
Сообщений: 128
Гость333
Именно такому запросу индексы, скорее всего, не нужны.
Вам всегда нужно получать данные для всех значений idRole?


Напрашивается вопрос - мб как то по другому запрос оформить?
Ну и уточнение - нет, не всегда для всех значений. Иногда этот запрос будет являться подзапросом, связываться будет по idRole.
24 июл 13, 13:37    [14610171]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
Гость333
Member

Откуда:
Сообщений: 3683
albertik
Напрашивается вопрос - мб как то по другому запрос оформить?

Использование индексов обычно имеет смысл при выборке не более нескольких процентов от общего числа записей таблицы. Иначе выгоднее сделать фуллскан таблицы. От оформления запроса это слабо зависит.

albertik
Ну и уточнение - нет, не всегда для всех значений. Иногда этот запрос будет являться подзапросом, связываться будет по idRole.

Можно создать составной индекс по полям idRole и history_record_State. Можно добавить поля history_id_editor и history_edit_date в качестве include-полей. Всё это ускорит ваши запросы, но более "толстые" индексы медленнее модифицируются (замедляют операции insert/update/delete). Тут сами смотрите, что для вас важнее — скорость чтений или скорость изменений.
24 июл 13, 14:04    [14610386]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
нуб987
Guest
Гость333
Использование индексов обычно имеет смысл при выборке не более нескольких процентов от общего числа записей таблицы. Иначе выгоднее сделать фуллскан таблицы. От оформления запроса это слабо зависит.

а можете прокомментировать тогда такой пример:
есть т.фактов и справочник клиентов
-- т.фактов
CREATE TABLE Facts (
	ClientId int NOT NULL ,
	Amount float NULL 
) ON [PRIMARY]

-- клиенты
CREATE TABLE Clients (
	id int IDENTITY (1, 1) NOT NULL ,
	Name nvarchar(255) NULL ,
	CONSTRAINT [PK_Clients] PRIMARY KEY  CLUSTERED 
	(
		[id]
	) WITH  FILLFACTOR = 90  ON [PRIMARY] 
) ON [PRIMARY]


у клиентов по полю ID построен первичный ключ.
При процессинге ОЛАП-куба, построенном на наших табличках, делается полная выборка всех записей, так?
Т.е. запрос будет какой-то такой:
select c.Name as [ИмяКлиента], SUM(f.Amount) as [КолвоОтгрузки]
from Facts f, Clients c
where c.id = f.ClientId

Правильно ли я понимаю, что индекс на поле ClientId т.фактов не нужен?
15 авг 13, 13:58    [14713092]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
нуб987,

Не совсем. Т.е. понятно, что тянуться будет вся таблица, но индекс даст отсортированность столбца, что при соединении обычно важно.

Вы попробуйте два разных варианта, с индексом и без, и сравните планы выполнения и время. Только учтите, что для 100 строк разница будет совсем не такая, как для 100 миллионов.
15 авг 13, 14:05    [14713149]     Ответить | Цитировать Сообщить модератору
 Re: Помогите ламеру с индеками:)  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2396
нуб987
При процессинге ОЛАП-куба, построенном на наших табличках, делается полная выборка всех записей, так?
Т.е. запрос будет какой-то такой:


при процессинге из вижуал студии, можно (в подробностях) увидеть SQL запрос
15 авг 13, 15:08    [14713555]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить