Блог инженеров технической поддержки SQL Server. Microsoft. Россия

Блог инженеров технической поддержки SQL Server. Microsoft. Россия

Выполнение join и транзакций между различными базами в In-Memory database.

Внимательно прочитав описание на In-memory базы данных мы можем обнаружить большое количество ограничений (http://msdn.microsoft.com/en-us/library/dn247639.aspx), присутствующих в настоящее время. Часть этих ограничений, быстрее всего, так и останется в будущем, но часть исчезнет.

Одно из ограничений связано с невозможностью выполнять Cross-database транзакции и запросы (http://msdn.microsoft.com/en-us/library/dn584627.aspx) если в эти запросы вовлечены In-memory таблицы.

Приведем пример.

При попытке выполнения запроса, приведенного ниже, появляется сообщение об ошибке.

select *
from [hkNorthwind].[dbo].[ShoppingCart_Hash] hksch
join [Northwind].[dbo].[ShoppingCart] nsc
on hksch.ShoppingCartId = nsc.ShoppingCartId

Msg 41317, Level 16, State 5, Line 1 A user transaction that accesses memory optimized tables or natively compiled procedures cannot access more than one user database or databases model and msdb, and it cannot write to master.

Сообщение указывает на невозможность выполнения cross-database запроса между in-memory таблицей ([ShoppingCart_Hash])  и обычной таблицей размещенной в другой базе данных.

Для обхода этого ограничения предлагается использовать табличную переменную, перемещая данные в нее (http://msdn.microsoft.com/en-us/library/dn584627.aspx).

Однако при большом количестве строк этот подход не всегда удобен и нивелирует преимущества in-memory таблиц.

Возможно использование другого пути.

Возможность эта основана, на особенностях работы ODBC (OLEDB) провайдеров, которые и позволяют  частично обойти это ограничение.

Пример.

Оформим локальный сервер как Linked Server.

EXEC master.dbo.sp_addlinkedserver @server = N'(LOCAL)\SQL2014′, @srvproduct=N’SQL Server’

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'(LOCAL)\SQL2014′,@useself=N’True’,@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL

 

Выполним запрос еще раз слегка его подправив.

select *
from [hkNorthwind].[dbo].[ShoppingCart_Hash] hksch
join [(LOCAL)\SQL2014].[Northwind].[dbo].[ShoppingCart] nsc
on hksch.ShoppingCartId = nsc.ShoppingCartId

 Запрос будет выполнен.

Однако, если вы представите запрос в формате приведенном ниже, то получите сообщение об ошибке.

select *
from [(LOCAL)\SQL2014].[hkNorthwind].[dbo].[ShoppingCart_Hash] hksch
join [Northwind].[dbo].[ShoppingCart] nsc
on hksch.ShoppingCartId = nsc.ShoppingCartId

Msg 12323, Level 16, State 95, Line 1 Distributed Queries and Multiple Active Result Sets (MARS) are not supported with memory optimized tables.

Т.е. in-memory таблица не может быть получена с удаленного сервера для выполнения любых операций на локальном сервере.

Даже такой запрос вернет эту же самую ошибку.

select *
from [(LOCAL)\SQL2014].[hkNorthwind].[dbo].[ShoppingCart_Hash] hksch

 Msg 12323, Level 16, State 95, Line 1 Distributed Queries and Multiple Active Result Sets (MARS) are not supported with memory optimized tables.

Обращение к OPENQUERY ничего не изменит.

SELECT *
FROM OPENQUERY([(LOCAL)\SQL2014], ‘select * from [hkNorthwind].[dbo].[ShoppingCart_Hash]’)

OLE DB provider “SQLNCLI11” for linked server “(LOCAL)\SQL2014” returned message “Deferred prepare could not be completed.”.
Msg 12323, Level 16, State 95, Line 1 Distributed Queries and Multiple Active Result Sets (MARS) are not supported with memory optimized tables.

Таким образом частично это ограничение может быть обойдено формированием запроса к стандартной таблице, размещенной на удаленном сервере, с локального сервера, где размещена in-memory таблица.

 Александр Каленик, Senior Premier Field Engineer (PFE), MSFT (Russia)