Bob*_*bst 8 sql-server sql-server-2000
这个程序
create proc dbo.Get_Accounts as
begin
declare @current_date datetime
set @current_date = dbo.fn_currdate()
select [fields]
into dbo.current_accounts
from linkedserver.database.dbo.accounts
where date = @current_date
end
Run Code Online (Sandbox Code Playgroud)
10 分钟后不断失败,并显示以下错误消息:
服务器:消息 7399,级别 16,状态 1,第 1 行 OLE DB 提供程序“SQLOLEDB”报告了错误。由于达到资源限制,提供程序终止了执行。[OLE/DB 提供程序返回消息:超时已过期] OLE DB 错误跟踪 [OLE/DB 提供程序 'SQLOLEDB' ICommandText::Execute 返回 0x80040e31:由于达到资源限制,提供程序终止执行。]。
但是,当我在具有硬编码日期的交互式查询窗口中从同一个数据库(不在远程数据库上)运行相同的查询时:
select [fields]
into dbo.current_accounts
from linkedserver.database.dbo.accounts
where date = '1/20/2012'
Run Code Online (Sandbox Code Playgroud)
它在 30 秒后返回。
本地服务器是 SQLSERVER 2008,远程服务器是 SQLSERVER 2000。
我们做了以下工作,但无济于事:
问题
Mit*_*eat 11
您可以打开跟踪标志 7300,这可能会为您提供更详细的错误消息
代表性查询返回多少行?两台服务器之间的网络连接有多快/有多可靠?
传输大型数据集的时间可能太长(超出实际查询时间)。您可以提高超时值。
您可以尝试重新配置超时设置,如下所示:
将远程登录超时设置为 300 秒:
sp_configure 'remote login timeout', 300
go
reconfigure with override
go
Run Code Online (Sandbox Code Playgroud)
将远程查询超时设置为 0(无限等待):
sp_configure 'remote query timeout', 0
go
reconfigure with override
go
Run Code Online (Sandbox Code Playgroud)
更新:SQL Server 2012 SP1 以后:具有SELECT
权限的用户将能够访问DBCC SHOW_STATISTICS
,这将提高链接服务器上的只读性能。参考:https : //msdn.microsoft.com/en-us/library/ms174384(v= sql.110) .aspx
更新:您说得对,这不是数据大小或连接速度。它在我模糊的记忆中敲响了警钟,我记得我在哪里见过它:应用程序慢,SSMS 快?(链接服务器的问题)。这不是参数嗅探,而是统计信息本身丢失(由于权限),导致使用错误的查询计划:
您可以看到估计值不同。当我以系统管理员身份运行时,估计是 1 行,这是一个正确的数字,因为 Northwind 中没有订单 ID 超过 20000 的订单。但是当我以普通用户身份运行时,估计是 249 行。我们将此特定数字识别为 830 个订单的 30%,或者当优化器没有信息时对不等式运算的估计。以前,这是由于未知变量值造成的,但在这种情况下,没有任何变量是未知的。不,缺少的是统计数据本身。
只要查询只访问本地服务器中的表,优化器始终可以访问查询中所有表的统计信息;没有额外的权限检查。但这与链接服务器上的表不同。当 SQL Server 访问链接服务器时,没有仅用于服务器间通信的秘密协议。不,SQL Server 使用标准的 OLE DB 接口连接服务器,可以是其他 SQL Server 实例、Oracle、文本文件或您自制的数据源,并像任何其他用户一样连接。究竟如何检索统计信息取决于数据源和相关的 OLE DB 提供程序。在这种情况下,提供程序是 SQL Server Native Client,它分两步检索统计信息。(您可以通过对远程服务器运行 Profiler 来查看这一点)。首先,提供程序运行过程 sp_table_statistics2_rowset,它返回有关列统计信息的信息,以及它们的基数和密度信息。在第二步中,提供程序运行 DBCC SHOW_STATISTICS,这是一个返回完整分布统计信息的命令。(我们将在本文后面详细介绍此命令。)这里有一个要点:要运行 DBCC SHOW_STATISTICS,您必须是服务器角色 sysadmin 或任何数据库角色 db_owner 或 db_ddladmin 的成员。
这就是为什么我得到了不同的结果。以系统管理员身份运行时,我得到了完整的分布统计信息,表明没有订单 ID > 20000 的行,估计只有一行。(回想一下,优化器从不假设统计数据为零行。)但是当以普通用户身份运行时,DBCC SHOW_STATISTICS 失败并出现权限错误。这个错误没有传播,而是优化器接受没有统计数据并使用默认假设。由于它确实获得了基数信息,它了解到远程表有 830 行,因此估计为 249 行。
每当您遇到性能问题,其中包括访问链接服务器的查询在应用程序中速度很慢,但当您从 SSMS 测试它时它运行得很快,您应该始终调查远程数据库的权限不足是否可能是原因。(请记住,对链接服务器的访问可能不会在查询中公开,但可能隐藏在视图中。)如果您确定远程数据库的权限是问题,您可以采取什么措施?
您可以将用户添加到角色 db_ddladmin,但由于这赋予他们添加和删除表的权利,因此不建议这样做。
默认情况下,当用户连接到远程服务器时,他们以自己的身份连接,但您可以使用 sp_addlinkedsrvlogin 设置登录映射,以便用户映射到在 db_ddladmin 中具有成员资格的代理帐户。请注意,此代理帐户必须是 SQL 登录名,因此如果远程服务器未启用 SQL 身份验证,则这不是一个选项。从安全角度来看,这个解决方案也有些可疑,尽管它比之前的建议更好。
在某些情况下,您可以使用 OPENQUERY 重写查询以强制对远程服务器进行评估。如果查询包含多个远程表,这可能特别有用。(但它也可能适得其反,因为优化器现在从远程服务器获取的统计信息更少。)
您当然可以使用完整的提示和计划指南来获得您想要的计划。
最后,您应该问问自己是否需要链接服务器访问权限。也许数据库可以在同一台服务器上?数据可以复制吗?一些其他的解决方案?
归档时间: |
|
查看次数: |
54986 次 |
最近记录: |