2015-09-09 86 views
2

我修改我這是剛剛從預訂拉動保留原始查詢表加入到單位它連接到建築的表,以檢索每個建築物的名稱和單元編號表預訂。優化此雙左連接查詢?

我爲此創建了一個SQLFiddle,並在查詢前加上了解釋。 Per @Alex,我在bookings.unit_number上添加了一個索引,它在SQLFiddle中是bookings.external_system_id。 (忽略次要欄位)。

當我爲所有預訂完全導出時,仍然需要一些時間(分鐘)。我只是試圖儘可能優化這一點,因爲我意識到完全導出仍然需要一段時間(總計13019077個結果)。

+2

如果你沒有使用'units'中的任何一列,爲什麼'join'? –

+0

順便說一下,我在EXPLAIN前面加了SELECT,但它對我來說並不重要。 –

+1

@vkp - 添加從建築物表中提取數據的最終查詢。 –

回答

4

你正在處理一個複雜的SQL方面。你可能想讀http://use-the-index-luke.com

恕我直言,你的發言

有日期範圍和屬性過濾器,但這些都是可選的

很可能讓你從我們這裏得到完全的任何意見除非您向我們展示這些過濾器的外觀,否則毫無價值。但是,我仍然會盡力提供幫助。

units (unit_number, id)buildings(id,name)上創建化合物covering indexes並查看性能是否提高。這些複合指標應該有助於業績。如果您在bookings.arrival上過濾,那麼您也可以爲了同樣的目的在bookings (arrival, unit_number)上創建複合索引。

在InnoDB中,將主鍵作爲複合索引的最後一列沒有意義; MySQL在每個索引中放置相應的對象。 在MyISAM你應該把PK放在那裏,如果你的查詢需要它。以主鍵開頭或包含它的複合索引仍然可能有用。

單列索引的集合無法達到與精心挑選的複合索引相同的目的。擁有大量索引會增加查詢計劃程序爲給定查詢找到有用的索引的機率。但是,覆蓋爲您的查詢設計的索引可以從根本上加快速度。

索引消耗的空間與其包含的數據量非常大致成正比。硬盤空間現在是驚人的便宜。

在你的Sql小提琴很顯然你應該改變你的units表的索引。擺脫external_system_id上的單列索引並將其替換爲該複合索引。

INDEX `units_joindex` (`external_system_id`, `building_id`) 

像這樣:(http://sqlfiddle.com/#!9/e5ffd/2/0)。請注意,EXPLAIN結果和查詢計劃在很大程度上取決於表中的行數和索引。像你這樣的查詢必然需要拉一張桌子,所以你不會在那裏看到很多索引。

+0

@Ollie_Jones - 感謝您的鏈接。 「請注意,這將消耗更多空間,並且插入會減慢」 - 您是否知道添加覆蓋索引會佔用多少「空間」?使用多個單一索引與組合索引是否「更安全」?目前這些表使用單個索引。 –

+0

也,因爲id已經是一個PK,它不應該包含在組合索引或應該? –

+0

請參閱我的編輯。請花時間閱讀使用索引盧克。 –