Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
Добрый день.
Я не администратор БД, эта задача для меня прикладная. Т.е. ее надо решить, но уходить в дебри изучения архитектуры индексов и идеологически верного проектирования БД, для меня непозволительная роскошь. Поэтому прошу не пинать ногами, т.к. беглые поиск в течении трех дней для меня ясности не внес. Только по этому решил написать сюда.
Итак задача:
Сервер MS SQL 2008 R2 64bit, Windows 2008 R2.
Два массива RAID10 (на контроллере LSI MegaRAID SAS 9260-8i), на одном крутится несколько БД, на втором оперативные бекапы+файлы журнала транзакций.
24GB RAM, 24 ядра в диспетчере устройств (XEON X5650).
Есть таблица статистики звонков:
USE [INFDATA_STAT]
GO

/****** Object:  Table [dbo].[I_STATISTICS_CALL_IN]    Script Date: 11/25/2013 08:25:13 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[I_STATISTICS_CALL_IN](
	[CALLID] [varchar](50) NULL,
	[DATETIME] [float] NULL,
	[DATETIME_D] [float] NULL,
	[DATETIME_T] [float] NULL,
	[ANUMBER] [varchar](100) NULL,
	[ANAME] [varchar](250) NULL,
	[ANUMBERDIALED] [varchar](100) NULL,
	[CALLRESULT] [int] NULL,
	[IVRLENGTH] [float] NULL,
	[IVRNAME] [varchar](250) NULL,
	[B1WAITLENGTH] [float] NULL,
	[B1TALKLENGTH] [float] NULL,
	[B1NUMBER] [varchar](100) NULL,
	[B1NAME] [varchar](250) NULL,
	[B1IDUSER] [int] NULL,
	[B2WAITLENGTH] [float] NULL,
	[B2TALKLENGTH] [float] NULL,
	[B2NUMBER] [varchar](100) NULL,
	[B2NAME] [varchar](250) NULL,
	[B2IDUSER] [int] NULL,
	[B3WAITLENGTH] [float] NULL,
	[B3TALKLENGTH] [float] NULL,
	[B3NUMBER] [varchar](100) NULL,
	[B3NAME] [varchar](250) NULL,
	[B3IDUSER] [int] NULL,
	[EXWAITLENGTH] [float] NULL,
	[EXTALKLENGTH] [float] NULL,
	[EXNUMBER] [varchar](100) NULL,
	[EXNAME] [varchar](250) NULL,
	[EXROUTENAME] [varchar](250) NULL,
	[SUMLENGTH] [float] NULL,
	[SUMIVRLENGTH] [float] NULL,
	[SUMOPERLENGTH] [float] NULL,
	[SUMEXTERNALLENGTH] [float] NULL,
	[SERVER_ID] [int] NULL,
	[GLOBAL_ID] [bigint] NOT NULL,
 CONSTRAINT [PK_I_STATISTICS_CALL_IN] PRIMARY KEY CLUSTERED 
(
	[GLOBAL_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


В ней порядка 24 млн строк. Созданы индексы:
CREATE NONCLUSTERED INDEX [I_STATISTICS_CALL_IN_IDX1] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC,[B1WAITLENGTH] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [I_STATISTICS_CALL_IN_IDX2] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] DESC,[SUMOPERLENGTH] ASC,[SERVER_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_ANUMBER] ON [dbo].[I_STATISTICS_CALL_IN] 
([ANUMBER] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_ANUMBERDIALED] ON [dbo].[I_STATISTICS_CALL_IN] 
([ANUMBERDIALED] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_callresult] ON [dbo].[I_STATISTICS_CALL_IN] 
([CALLRESULT] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_DATETIME] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_ServerID_CALLID] ON [dbo].[I_STATISTICS_CALL_IN] 
([CALLID] ASC,[SERVER_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_Sumlenght] ON [dbo].[I_STATISTICS_CALL_IN] 
([SUMLENGTH] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

ALTER TABLE [dbo].[I_STATISTICS_CALL_IN] ADD  CONSTRAINT [PK_I_STATISTICS_CALL_IN] PRIMARY KEY CLUSTERED 
([GLOBAL_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]


Для работы с таблицей как обязательно используются поля DATETIME. Чаще всего так же используются поля:
ANUMBER, SERVER_ID,B1IDUSER.
Что меня смущает, это то, что простейший запрос вида:
declare @Globalid_min bigint, @Globalid_max bigint
declare @dt1 float,	@dt2 float


set @dt1	=CONVERT(float,CONVERT(datetime,'20131109 12:00:00'))+2--дата от 
set @dt2	= cast(cast('20131122' as datetime) as float)+2--дата до


Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[datetime_D] between @dt1 and @dt2  
Select @Globalid_min as min, @Globalid_max as max

выполняется от минуты и более, что непозволительно долго для текущих задач. Вопрос к знающим и понимающим, что я могу оптимизировать или перенастроить, для того, чтобы снизить время выполнения запроса хотя бы раза в три.
План запроса:
  |--Nested Loops(Inner Join)
       |--Stream Aggregate(DEFINE:([Expr1002]=MIN([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
       |    |--Top(TOP EXPRESSION:((1)))
       |         |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME_D] as [isc].[DATETIME_D]>=[@dt1] AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME_D] as [isc].[DATETIME_D]<=[@dt2]) ORDERED FORWARD)
       |--Stream Aggregate(DEFINE:([Expr1003]=MAX([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
            |--Top(TOP EXPRESSION:((1)))
                 |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME_D] as [isc].[DATETIME_D]>=[@dt1] AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME_D] as [isc].[DATETIME_D]<=[@dt2]) ORDERED BACKWARD)


Сейчас есть предположение, что если в кластеризованный индекс по полю GLOBAL_ID включить дату, возможно все будет работать быстрее.
Но т.к. как база в бою, эксперименты особо проводить не хочется. Страшно! :(

К сообщению приложен файл. Размер - 22Kb
25 ноя 13, 08:52    [15183345]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
Сейчас есть предположение, что если в кластеризованный индекс по полю GLOBAL_ID включить дату, возможно все будет работать быстрее.
Мда, вы вообще не понимаете, что такое инедкс :-(

Нужно сделать интекс по datetime_D
AlexeyMish
Я не администратор БД, эта задача для меня прикладная. Т.е. ее надо решить, но уходить в дебри изучения архитектуры индексов и идеологически верного проектирования БД, для меня непозволительная роскошь.
Можно нанять специалиста.
25 ноя 13, 09:02    [15183370]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
alexeyvg
Мда, вы вообще не понимаете, что такое инедкс :-(

Нужно сделать интекс по datetime_D
Тьфу, 2 ошибки в однос слове :-)

Нужно сделать индекс по datetime_D
25 ноя 13, 09:03    [15183373]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
1) Прошу прощения, ошибка в посте.
естественно запрос по полю DATETIME.
2) Вариант с наймом специалиста тоже рассматриваю
3) У меня нет уверенности, что в найме будет толк. Т.к. не исключаю, что запрос так долго выполняется просто по причине того, что слишком много данных. Даже по индексированному полю поиск проходит слишком долго.
25 ноя 13, 09:05    [15183383]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
Что такое индекс я поверхностно понимаю.
Я не до конца понимаю, что такое покрывающие индексы, кластеризованные индексы. Когда какие надо использовать. Что лучше куча индексов на каждое поле или один на все поля. В каких случаях что лучше использовать. Имеет ли смысл на таких объемах смотреть в сторону партиционирования или это на производительности не скажется.
Но в эти дебри я лезть не хочу, поэтому прошу помощи в одной маленькой задаче. Для того, чтобы хотя бы понять, имеет смысл заниматься оптимизацией (читай наймом специалиста) или же стоит задуматься над выносом старых данных в некую архивную базу данных. А для оперативных нужд держать данные за последние полгода-год.
25 ноя 13, 09:11    [15183422]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
1) Прошу прощения, ошибка в посте.
естественно запрос по полю DATETIME.
Какой запрос:
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[DATETIME] between @dt1 and @dt2  
?

Тогда должен работать индекс
CREATE NONCLUSTERED INDEX [IDX_DATETIME] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC)

Можно попробовать сделать индекс
CREATE NONCLUSTERED INDEX [IDX_DATETIME] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC) INCLUDE (GLOBAL_ID)


AlexeyMish
В ней порядка 24 млн строк
Важна селективность по [DATETIME], т.е. сколько записей будет для значений [DATETIME] between @dt1 and @dt2

Ещё попробуйте выполнить запрос
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[DATETIME] between 'константа 1' and 'константа 2'
Если будет быстро и будет использоваться индекс [IDX_DATETIME], то нужно решать проблему по другому.
25 ноя 13, 09:19    [15183451]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
Имеет ли смысл на таких объемах смотреть в сторону партиционирования или это на производительности не скажется.
Партиционирование используется больше для облегчения обслуживания и загрузки данных, вряд ли вам оно поможет.

AlexeyMish
Для работы с таблицей как обязательно используются поля DATETIME
На эту вашу таблицу ссылки (FK) есть?
Поле [DATETIME] гарантированно будет в любом запросе, в котором хоть как то упоминается эта таблица?
25 ноя 13, 09:25    [15183469]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
alexeyvg
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[DATETIME] between @dt1 and @dt2  
?

Тогда должен работать индекс
CREATE NONCLUSTERED INDEX [IDX_DATETIME] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC)


Судя по приведенным планам индекс работает.

alexeyvg
Можно попробовать сделать индекс
CREATE NONCLUSTERED INDEX [IDX_DATETIME] ON [dbo].[I_STATISTICS_CALL_IN] 
([DATETIME] ASC) INCLUDE (GLOBAL_ID)

Попробую, когда нагрузка упадет. Перенапрягать сейчас базу не хочу, в настоящий момент этот сервер очень активно используется.

alexeyvg
Важна селективность по [DATETIME], т.е. сколько записей будет для значений [DATETIME] between @dt1 and @dt2

В сутки порядка 40тыс строк. Т.е. если в запросе выборка за 10 дней, то около 400 тыс уникальных строк попадает в выборку.

alexeyvg
Ещё попробуйте выполнить запрос
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[DATETIME] between 'константа 1' and 'константа 2'
Если будет быстро и будет использоваться индекс [IDX_DATETIME], то нужно решать проблему по другому.

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

alexeyvg
AlexeyMish
Имеет ли смысл на таких объемах смотреть в сторону партиционирования или это на производительности не скажется.
Партиционирование используется больше для облегчения обслуживания и загрузки данных, вряд ли вам оно поможет.

Я так и понял, когда в пятницу проводил себе ликбез :).

alexeyvg
AlexeyMish
Для работы с таблицей как обязательно используются поля DATETIME
На эту вашу таблицу ссылки (FK) есть?
Поле [DATETIME] гарантированно будет в любом запросе, в котором хоть как то упоминается эта таблица?

FK нет. Поле [DATETIME] будет использоваться. Даже если сейчас не используется, то дописать запросы возможность есть. К счастью несмотря на то, что продукт полукоробочный, возможность написания запросов у меня сохранилась.
25 ноя 13, 09:43    [15183534]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
Судя по приведенным планам индекс работает.
Нет, по приведенным планам видим полное сканирование таблицы:
Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN]
AlexeyMish
В первый раз было быстро, я сообразил поменять дату, чтоб не использовался кеш сервера. Время выполнения запроса практически не изменилось. (По прежнему слишком долго)
ИМХО дело не в кеше, а в постоянном сканировании.

И вообще, точно приводите запросы и планы.
По плану тоже используется поиск по полю [DATETIME_D], а не по [DATETIME]
Такие мелкие опечатки и непонимания могут приводить к многодневным бесплодным поискам проблемы там, где её нет :-)

Вы ещё раз запрустите запрос с константами вместо переменных, выложите сюда запрос и его план.
25 ноя 13, 09:56    [15183612]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
declare @Globalid_min bigint, @Globalid_max bigint
declare @dt1 float,	@dt2 float

set @dt1	=CONVERT(float,CONVERT(datetime,'20131109 12:00:00'))+2--дата от 
set @dt2	= cast(cast('20131122' as datetime) as float)+2--дата до

Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[datetime] between @dt1 and @dt2  
Select @Globalid_min as min, @Globalid_max as max


  |--Nested Loops(Inner Join)
       |--Stream Aggregate(DEFINE:([Expr1002]=MIN([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
       |    |--Top(TOP EXPRESSION:((1)))
       |         |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]>=[@dt1] AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]<=[@dt2]) ORDERED FORWARD)
       |--Stream Aggregate(DEFINE:([Expr1003]=MAX([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
            |--Top(TOP EXPRESSION:((1)))
                 |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]>=[@dt1] AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]<=[@dt2]) ORDERED BACKWARD)


К сообщению приложен файл. Размер - 45Kb
25 ноя 13, 10:09    [15183682]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
Пробовал выполнить с константами, картина полностью идентична.
25 ноя 13, 10:13    [15183700]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
С константами.

--SET SHOWPLAN_TEXT ON
--go

declare @Globalid_min bigint, @Globalid_max bigint
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock)
where isc.[datetime] between 41556.5 and 41569  
Select @Globalid_min as min, @Globalid_max as max
--go
--SET SHOWPLAN_TEXT OFF
--go


  |--Nested Loops(Inner Join)
       |--Stream Aggregate(DEFINE:([Expr1002]=MIN([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
       |    |--Top(TOP EXPRESSION:((1)))
       |         |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]>=(4.155650000000000e+004) AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]<=(4.156900000000000e+004)) ORDERED FORWARD)
       |--Stream Aggregate(DEFINE:([Expr1003]=MAX([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[GLOBAL_ID] as [isc].[GLOBAL_ID])))
            |--Top(TOP EXPRESSION:((1)))
                 |--Clustered Index Scan(OBJECT:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[PK_I_STATISTICS_CALL_IN] AS [isc]),  WHERE:([INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]>=(4.155650000000000e+004) AND [INFDATA_STAT].[dbo].[I_STATISTICS_CALL_IN].[DATETIME] as [isc].[DATETIME]<=(4.156900000000000e+004)) ORDERED BACKWARD)


К сообщению приложен файл. Размер - 25Kb
25 ноя 13, 10:26    [15183767]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
В сутки порядка 40тыс строк. Т.е. если в запросе выборка за 10 дней, то около 400 тыс уникальных строк попадает в выборку.
Получается, сервер считает, что выгоднее сканировать, чем использовать индекс.

Попробуйте задать использование инедкса принудительно:
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock, index=IDX_DATETIME)
where isc.[DATETIME] between @dt1 and @dt2  

Ну и потом попробуйте, когда появится возможность, сделать индекс с включённым Global_ID, как я говорил...
25 ноя 13, 10:27    [15183778]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
[DATETIME] [float] NULL,
Просто интересно - почему используется тип float вместо datetime?
Это же неудобно.
25 ноя 13, 10:29    [15183795]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
alexeyvg
Попробуйте задать использование инедкса принудительно:
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  (nolock, index=IDX_DATETIME)
where isc.[DATETIME] between @dt1 and @dt2  

Ну и потом попробуйте, когда появится возможность, сделать индекс с включённым Global_ID, как я говорил...


Прошу прощения, я такого формата запроса никогда не видел.
Буду искать, но паралельно тут спрошу. Сервер меня не понимает.

Msg 1018, Level 15, State 1, Line 8
Incorrect syntax near 'index'. If this is intended as a part of a table hint, A WITH keyword and parenthesis are now required. See SQL Server Books Online for proper syntax.

Если до снижения нагрузки проблема не решится - обязательно попробую. В одиночку бьюсь уже третий день. Если не прислушиваться к советам, боюсь, что сам решить не смогу. =)
25 ноя 13, 10:31    [15183807]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
alexeyvg
AlexeyMish
[DATETIME] [float] NULL,
Просто интересно - почему используется тип float вместо datetime?
Это же неудобно.


Продукт коммерческий. Изначально был взращен на firebird. Потом для нас допилен под MS SQL. Допилен понятно с минимальными затратами времени. Т.е. этот формат можно сказать атавизм, но жить сильно не мешает.
Проще говоря, не виноватый я. Мне такое досталось. =)
25 ноя 13, 10:36    [15183841]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
alexeyvg,
Можно еще посоветоваться?
я тут пытаюсь все таки ликвидировать свою безграммотность в плане MS SQL. И насколько понимаю рекомендации из http://www.gotdotnet.ru/blogs/alexgaas/455/
в моем случае кластерный индекс лучше накладывать на поле не GLOBAL_ID, а сделать покрывающий кластерный индекс (если я правильно понял термины), на поля Global_ID+Datetime.
Суждение сформировано исходя из рекомендации:
автор
4) Ключ должен быть выбран таким образом, чтобы соответствовать большинству запросов выборки по диапазону

и вроде бы не сильно противоречит
автор
2) Создайте как можно более компактный ключ
25 ноя 13, 10:42    [15183871]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
Прошу прощения, я такого формата запроса никогда не видел.
Буду искать, но паралельно тут спрошу. Сервер меня не понимает.

Msg 1018, Level 15, State 1, Line 8
Incorrect syntax near 'index'. If this is intended as a part of a table hint, A WITH keyword and parenthesis are now required. See SQL Server Books Online for proper syntax.
Да путаюсь в синтаксисе, старом, новом... :-)

Наверное так:
Select 
@Globalid_min=min(Global_ID), 
@Globalid_max=MAX(GLOBAL_ID) 
from INFDATA_STAT.dbo.i_statistics_call_in isc  WITH (nolock, INDEX(IDX_DATETIME))
where isc.[DATETIME] between @dt1 and @dt2 
25 ноя 13, 10:42    [15183875]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
в моем случае кластерный индекс лучше накладывать на поле не GLOBAL_ID, а сделать покрывающий кластерный индекс (если я правильно понял термины), на поля Global_ID+Datetime.
Суждение сформировано исходя из рекомендации:
автор
4) Ключ должен быть выбран таким образом, чтобы соответствовать большинству запросов выборки по диапазону
Global_ID+Datetime будет совершенно бесполезным.

У вас же нету условия по Global_ID, а поиск по одному Datetime по этому индексу не может быть сделан.

Идеальным будет неуникальный кластерный индекс по Datetime или уникальный кластерный индекс по Datetime, Global_ID

Но я вам не рискнул такое предлагать, это всё таки слишком большое изменение для уже работающей системы, и к тому же стороннего производителя.
25 ноя 13, 10:47    [15183898]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
aleks2
Guest
AlexeyMish
CREATE TABLE [dbo].[I_STATISTICS_CALL_IN](
 CONSTRAINT [PK_I_STATISTICS_CALL_IN] PRIMARY KEY [s]CLUSTERED [/s](
	[GLOBAL_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


Для работы с таблицей как обязательно используются поля DATETIME.


Дык, сделай, страдалец, правильный кластерный индекс.

 CONSTRAINT [PK_I_STATISTICS_CALL_IN] UNIQUE CLUSTERED 
(
             [DATETIME]
           , [GLOBAL_ID] ASC
)
25 ноя 13, 10:50    [15183904]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
aleks2
Дык, сделай, страдалец, правильный кластерный индекс.
Рискованно такое предлагать...

ТС может быть не в курсе про все запросы в системе...

Хотя да, такой индекс пока видится идеальным, судя по описанию.
25 ноя 13, 10:56    [15183947]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
alexeyvg
aleks2
Дык, сделай, страдалец, правильный кластерный индекс.
Рискованно такое предлагать...
ТС может быть не в курсе про все запросы в системе...
Хотя да, такой индекс пока видится идеальным, судя по описанию.

Про запросы я достаточно в курсе.
Фактически система представляет из себя набор приложений которые занимаются ТОЛЬКО вставкой в базу.
Все работы по выборке данных и работе с ними лежат на мне.
Учитывая, время и сроки за которые провели допиливание системы с firebird до MS SQL вероятность того, что разрабы занимались тюнингом индексов я оцениваю как предельно малую.
Строго говоря, чуть выше я сам пришел к мысли, что этот индекс надо пересоздать, просто с формулировкой у меня не очень. Ибо не специалист.
автор
в моем случае кластерный индекс лучше накладывать на поле не GLOBAL_ID, а сделать покрывающий кластерный индекс (если я правильно понял термины), на поля Global_ID+Datetime.
Суждение сформировано исходя из рекомендации:


Итак, если я решусь на этот шаг. Мне нужно будет
1)удалить PK
автор
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[I_STATISTICS_CALL_IN]') AND name = N'PK_I_STATISTICS_CALL_IN')
ALTER TABLE [dbo].[I_STATISTICS_CALL_IN] DROP CONSTRAINT [PK_I_STATISTICS_CALL_IN]
GO

2) Создать новый
автор
ALTER TABLE [dbo].[I_STATISTICS_CALL_IN] ADD CONSTRAINT [PK_I_STATISTICS_CALL_IN] PRIMARY KEY CLUSTERED
(
[DATETIME], [GLOBAL_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO


Предварительно помолившись и создав бекап.
Все верно?
25 ноя 13, 11:04    [15184002]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31443
AlexeyMish
Все верно?
Да.
25 ноя 13, 11:20    [15184097]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
AlexeyMish,

alexeyvg
AlexeyMish
В сутки порядка 40тыс строк. Т.е. если в запросе выборка за 10 дней, то около 400 тыс уникальных строк попадает в выборку.
Получается, сервер считает, что выгоднее сканировать, чем использовать индекс.

А сколько у вас всего строк в таблице? И как часто вы вручную обновляете статистику?
25 ноя 13, 21:30    [15188054]     Ответить | Цитировать Сообщить модератору
 Re: Прошу помощи с построением индексов.  [new]
AlexeyMish
Member

Откуда:
Сообщений: 71
Mind,
около 24 млн строк.
вручную не обновлял. Как я говорил, я не дбошник. Приходится этим заниматься, т.к. больше особо некому.
25 ноя 13, 21:33    [15188066]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить