2010-02-13 63 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 | 
---------------------------------------------------------------------------