MS Access中本地服务器上的慢速SQL代码

时间:2008-11-11 15:18:43

标签: sql ms-access

我有一个特定的SQL语句需要大约30秒才能执行,我想知道是否有人可以看到它的问题,或者我需要额外的索引。

代码位于Access中的子窗体上,该窗体显示的结果取决于主窗体中五个字段的内容。表中有近5000条记录正在被查询。 Access项目是从实际SQL服务器上的终端服务器会话中存储和运行的,因此我认为这不是一个网络问题,并且还有另一种形式非常类似于使用相同类型的查询...

由于

PG

SELECT TabDrawer.DrawerName, TabDrawer.DrawerSortCode, TabDrawer.DrawerAccountNo, TabDrawer.DrawerPostCode, QryAllTransactons.TPCChequeNumber, tabdrawer.drawerref
FROM TabDrawer LEFT JOIN QryAllTransactons ON  TabDrawer.DrawerRef=QryAllTransactons.tpcdrawer
WHERE (Forms!FrmSearchCompany!SearchName Is Null 
      Or [drawername] Like Forms!FrmSearchCompany!SearchName & "*") 
      And (Forms!FrmSearchCompany.SearchPostcode Is Null 
      Or [Drawerpostcode] Like Forms!FrmSearchCompany!Searchpostcode & "*") 
      And (Forms!FrmSearchCompany!SearchSortCode Is Null 
      Or [drawersortcode] Like Forms!FrmSearchCompany!Searchsortcode & "*") 
      And (Forms!FrmSearchCompany!Searchaccount Is Null 
      Or [draweraccountno] Like Forms!FrmSearchCompany!Searchaccount & "*") 
      And (Forms!FrmSearchCompany!Searchcheque Is Null 
      Or [tpcchequenumber] Like Forms!FrmSearchCompany!Searchcheque & "*");
    ");

修改

Hold up似乎在构成QryAllTransactons查询的union查询中。

SELECT 
  "TPC" AS Type, 
  TabTPC.TPCRef, 
  TabTPC.TPCBranch, 
  TabTPC.TPCDate, 
  TabTPC.TPCChequeNumber, 
  TabTPC.TPCChequeValue, 
  TabTPC.TPCFee, 
  TabTPC.TPCAction,
  TabTPC.TPCMember, 
  tabtpc.tpcdrawer,
  TabTPC.TPCUser,
  TabTPC.TPCDiscount,
  tabcustomers.*
FROM 
  TabTPC 
  INNER JOIN TabCustomers ON TabTPC.TPCMember = TabCustomers.CustomerID

UNION ALL 

SELECT 
 "CTP" AS Type, 
  TabCTP.CTPRef, 
  TabCTP.CTPBranch, 
  TabCTP.CTPDate, 
  TabCTP.CTPChequeNumb, 
  TabCTP.CTPAmount, 
  TabCTP.CTPFee, 
  TabCTP.CTPAction,
  TabCTP.CTPMember,
  0 as CTPXXX,
  TabCTP.CTPUser,
  TabCTP.CTPDiscount, 
  TABCUSTOMERS.*
FROM 
  TabCTP  
  INNER JOIN TabCustomers ON Tabctp.ctpMember = TabCustomers.CustomerID;

我在简单的联合查询方面做了很多工作,但之前从未有过......

6 个答案:

答案 0 :(得分:2)

两件事。由于这是一个带有SQL Server后端的Access数据库,因此您可以通过将其转换为存储过程来获得相当大的速度提升。

其次,你真的需要返回所有这些字段,特别是在tabCustomers表中吗?永远不要返回比实际打算使用更多的字段,这样可以提高性能。

答案 1 :(得分:1)

首先,尝试压缩和修复.mdb文件。

然后,简化WHERE子句:

WHERE
  [drawername] Like Nz(Forms!FrmSearchCompany!SearchName, "") & "*"
  And 
  [Drawerpostcode] Like Nz(Forms!FrmSearchCompany!Searchpostcode, "") & "*"
  And 
  [drawersortcode] Like Nz(Forms!FrmSearchCompany!Searchsortcode, "") & "*"
  And 
  [draweraccountno] Like Nz(Forms!FrmSearchCompany!Searchaccount, "") & "*"
  And 
  [tpcchequenumber] Like Nz(Forms!FrmSearchCompany!Searchcheque, "") & "*"

