【问题标题】:Updating SQL Server table over WAN from Access front end extremely slow从 Access 前端通过 WAN 更新 SQL Server 表非常慢
【发布时间】:2010-12-10 11:31:34
【问题描述】:

我有一个小型数据库,托管在我们的共享主机帐户上,我通过访问 MDE 文件更新该数据库,该文件包含每天通过任务调度程序运行数次的链接 SQL 表。

基本上有一个小型(20 行以下)用户表和一个(目前)1000 行数据表。

基本上,我的 MDE“前端”所做的是将生产数据库中的数据查询到 Access 中的临时表中,从托管服务提供商的两个远程表中删除数据并重新填充它们。所以它链接到两台服务器(一台本地服务器和一台远程服务器),我读到有时这可能会出现问题?

随着越来越多的人要求访问他们的数据,数据正在缓慢增长,目前使用链接表删除/重新填充包含 1000 行的表大约需要 5 分钟。

我已经通过使用 SQL Passthrough 删除远程表数据来缓解部分缓慢。删除几乎是瞬时的。

但是,我不能对 APPEND 做同样的事情,因为我的临时数据只在本地 MDE 文件上,上传它没有意义(它不会比现在更快)。

我想知道如何加快对远程服务器的 APPEND 查询?将 1000 行数据(大约 8 列,几乎没有空值)放在 Excel 中时(几百 KB,可能)并不是很大,所以花费这么长时间的 APPEND 没有意义。

User 和 Datatable 都有一个时间戳数据列,我读过这有助于加快 Access -> SQL 删除/追加,因为 Access 可以检查时间戳而不是逐行比较。

我想就如何加快速度提出一些建议。无论如何,这不是大量的数据。


Private Sub UpdateWebFunc()
On Error GoTo errors
   Dim conn As New ADODB.Connection
   Dim cmd As New ADODB.Command
   Dim rst As New ADODB.Recordset
   Dim rst2 As DAO.Recordset
   Dim qdf As DAO.QueryDef

   conn.ConnectionString = "Blah blah blah here"

   conn.Open

   Set qdf = CurrentDb.QueryDefs("GetWebData")

   Set rst2 = qdf.OpenRecordset
   If Not rst2.BOF And Not rst2.EOF Then
   rst2.MoveFirst
   End If

   With cmd
    .CommandText = ”sp_UpdateWeb”
    .CommandType = adCmdStoredProc
    .ActiveConnection = conn
    .NamedParameters = True
    '.Parameters.Append .CreateParameter("@RETURN_VALUE", adInteger, adParamReturnValue, 0)
    .Parameters.Append .CreateParameter("@SampID", adVarChar, adParamInput, 50)
    .Parameters.Append .CreateParameter("@ReportTitle", adVarChar, adParamInput, 50)
   End With
   conn.BeginTrans
   Do Until rst2.EOF
    cmd.Parameters("@SampID") = rst2!SampID
    cmd.Parameters("@ReportTitle") = rst2!ReportTitle

    cmd.Execute , , adExecuteNoRecords
   rst2.MoveNext
   Loop
   conn.CommitTrans
   conn.Close
Set cmd = Nothing

   rst2.Close
   Set rst2 = Nothing

errors:
   MsgBox "Number: " & Err.Number & vbCr & " Description: " & Err.Description
End Sub

我一直卡在 cmd.execute 并出现语法错误。我已尝试将范围缩小到表中最重要的两个字段,以消除其他冲突。

错误:[Microsoft][ODBC SQL Server Driver]语法错误或访问冲突

这是我的 SP:


USE [MYDB]
GO

SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[sp_UpdateWeb] 
    -- Add the parameters for the stored procedure here
    @SampID VarChar(50),
    @ReportTitle VarChar(50)

AS
BEGIN
    -- Insert statements for procedure here
    INSERT INTO [dbo].[WEB] (SampID, ReportTitle) VALUES (@SampID, @ReportTitle)

END

【问题讨论】:

  • 您可以尝试使用其他工具,以检查问题是由于 Access,还是您的连接或主机。
  • 这可能是一切。我刚刚通过 SQLMS 运行更新,将 5200 行附加到远程主机上的表中,大约需要 6 分钟。 ://
  • 您是否尝试过使用 ADO 进行插入?它可能会绕过 Jet/ACE 将批 INSERT 分解为每条记录一个 INSERT 的错误决定(这是 Jet/ACE 将批 INSERT 发送到 ODBC 服务器数据库的方式)。
  • @David 我没有。我只是对链接的 ODBC 表运行查询。

标签: sql sql-server ms-access


【解决方案1】:

为什么不将远程服务器作为链接服务器附加到您的生产服务器,并完全绕过 Access?我喜欢 Access,但在这种情况下,它是不必要的,直接使用将允许您使用 SQL 代理来自动执行任务。

【讨论】:

  • 这是我没有考虑过的。虽然我不确定我是否知道如何在 SQL 管理控制台中链接表。
  • 没那么复杂...谷歌搜索“sql server linked”或查看msdn.microsoft.com/en-us/library/ff772782.aspx
  • 是的,我明白了。 :) 只是想找出现在做事的最佳方式。
  • @Mindflux:你的结果是什么?
【解决方案2】:

我认为您目前正在使用访问查询附加数据?您可能会尝试蛮力方法并在代码中打开本地表并循环通过该记录集触发每一行的插入语句。您可以将这一切包装在一个事务中以提高性能,您还可以尝试在您调用的 SQL 服务器上创建一个存储过程并传递参数,而不是在本地创建插入语句。

已添加代码示例*

您已经知道如何打开本地表,因此我将使用 presto 代码。您可以(有些人认为应该)将 DAO 用于本地访问表。然后在这样的 ADO 连接上触发存储过程

DIM cmd as NEW ADODB.Command
Dim dbCon as NEW ADODB.Connection

dbCon.ConnectionString = “Your connection string to the SQL server”
dbCon.Open

‘Setup the command
With CMD
 .CommandText=”spYour_stored_procedure”
 .CommandType=adCmdStoredProc
 .ActiveConnection=dbCon
 .NamedParameters=True
 .Parameters.Append .CreateParameter("@YourIntField", adInteger, adParamInput, 0, 123456)
 .Parameters.Append .CreateParameter("@YourTextField", adVarChar, adParamInput, 20, “Badger”)
 ‘keep on adding parameters
End With
dbcon.BeginTrans
Do until YourDAORecordset.EOF
 cmd.Parameters(“@YourIntField”)= YourDAORecordset.YourField
 cmd.Parameters(“@YourTextField”)=” YourDAORecordset.YourOtherField
 cmd.Execute , , adExecuteNoRecords
 YourDAORecordset.MoveNext
Loop
dbcon.CommitTrans
Dbcon.close
Set cmd=nothing

【讨论】:

  • 是的,我正在使用 Access 进行附加。我认为拥有数百个插入物不会比我目前的情况更好吗?这或多或少是查询最终会做什么?
  • 当您从 Access 对 ODBC 链接数据库运行批处理 INSERT 时,Jet/ACE 将批处理 INSERT 转换为一系列 INSERT,每个 INSERT 一行。这就是为什么它很慢。但它也完全等同于遍历记录集并一次插入一条记录,所以这个建议根本不会加快速度。
  • @David 这正是我的想法。推荐?
  • 关于拥有服务器端存储过程和调用的部分仍然存在,有助于提高性能。只需确保在循环之前设置命令对象,并且只在循环期间更改参数。另外,我应该在使用 ADO 打开 SQL 服务器表的代码时说。
  • 凯文。好吧,我知道你要怎么处理这个了。我还没有处理过任何这样的存储过程,或者 ADO(我以前使用过 DAO 循环)。您介意提供两者的示例吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多