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

Откуда:
Сообщений: 67
Здравствуйте, помогите разобраться с проблемой:
Имеется вьюшка с большим количеством данных (порядка 1млрд).
Когда делаю запрос с ORDER BY - все работает очень медленно.
ORDER BY делается по 2 полям с типом datetime

Хочу сделать индекс в таблице из которой вьюшка берет эти поля. Поможет это? И если делать индекс, то лучше на каждое поле отдельно или на оба поля один индекс? Может быть есть какой-нибудь другой способ ускорить запрос?
4 июл 13, 08:30    [14520080]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Забыл добавить: MS SQL SERVER 2012
4 июл 13, 08:30    [14520082]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
inooni
Здравствуйте, помогите разобраться с проблемой:
Имеется вьюшка с большим количеством данных (порядка 1млрд).
Когда делаю запрос с ORDER BY - все работает очень медленно.
ORDER BY делается по 2 полям с типом datetime

Хочу сделать индекс в таблице из которой вьюшка берет эти поля. Поможет это? И если делать индекс, то лучше на каждое поле отдельно или на оба поля один индекс? Может быть есть какой-нибудь другой способ ускорить запрос?

Добрый день. Вы бы выложили скрипты создания таблиц, вьюхи и сам запрос (желательно с планом). А так вслепую советовать что-то мало кто возмётся.
4 июл 13, 08:31    [14520087]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
сейчас выложу
4 июл 13, 08:34    [14520097]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Создание вьюхи
Create View [dbo].[MaintenanceEventsV] AS
select mc.CustomerID, mc.areaid as "AreaID", mm.ZoneID, me.Location, mc.MeterID, 
	mc.GlobalMeterID, ha.TimeOfNotification, ha.TimeOfClearance as "Time of Completion", 
	tt.TimeTypeDesc as "Time Class", mme.MaintenanceCode as "Repair Code", 
	ec.EventDescVerbose as "Description", wo.TechnicianID, td.name as "Technician Name", 
	mc.EventCode as "Alarm Code", ec.AlarmTier as "Alarm Class"
from EventLogs mc
		join MeterMap mm
		on mc.customerid = mm.customerid
		and mc.areaid = mm.areaid
		and mc.meterid = mm.meterid
		join EventCodes ec
		on mc.EventCode = ec.EventCode
		join Meters me
		on mc.MeterID = me.MeterID
		and mc.CustomerID = me.CustomerID
		join HistoricalAlarms ha
		on mc.MeterID = ha.MeterID
		and mc.CustomerID = ha.CustomerID
		and mc.MeterID = ha.MeterID		
		join TimeTypeCustomer ttc
		on mc.CustomerID = ttc.CustomerID
		join TimeType tt
		on ttc.TimeTypeId = tt.TimeTypeId
		join WorkOrder wo
		on mc.customerid = wo.customerid
		and ha.WorkOrderId = wo.WorkOrderId
		join TechnicianDetails td
		on wo.TechnicianID = td.TechnicianId
		join SFMeterMaintenanceEvent mme
		on mc.customerid = mme.customerid
		and ha.WorkOrderId = mme.WorkOrderId
		and mc.MeterID = mme.MeterID
		where mc.EventCode in (16,30,2008)


План выполнения в приложенном файле (там я уже добавил 2 индекса на эти поля для проверки)

Запрос необходимо выполнить следующий:
SELECT DISTINCT TOP 1000
[dbo].[MaintenanceEventsV].[TimeOfNotification] AS 'Time Of Notification', [dbo].[MaintenanceEventsV].[Time of Completion] AS 'Time of Completion', [dbo].[MaintenanceEventsV].[Time Class] AS 'Time Class', [dbo].[MaintenanceEventsV].[Alarm Class] AS 'Class@Alarm Info', [dbo].[MaintenanceEventsV].[Alarm Code] AS 'Code@Alarm Info', [dbo].[MaintenanceEventsV].[Description] AS 'Description@Alarm Info', [dbo].[MaintenanceEventsV].[GlobalMeterID] AS 'Global Meter@ID Numbers', [dbo].[MaintenanceEventsV].[MeterID] AS 'Meter@ID Numbers', [dbo].[MaintenanceEventsV].[Repair Code] AS 'Code@Repair', [dbo].[MaintenanceEventsV].[Technician Name] AS 'Name@Technician', [dbo].[MaintenanceEventsV].[TechnicianID] AS 'ID@Technician', [dbo].[MaintenanceEventsV].[Location] AS 'Location@Location', [dbo].[MaintenanceEventsV].[AreaID] AS 'Area@Location', [dbo].[MaintenanceEventsV].[ZoneID] AS 'Zone@Location'
FROM [dbo].[MaintenanceEventsV] WITH(NOLOCK) 
ORDER BY [dbo].[MaintenanceEventsV].[TimeOfNotification] ASC, [dbo].[MaintenanceEventsV].[Time of Completion] ASC; 


К сообщению приложен файл (plan.zip - 13Kb) cкачать
4 июл 13, 08:43    [14520118]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
В таблице HistoricalAlarms (откуда оба поля, по которым мы делаем ORDER BY) порядка 25000 записей.

