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

Откуда:
Сообщений: 27
Против команды знатоков играет MS SQL 2014 12.0.5000.0 (X64).

Имеем 2 таблицы:
+

CREATE TABLE [cma].[User](
	[UserId] [int] IDENTITY(1,1) NOT NULL,
	[Login] [nvarchar](255) NOT NULL,
	[UserName] [nvarchar](50) NULL,
PRIMARY KEY CLUSTERED 
(
	[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [AK_User_Login] UNIQUE NONCLUSTERED 
(
	[Login] 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

CREATE TABLE [cma].[Session]
(
	[SessionId] [uniqueidentifier] NOT NULL,
	[CreateDate] [datetime] NOT NULL,
	[UserId] [int] NOT NULL,
	[ValidTill] [datetime] NOT NULL,
	[DeviceToken] [nvarchar](255) COLLATE Cyrillic_General_100_BIN2 NOT NULL,
	[UserAgent] [nvarchar](500) COLLATE Cyrillic_General_100_BIN2 NULL,

INDEX [idx_Session_ProfileId] NONCLUSTERED 
(
	[UserId] ASC
),
 PRIMARY KEY NONCLUSTERED HASH 
(
	[SessionId]
)WITH ( BUCKET_COUNT = 1048576)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_ONLY )

GO

ALTER TABLE [cma].[Session] ADD  DEFAULT (getdate()) FOR [CreateDate]
GO



Пишу вот такой простой запрос:

SELECT 
    [Project1].[UserId]			AS [UserId], 
    [Project1].[Login]			AS [Login], 
    [Project1].[UserName]		AS [UserName], 
    [Project1].[C1]				AS [C1], 
    [Project1].[SessionId]		AS [SessionId], 
    [Project1].[CreateDate]		AS [CreateDate], 
    [Project1].[UserId1]		AS [UserId1], 
    [Project1].[ValidTill]		AS [ValidTill], 
    [Project1].[DeviceToken]	AS [DeviceToken], 
    [Project1].[UserAgent]		AS [UserAgent]
FROM 
( 
   SELECT 
        [Extent1].[UserId]		AS [UserId], 
        [Extent1].[Login]		AS [Login], 
        [Extent1].[UserName]	AS [UserName], 
        [Extent2].[SessionId]	AS [SessionId], 
        [Extent2].[CreateDate]	AS [CreateDate], 
        [Extent2].[UserId]		AS [UserId1], 
        [Extent2].[ValidTill]	AS [ValidTill], 
        [Extent2].[DeviceToken] AS [DeviceToken], 
        [Extent2].[UserAgent]	AS [UserAgent], 
        CASE WHEN ([Extent2].[UserId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
   FROM  
	[cma].[User] AS [Extent1]
        LEFT OUTER JOIN [cma].[Session] AS [Extent2] 
	        ON [Extent1].[UserId] = [Extent2].[UserId]
)  AS [Project1]    
ORDER BY 
	[Project1].[UserId] ASC,
	[Project1].[C1] ASC


В каждой таблице по две записи, и при этом запрос выполняется... барабанная дробь.... 4 минуты!
Судя по плану и по результатам вот этого
+
SELECT  wt.session_id, 
    ot.task_state, 
    wt.wait_type, 
    wt.wait_duration_ms, 
    wt.blocking_session_id, 
    wt.resource_description, 
    es.[host_name], 
    es.[program_name] 
FROM  sys.dm_os_waiting_tasks  wt  
INNER  JOIN sys.dm_os_tasks ot ON ot.task_address = wt.waiting_task_address 
INNER JOIN sys.dm_exec_sessions es ON es.session_id = wt.session_id 
WHERE es.is_user_process =  1
and wt.session_id = 73 


73 SUSPENDED RESOURCE_SEMAPHORE 74023


он ждет выделения памяти под запрос, так? Но с чего такой дикий расход памяти, если всего 4 строки в таблицах?
Ну и собственно, как ускорить это дело?
20 апр 17, 19:34    [20420040]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31355
Newbie001
он ждет выделения памяти под запрос, так? Но с чего такой дикий расход памяти, если всего 4 строки в таблицах?
Вы же указали BUCKET_COUNT = 1048576
Вот он выделяет, и сканирует их в запросах, даже пустые.
https://msdn.microsoft.com/ru-ru/library/dn494956(v=sql.120).aspx
Чем выше значение числа контейнеров, тем больше пустых контейнеров будет в индексе. Это влияет на использование памяти (8 байт на сегмент) и производительность просмотров таблиц, так как в процессе просмотра таблицы сканируется каждый контейнер.
20 апр 17, 19:58    [20420085]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4727
Newbie001,

INDEX [idx_Session_ProfileId] NONCLUSTERED
(
[UserId] ASC
),

замените на HASH индекс с правильным BUcketCount .

Но не факт, что в один поток вы получите выигрыш. Вот в 10 параллельных запросов InMemery против Physical должны дать эффект
20 апр 17, 20:00    [20420089]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
Newbie001
Member

Откуда:
Сообщений: 27
Спасибо, пойду читать про bucket count`ы...
21 апр 17, 00:21    [20420624]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3708
alexeyvg
Newbie001
он ждет выделения памяти под запрос, так? Но с чего такой дикий расход памяти, если всего 4 строки в таблицах?
Вы же указали BUCKET_COUNT = 1048576
Вот он выделяет, и сканирует их в запросах, даже пустые.
https://msdn.microsoft.com/ru-ru/library/dn494956(v=sql.120).aspx
Чем выше значение числа контейнеров, тем больше пустых контейнеров будет в индексе. Это влияет на использование памяти (8 байт на сегмент) и производительность просмотров таблиц, так как в процессе просмотра таблицы сканируется каждый контейнер.


А если указать меньше, чем реально записей? как лучше настраивать BUCKET_COUNT для предполагаемых данных?
24 апр 17, 14:42    [20429422]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
o-o
Guest
Ролг Хупин
А если указать меньше, чем реально записей? как лучше настраивать BUCKET_COUNT для предполагаемых данных?

Олег, я даже помню, что вопрос про число бакетов задавал именно ты.
у меня там аж цитата по этому поводу:
Использовал Memory Optimized таблицу вместо #временной
24 апр 17, 15:00    [20429520]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4727
Ролг Хупин
А если указать меньше, чем реально записей? как лучше настраивать BUCKET_COUNT для предполагаемых данных?


Почитайте и наложите на InMemory

https://ru.wikipedia.org/wiki/Хеш-таблица
24 апр 17, 16:09    [20429990]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31355
Ролг Хупин
А если указать меньше, чем реально записей? как лучше настраивать BUCKET_COUNT для предполагаемых данных?
Там же написано.
Идеально - если BUCKET_COUNT равно количеству записей.
Если BUCKET_COUNT будет больше, то будет больше сканирования при поиске и больше бесполезно занимаемой памяти.
Если BUCKET_COUNT будет меньше, то после каждого поиска по ключу будет ещё сравнение всех значений для этого бакета.
То есть если отклонение BUCKET_COUNT от количества записей небольшое, то потери будут незаметны.
Но если отклонение в 250 тысяч раз, как у вас, то потери будут соответствующие.
24 апр 17, 16:14    [20430021]     Ответить | Цитировать Сообщить модератору
 Re: InMemory - баг? фича?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3708
alexeyvg
Ролг Хупин
А если указать меньше, чем реально записей? как лучше настраивать BUCKET_COUNT для предполагаемых данных?
Там же написано.
Идеально - если BUCKET_COUNT равно количеству записей.
Если BUCKET_COUNT будет больше, то будет больше сканирования при поиске и больше бесполезно занимаемой памяти.
Если BUCKET_COUNT будет меньше, то после каждого поиска по ключу будет ещё сравнение всех значений для этого бакета.
То есть если отклонение BUCKET_COUNT от количества записей небольшое, то потери будут незаметны.
Но если отклонение в 250 тысяч раз, как у вас, то потери будут соответствующие.


да... багофича какая-то
24 апр 17, 16:48    [20430219]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить