Выполнение join и транзакций между различными базами в In-Memory database.
Внимательно прочитав описание на In-memory базы данных мы можем обнаружить большое количество ограничений (https://msdn.microsoft.com/en-us/library/dn247639.aspx), присутствующих в настоящее время. Часть этих ограничений, быстрее всего, так и останется в будущем, но часть исчезнет.
Одно из ограничений связано с невозможностью выполнять Cross-database транзакции и запросы (https://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]) и обычной таблицей размещенной в другой базе данных.
Для обхода этого ограничения предлагается использовать табличную переменную, перемещая данные в нее (https://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)
Comments
- Anonymous
July 15, 2014
It seems also another alternative is to wrap the external db reference in a straight view and use the view in the join - Anonymous
August 06, 2014
The comment has been removed