2013-08-29 44 views
0

我在這裏要問一個問題,你們中許多人已經問自己,我想。我正在創建一個PHP網站,並且一切都一直順利運行,直到我決定用一些測試數據(實際數據,當應用程序開始真正使用時,將會變得更大)填充我的數據庫爲止。大多數情況仍然可以正常工作,但是一個特別的(並且非常重要的)功能開始執行時間爲三到四秒,而且大部分時間都花在了MySQL服務器上。許多(很多)SQL連接VS多個查詢

這裏的交易:我建立一個應用程序的一所學校,它需要將所有每天的時間表和教訓,每一個人,每一個房間,每一個類。數據庫的結構做了,創建索引,等等的問題是,由於所有這些數據是關係(並且可以跨多臺傳播)一個查詢來獲取他們都可能是這樣的:

SELECT field1, field2, etc 
FROM schedules AS su 
LEFT JOIN schedules_lessons AS sul 
    ON sul.ID_SCHEDULE = su.ID 
LEFT JOIN schedules_lessons_teachers AS sult 
    ON sult.ID_LESSON = sul.ID 
LEFT JOIN users AS u 
    ON u.ID = sult.ID_TEACHER 
LEFT JOIN schedules_periods AS sup 
    ON sup.ID_SCHEDULE = su.ID 
LEFT JOIN schedules_periods AS sulp 
    ON sulp.ID_SCHEDULE = sul.ID_SCHEDULE AND sulp.period = sul.period 
LEFT JOIN schools AS s 
    ON s.ID = su.ID_SCHOOL 
LEFT JOIN schools_buildings AS sb 
    ON sb.ID_SCHOOL = s.ID 
LEFT JOIN schools_rooms AS sr 
    ON sr.ID = sul.ID_ROOM 
LEFT JOIN schools_classes AS sc 
    ON sc.ID = sul.ID_CLASS 

是啊,這是一個很大的加入,我知道了。我的問題是:我應該如何在數量或查詢的連接數&之間取得最佳平衡?因爲我覺得這樣可以真正改善,但我不知道如何實現它。

大多數表將在200的記錄數,只有教訓表可以有其它更多地方。最小值約爲5k,最大值可以是30k或更多。

+0

不知道你的模式是不容易給意見,但是從你的查詢猜測它,似乎有什麼不對勁的地方。爲了提高性能,您是否已在所有表格中正確編制了所有相關字段(示例中的所有外鍵)的索引?此外,第二次加入'schedules_periods AS sulp'似乎是多餘的,只需將第一次加入更改爲'LEFT JOIN schedules_periods AS sup sup.ID_SCHEDULE = su.ID AND sup.period = sul.period'。關於查詢長度,您可以使用一些視圖來縮短查詢時間。規範化的數據庫沒有錯。 – Eggplant

+0

像這樣的東西是nosql閃耀的地方..那是可怕的看看。 – sircapsalot

+0

@Eggplant嗨。那麼,事實是(冗餘)查詢是我用來完成排序工作的一個小技巧。這有點難以解釋。這是因爲這些時間段是特定於時間表的,這意味着它們對於每個時間表都是不同的。因此,我不僅要選擇與課程相對應的時間段,還要選擇與整個時間表相對應的時間段,而只是在課程開始時排序。 :) –

回答

0

如果需要此信息和表適當的索引,那麼你的連接查詢應該是一個非常合理的方式來提取數據。查詢前可以通過添加explain來查看索引是否正在使用。

當你說「大部分的[的]時間花費在MySQL服務器」,你考慮到返回數千行需要時間?您可以嘗試執行相同的查詢,但用select count(*)替換select . . .以查看底層查詢性能。另一種方法是將order by <something> limit 1添加到現有查詢 - order by必須在返回結果之前完全處理該查詢。

最後,如果這只是開始成爲一個問題,是什麼,因爲它的工作,你希望它的方式改變了嗎?

+0

嗨,謝謝你的答案。那麼,這是因爲我將一些真實的數據插入數據庫(創建那些4k +行)。另外,我已經爲每個表檢查了phpMyAdmin,並且檢查了索引,並且它們都是爲這些字段創建的。另外,當我說查詢時間時,我實際上只是在獲取結果之前測量查詢函數所花費的時間。此外,遵循您使用count(*)的建議將執行時間降低到1.5秒。 –

0

我不是一個數據庫專家,但也許是有意義的只查詢從您目前需要在你的應用程序或網頁數據庫中的信息。 這應該可以在相當短的時間內,我猜。 其餘的可以在實際需要時從數據庫中查詢。

請注意,數據庫服務器是建立一個大表在內存中的所有連接進行合併。如果您的服務器內存太少,則可能難以構建此表。 (雖然可能大概不會在您的方案的情況下...)

0

儘可能你應該讓數據庫處理加入,避免超過必要讓更多的查詢。理論上這應該是最佳的。你的查詢似乎很好提供所有的連接字段索引。 規定的卷不是什麼壯觀的,響應時間應該是罰款(再次提供所有索引創建)。 請記住,您應該很少有如果有查詢返回許多記錄(當然是一個例外報告) - 在應用程序中,你應該用分頁來控制它。

+0

嗨,謝謝你的答案。事實上,實際上沒有辦法減少我向數據庫查詢的內容,因爲我只查詢屬於用戶請求的計劃的課程。它最終可能會最多返回30個課程。 :) –

+0

嗨,根據您的信息:30條記錄返回和執行時間> 1秒我會說可能有索引缺失,或者您的數據庫非常緩慢。你應該檢查執行計劃。 – user2497369