2010-02-13 59 views
24

这可能是一个愚蠢的问题,但它可能会阐明连接如何在内部工作。加速大桌子和小桌子之间的内连接

比方说,我有一个大表L和一个小表S(100K行与100行)。

会不会有以下两个选项之间在速度方面的任何差异?:

OPTION 1:     OPTION 2: 
---------     --------- 
SELECT *     SELECT * 
FROM L INNER JOIN S  FROM S INNER JOIN L 
ON L.id = S.id;   ON L.id = S.id; 

注意,唯一的区别是将表的连接的顺序。

我意识到性能可能会因不同的SQL语言而异。如果是这样,MySQL如何与Access进行比较?

回答

13

不,订单无关紧要。

几乎所有的RDBMS(如MS Access,MySQL,SQL Server,ORACLE等)都使用基于列统计的基于成本的优化器。在大多数情况下,优化器会选择一个正确的计划。在你给出的例子中,顺序无关紧要(只要统计数据是最新的)。

要决定使用哪种查询策略,请使用 Jet Engine优化器使用 统计信息。以下因素是 一些因素,这些 统计基于:

  • 的记录表中​​的
  • 数据页的表中的
  • 的位置数数
  • 指标是否存在
  • 指标如何独特的是

注意:您无法查看Jet数据库引擎优化方案,并且您无法指定如何优化 查询。但是,可以使用 数据库记录器确定 是否存在索引以及索引的唯一性如何。

根据这些统计数据, 优化器然后选择最佳的 内部查询策略以用特定查询处理 。

只要编译了 查询,就会更新统计信息。查询标记为 ,用于在保存对查询(或其 基础表)的任何 更改时以及当数据库压缩时编译。如果查询为标记为编译的 ,则在下次运行查询时编译 和更新统计信息发生 。编译通常需要从一个 秒到四秒钟。

如果您向数据库添加大量 记录,则必须打开 ,然后将您的查询保存到 重新编译查询。例如,如果您使用少量样本数据设计并测试了 的查询,则 必须在向 数据库添加 附加记录之后重新编译查询。当您这样做时,您需要 以确保在您的 应用程序正在使用时实现最佳查询 性能。

Ref

可能会感兴趣:ACC: How to Optimize Queries in Microsoft Access 2.0, Microsoft Access 95, and Microsoft Access 97

托尼·托斯的Microsoft Access Performance FAQ是值得一读。

+0

因此,鉴于两个表都有独特的索引,性能会根据具体情况而有所不同? – Zaid 2010-02-13 08:58:01

+0

@Zaid:如果统计信息是最新的(并且如上所述重新编译查询),那么加入的顺序将不会影响;优化器将选择正确的方式。 – 2010-02-13 09:09:39

+0

是的,也许我应该在OP中包含多个嵌套连接... – Zaid 2010-02-13 09:43:21

2

我知道Oracle不在您的列表中,但我认为大多数现代数据库都会以这种方式行事。

您可以在下面的执行计划中看到两个语句之间没有区别。

它是完全访问每个表(在我的情况下没有索引),然后HASH JOIN。既然你想要两个表中的所有东西,那么这两个表都需要被读取和连接,这个序列没有影响。

--------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  | 100 | 700 | 42 (12)| 00:00:01 | 
|* 1 | HASH JOIN   |  | 100 | 700 | 42 (12)| 00:00:01 | 
| 2 | TABLE ACCESS FULL| S | 100 | 300 |  2 (0)| 00:00:01 | 
| 3 | TABLE ACCESS FULL| L | 100K| 390K| 38 (8)| 00:00:01 | 
---------------------------------------------------------------------------