它仍然运行缓慢吗?

修改

事实证明,问题并不明确,因为它是一个带有SQL Server后端的大型Access数据库和一个Access Project前端。

这对整个问题提出了不同的看法。

您能否详细解释 这个整个查询的用途?

如果您使用它来填充某些表单或报表的RecordSource,我认为您将能够重构这样的全部内容:

  • 在返回正确数据的SQL服务器上创建视图
  • 使用SQL语法查询该视图,而不是使用Access语法
  • 让服务器对其进行排序

答案 2 :(得分:0)

QryAllTransactons中有多少行?

如果你的结果返回0行,那么Access可能会立即看到并停止,但如果它返回一行,那么它需要拉入QryAllTransactons的整个结果集,以便它可以在内部进行连接。这将是我对发生的事情的第一次猜测。

通常最好在SQL Server上进行连接。尝试创建一个执行LEFT OUTER JOIN的视图并对其进行查询。

即使Access在SQL Server本身上运行并最大限度地减少网络流量,您的目标也只是向Access发送它绝对需要的内容。否则一个大表仍会占用内存等。

答案 3 :(得分:0)

您是否尝试过运行联合中的每个子查询?通常,优化器不会花费太多时间来检查union元素之间的效率 - 每个元素都有自己的优点。

鉴于这一事实,您还可以将“IF”逻辑放入过程代码中,并以某种可能的发现顺序运行每个测试,而不会产生更多调用的额外开销。

答案 4 :(得分:0)

摆脱像运营商这样的人。

在您的情况下,您不需要它们。只需检查字段是否以给定值开头,您可以执行以下操作:

Left([field], Len(value)) = value

应用于您的查询的此方法看起来像这样(为了更好的可读性,进行了一些重新格式化):

SELECT
  TabDrawer.DrawerName, 
  TabDrawer.DrawerSortCode, 
  TabDrawer.DrawerAccountNo, 
  TabDrawer.DrawerPostCode, 
  QryAllTransactons.TPCChequeNumber, 
  TabDrawer.DrawerRef
FROM
  TabDrawer 
  LEFT JOIN QryAllTransactons 
    ON TabDrawer.DrawerRef = QryAllTransactons.TpcDrawer
WHERE 
  (Forms!FrmSearchCompany!SearchName Is Null 
  Or Left([drawername], Len(Forms!FrmSearchCompany!SearchName)) = Forms!FrmSearchCompany!SearchName)
And
  (Forms!FrmSearchCompany.SearchPostcode Is Null 
  Or Left([Drawerpostcode], Len(Forms!FrmSearchCompany!Searchpostcode)) = Forms!FrmSearchCompany!Searchpostcode) 
And 
  (Forms!FrmSearchCompany!SearchSortCode Is Null 
  Or Left([drawersortcode], Len(Forms!FrmSearchCompany!Searchsortcode)) = Forms!FrmSearchCompany!Searchsortcode) 
And 
  (Forms!FrmSearchCompany!Searchaccount Is Null 
  Or Left([draweraccountno], Len(Forms!FrmSearchCompany!Searchaccount)) = Forms!FrmSearchCompany!Searchaccount) 
And 
  (Forms!FrmSearchCompany!Searchcheque Is Null 
  Or Left([tpcchequenumber], Len(Forms!FrmSearchCompany!Searchcheque)) = Forms!FrmSearchCompany!Searchcheque)

请注意,您要比较区分大小写。我不完全确定MS-Access中的like运算符是否不区分大小写。如果需要,将两个字符串转换为大写或小写。

答案 5 :(得分:0)

当你升迁时,你确保表格被正确编入索引吗?如果使用得当,索引会极大地加快查询速度(注意它们也可能会减慢插入/更新/删除速度,因此请仔细选择要索引的内容)