【问题标题】:Slow query when connecting to linked server连接到链接服务器时查询慢
【发布时间】:2010-11-18 11:16:06
【问题描述】:

我有这个问题

UPDATE linkeddb...table SET field1 = 'Y' WHERE column1 = '1234'

选择和更新一行需要 23 秒

但如果我使用 openquery(我不想这样做),那么它只需要半秒钟。

我不想使用 openquery 的原因是我可以安全地将参数添加到我的查询中并避免 SQL 注入。

有人知道它运行如此缓慢的任何原因吗?

【问题讨论】:

  • 查询执行计划有什么线索吗?或者您可以设置 SQL Profiler 来观察数据库并查看 openquery 的不同之处。

标签: asp.net sql sql-server linked-server openquery


【解决方案1】:

这里有一个替代方案。在远程服务器上创建一个存储过程以执行更新,然后从本地实例调用该过程。

/* On remote server */
create procedure UpdateTable
    @field1 char(1),
    @column1 varchar(50)
as
    update table
        set field1 = @field1
        where column1 = @column1
go

/* On local server */
exec linkeddb...UpdateTable @field1 = 'Y', @column1 = '1234'

【讨论】:

  • @Joe - 存储过程基本上只是数据库的函数/方法?
  • @orokusaki:是的,你可以这么想。
  • @Joe 由于删除了解析和编译时间,这只会稍微快一点。 @orokusaki 它仍然比您的方法更好,因为它可以让数据库保护自己免受 sql 注入。您还可以设置权限,使用户不能直接更新表,只能通过 SP 进行。
  • @Overflow:实际上,随着执行更新的工作负载转移到远程服务器的 SQL 引擎,我预计会有更显着的改进。在 OP 的当前版本中,本地 SQL 引擎正在尝试更新远程资源。
  • @Joe,这种行为是否取决于特定的 rdbms 或驱动程序?我运行了两个版本,使用wireshark查看网络上的数据,都导致查询发送到服务器,数据发回。如果本地 sql 引擎正在运行查询,我应该期待什么?我曾设想将数据获取到本地缓存并发送回批量更新的数据,或者逐行检索和更新。
【解决方案2】:

如果您正在寻找为什么Linchi Shea's Blog 提供了一种可能性:

创建最佳查询计划时 您正在使用链接的表格 服务器,查询处理器必须有 数据分布统计 链接服务器。有限制的用户 任何列的权限 表可能没有足够的 获得所有有用的权限 统计数据,可能会收到更少 高效的查询计划和体验 表现不佳。如果链接 server 是 SQL Server 的一个实例,用于 获得所有可用的统计数据, 用户必须拥有该表或成为成员 sysadmin 固定服务器角色的 db_ownerfixed 数据库角色,或 db_ddladmin 固定数据库角色 链接服务器。

(由于 Linchi 的帖子,此说明已添加到最新的 BooksOnline SQL 文档中)。

换句话说,如果链接服务器设置为具有有限权限的用户,则 SQL 无法检索表的准确统计信息,并且可能会选择糟糕的方法来执行查询,包括检索所有行。

这是关于链接服务器查询性能的related SO question。他们的结论是:使用 OpenQuery 以获得最佳性能。

更新:来自 Linchi 博客的一些 additional excellent posts 关于链接服务器性能的信息。

【讨论】:

    【解决方案3】:

    column1 是主键吗?可能不是。尝试使用主键(其中 PK_field=xxx)选择要更新的记录,否则(有时?)将读取所有记录以查找要更新的记录的 PK。

    【讨论】:

    • 我很确定 column1 是主键,但是查看 SQL 查询分析器中的执行计划,它显示远程扫描花费的时间最长,因此它似乎正在遍历所有 40,000 条记录.
    • 嗯,如果你的 PK 是 (n)varchar,那么你可能有一些排序规则问题(我的意思是 SQL 不使用这样的索引,因为它不知道排序规则等等)。不过,我没有使用非整数 PK 字段的经验。
    • @Jamie,我赞同 Arvo 的整理理论是一个潜在问题
    【解决方案4】:

    column1 是 varchar 字段吗?这就是为什么你用单引号括住值 1234 ?或者这只是您问题中的一个错字?

    【讨论】:

    • 如果我在查询分析器中运行不带引号的查询,我会收到错误,并且我认为 column1 是一个 varchar 字段
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2014-04-16
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多