我有一个特定的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;
我在简单的联合查询方面做了很多工作,但之前从未有过......
答案 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,我认为您将能够重构这样的全部内容:
答案 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)
当你升迁时,你确保表格被正确编入索引吗?如果使用得当,索引会极大地加快查询速度(注意它们也可能会减慢插入/更新/删除速度,因此请仔细选择要索引的内容)