Переделывание структуры базы данных я пока что не рассмматриваю, т.к. база не моя, а заказчиков, мне, по-сути, нужно из нее извлечь некоторые данные
4 июл 13, 08:46    [14520133]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
inooni
В таблице HistoricalAlarms (откуда оба поля, по которым мы делаем ORDER BY) порядка 25000 записей.

Переделывание структуры базы данных я пока что не рассмматриваю, т.к. база не моя, а заказчиков, мне, по-сути, нужно из нее извлечь некоторые данные

Выложите, пожалуйста, ещё план выполнения самого запроса из представления.

select mc.CustomerID, mc.areaid as "AreaID", mm.ZoneID, me.Location, mc.MeterID, 
	mc.GlobalMeterID, ha.TimeOfNotification, ha.TimeOfClearance as "Time of Completion", 
	tt.TimeTypeDesc as "Time Class", mme.MaintenanceCode as "Repair Code", 
	ec.EventDescVerbose as "Description", wo.TechnicianID, td.name as "Technician Name", 
	mc.EventCode as "Alarm Code", ec.AlarmTier as "Alarm Class"
from EventLogs mc
		join MeterMap mm
		on mc.customerid = mm.customerid
		and mc.areaid = mm.areaid
		and mc.meterid = mm.meterid
		join EventCodes ec
		on mc.EventCode = ec.EventCode
		join Meters me
		on mc.MeterID = me.MeterID
		and mc.CustomerID = me.CustomerID
		join HistoricalAlarms ha
		on mc.MeterID = ha.MeterID
		and mc.CustomerID = ha.CustomerID
		and mc.MeterID = ha.MeterID		
		join TimeTypeCustomer ttc
		on mc.CustomerID = ttc.CustomerID
		join TimeType tt
		on ttc.TimeTypeId = tt.TimeTypeId
		join WorkOrder wo
		on mc.customerid = wo.customerid
		and ha.WorkOrderId = wo.WorkOrderId
		join TechnicianDetails td
		on wo.TechnicianID = td.TechnicianId
		join SFMeterMaintenanceEvent mme
		on mc.customerid = mme.customerid
		and ha.WorkOrderId = mme.WorkOrderId
		and mc.MeterID = mme.MeterID
		where mc.EventCode in (16,30,2008)
4 июл 13, 08:51    [14520152]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Сейчас выложу. Тут оказалось еще, что на машине заказчиков место закончилось на жестком диске. Сейчас разберусь с этим и выложу план.
4 июл 13, 09:01    [14520198]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Вот план самой вьюхи.

К сообщению приложен файл (plan2.zip - 11Kb) cкачать
4 июл 13, 09:04    [14520215]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
Почему-то мне кажется, что вам может подойти вот это.
Также посмотрите на таблицу: EventLogs.

У вас идёт скан индекса и операция Key Lookup (Key Lookup.
Попробуйте добавить в индекс EventLogs_IDX_Camee INCLUDE GlobalMeterID. Количество операций ввода/вывода существенно должно снизиться.

И вообще я смотрю на названия индексов в вашей системе _dta_index_...... Вы настолько доверяете Tuning Advisor?
4 июл 13, 09:32    [14520334]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Сергей Викт.
И вообще я смотрю на названия индексов в вашей системе _dta_index_...... Вы настолько доверяете Tuning Advisor?


Спасибо за совет, попробую. Насчет Tuning Advisor - это вопрос к заказчикам, их база
4 июл 13, 09:37    [14520351]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
Сергей Викт.
Member

Откуда: Москва
Сообщений: 888
inooni
Сергей Викт.
И вообще я смотрю на названия индексов в вашей системе _dta_index_...... Вы настолько доверяете Tuning Advisor?


Спасибо за совет, попробую. Насчет Tuning Advisor - это вопрос к заказчикам, их база

Понял. Кстати: про индексы хорошая статья. Советую прочитать для понимания основных принципов.
4 июл 13, 09:42    [14520367]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
inooni
Member

Откуда:
Сообщений: 67
Сергей Викт.
inooni
пропущено...


Спасибо за совет, попробую. Насчет Tuning Advisor - это вопрос к заказчикам, их база

Понял. Кстати: про индексы хорошая статья. Советую прочитать для понимания основных принципов.

В свое время я разобрался со всем этим, но с тех пор прошло довольно много времени, в течении которого я занимался другими вещами и многое уже забылось. Похоже, пришло время вспомнить все.
4 июл 13, 09:56    [14520423]     Ответить | Цитировать Сообщить модератору
 Re: Какой индекс лучше создать  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
inooni,

Вам тут индекс на HistoricalAlarms при таком запросе не поможет. Фильтруйте эту таблицу по датам . Все равно вы делаете select distinct top 1000 т.е. вам все равно какие записи, лишь бы было 1000 штук и не повторялись, полагаю что и число 1000 тоже особенно не критично. Как вариант можно соединять подзапрос из HistoricalAlarms с первыми 1000 записями, но не факт что в итоге на выводе получится именно 1000. Из индексов можно посоветовать только покрывающий на EventLog, но он особой погоды не сделает, самое дорогое это distinct сортировка для отбора 1000 записей в самом конце плана, повторюсь, если создать ограничительные условия, которые применятся на ранних этапах выполнения, то и финальная сортировка не будет так дорого стоить.
4 июл 13, 11:08    [14520847]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить