JET SQL性能/SQL理解

JET SQL性能/SQL理解,sql,ms-access,jet,Sql,Ms Access,Jet,这不是一个需要回答的问题,更多的是关于为什么会发生这种情况的疑问 我在一个表中有一个字段,该字段填充了“Y”或“N”,我有一个查询,该查询只需要获取该字段的值并弹出到另一个表中 该表中约有25000条记录 下面的查询运行大约需要25秒 UPDATE ObjectivesApproved INNER JOIN Approved ON ObjectivesApproved.ID = Approved.ID SET ObjectivesApproved.F

这不是一个需要回答的问题,更多的是关于为什么会发生这种情况的疑问

我在一个表中有一个字段,该字段填充了“Y”或“N”,我有一个查询,该查询只需要获取该字段的值并弹出到另一个表中

该表中约有25000条记录

下面的查询运行大约需要25秒

UPDATE ObjectivesApproved 
       INNER JOIN Approved 
          ON ObjectivesApproved.ID = Approved.ID 
   SET ObjectivesApproved.Football = [Approved].[Cri Football Related];
删除联接操作会使查询花费更长的时间

但是,如果我执行以下操作,整个操作所需时间不到5秒,即使它正在执行2个查询

UPDATE ObjectivesApproved 
       INNER JOIN Approved 
          ON ObjectivesApproved.ID = Approved.ID 
   SET ObjectivesApproved.Football = 'Y' 
 WHERE (([Approved].[Cri Football Related]='Y'));

UPDATE Approved 
       INNER JOIN ObjectivesApproved 
          ON Approved.ID = ObjectivesApproved.ID 
   SET ObjectivesApproved.Football = 'N' 
 WHERE (([ObjectivesApproved].[Football] Is Null));

我对我的解决方案很满意,即使它有点不雅观,但为了进一步了解SQL为什么会发生这种情况?

您的第一个版本正在更新25K行,不管发生什么,但它必须保持表同步,因为它在逐行的基础上使用从一个表到另一个表的值。更新的每一行都必须从一个字段读取-25K次

第二个版本(两个语句)过滤数据,而不是逐行比较。在内部找到一组记录,然后在批处理中更新,而不是逐行计算。值“Y”不必每次都查找,它是常量


想象一下,如果我让你根据我给你的列表将25K个盒子涂成黑色或白色。拿起第一个框,检查列表,并给它上色,拿起第二个框,检查列表,给它上色,重复。或者是把所有应该是白色的都拿出来涂上颜色,然后把所有黑色的都涂上颜色。注意:在第二种情况下,您只需“检查列表”2次,但在第一种情况下,您只需“检查列表”2.5万次。

我将这些放在注释中,但意识到它们构成了一个答案:


您说没有索引,但您说ID字段是PKs。如果是这样,这些字段上必须有一个唯一的索引。如果没有,那么它们就不是真正的PKs,这可能解释了为什么带有WHERE子句的版本比只带有JOIN的版本要快

另外,谷歌“Jet SHOWPLAN”,这样你就可以看到Jet查询优化器在做什么,然后你就可以真正看到发生了什么


使用索引,您将得到一个索引合并,这应该非常快。没有他们,我不知道杰特会怎么做。此外,如果您的Y/N字段已编制索引,则可能会有所不同。建议不要为稀疏填充的字段(即基数较低的字段)编制索引,但我发现Jet/ACE中的索引布尔字段实际上可以产生显著的性能差异。

这两个表上的主键和索引是什么?主键是两个表中的ID列。没有索引。三条
UPDATE
语句中的每一条都影响多少行?您说没有索引,但您说ID字段是PKs。如果是这样,这些字段上必须有一个唯一的索引。如果没有,那么它们就不是真正的PKs,这可能解释了为什么带有WHERE子句的版本比只带有JOIN的版本要快。另外,谷歌“Jet SHOWPLAN”可以让你看到Jet查询优化器在做什么。“您说没有索引,但您说ID字段是PKs。如果是这样,这些字段上必须有一个唯一的索引。如果没有,那么它们就不是真正的PKs”--请注意,如果表上没有PK,但存在
非空唯一
约束,则这将用作聚集索引,即除名称外的所有PK。(如果有多个
非空唯一
约束,ACE/Jet将选择哪一个…?)感谢您提供有关Jet SHOWPLAN的提示,但我无法访问我的计算机注册表,而且从过去与公司IT部门的痛苦经历来看,他们不太可能提供帮助。无论如何,我很快就会将该项目升级到SQL server。如果您有索引问题,您只需将其移动到另一个数据库,而不是实际上解决问题的原因。@onedaywhen:DDL放在一边,是否可以在Access/Jet/ACE中分配一个没有唯一索引的PK?这取决于PK的含义。我可以创建一个带有
检查
约束的无索引选项卡,以防止重复行。我会将其称为真正的关系键。不过,这更有实际意义组合使用
notnull
UNIQUE
(甚至PK),让SQL产品决定如何最好地在物理层强制执行密钥。我避免在SQL Server中使用PK,因为它只提供了我更愿意明确的隐式行为,例如创建聚集索引。对于ACE/Jet,我不能这样说。