2017-05-24 37 views
2

對於我使用InnoDB引擎和我的表結構的MySQL表看起來是這樣的:PHP與MySQL的性能 - 一個大的查詢與多個小

表用戶

id | username | etc... 
----|------------|-------- 
    1 | bruce  | ... 
    2 | clark  | ... 
    3 | tony  | ... 

表用戶的電子郵件

id | person_id | email 
----|-------------|--------- 
    1 |   1 | [email protected] 
    2 |   1 | [email protected] 
    3 |   2 | [email protected] 

爲了從數據庫中提取數據我已經寫了一個小framewor ķ。例如。在__construct($id)它檢查是否有一個人與給定的ID,如果是,它會創建相應的模型,並只保存字段id到一個數組。在運行期間,如果我需要模型中的另一個字段,它只會從數據庫中提取值,並將其保存到數組中並將其返回。例如。與emails相同,因爲我的代碼訪問表user-emails並獲取相應用戶的所有電子郵件。

對於小型模型來說,這個工作正常,但現在我正在處理另一個項目,我必須一次爲列表獲取大量數據,並且需要一些時間。另外我知道很多連接到MySQL和許多查詢對服務器來說都是很有壓力的,所以...

我現在的問題是:我應該在構建模型時一次獲取所有數據(包含左連接等)並將這些字段保存爲一個數組,或者我應該使用其他方法?

+0

...取決於。一般來說,使用許多簡單的查詢將比使用一個複雜的查詢更好;但這取決於它的複雜程度以及您的索引是如何設置的。 – CD001

+0

您應該只測量性能並查看是否有問題。 – pvg

+0

@ CD001這個評論實際上讓我感到驚訝,人們試圖將許多SQL查詢填充到一個大查詢中的數量使我認爲更少的大型查詢通常說起來效率更高.....我想我不應該跟隨人羣。 ....':-D' – Martin

回答

1

爲什麼人們堅持將實體和領域對象稱爲「模型」。

除非您的實體非常大,否則我會在您需要時填充整個實體。而且,如果「電子郵件清單」是該實體的一部分,我也會填寫該清單。

正如我所看到的,問題更多地與「如何處理與外鍵相關的表」有關。

可以假設你有UsersArticles表,其中每篇文章有一個特定的所有者通過user_id外鍵關聯。在這種情況下,當填充Article實體時,我只會檢索user_id值,而不是提取有關用戶的所有信息。

但與UsersUserEmails您例如,電子郵件似乎是User實體的一部分,和東西,你會經常通過$user->getEmailList()調用。

TL; DR

填充User實體時,我會在兩個查詢,這樣做:

  1. 選擇你從用戶表需要,適用於User實體
  2. 選擇所有用戶來自UserEmails表的電子郵件並將其應用於User實體。

P.S

你可能想看看data mapper模式的「how」部分。

+0

'users' +'articles'的例子有些不同,那些基本上是2個不同的實體。在我的情況下,所有其他表都屬於同一個實體,現在我所有的都出現在列表中。 – donnikitos

+0

您是否閱讀過以「但在您的例子中......」開頭的部分? –

+0

是的,剛纔要考慮這個解決方案。那麼PHP呢?如果我不使用主表的某些區域,那麼這不會污染內存嗎? – donnikitos

0

在我看來,你應該一次獲取所有的字段,並以一種讓你的代碼更容易閱讀/管理的方式劃分查詢。

當我們談論一個或兩個查詢時,除非組合查詢(與JOIN s或其他)過於複雜,否則通常可以忽略不同。通常,一個或兩個索引是解決非常慢的查詢問題的方法。

如果我們談論的是一個vs數百或數千個查詢,那麼連接/傳輸開銷變得更加重要,並且減少查詢次數可以產生影響。

看來你的框架遭受premature optimization。你太擔心從行中取得太多的字段,但爲什麼?你有成千上萬的專欄嗎?

查詢耗時的部分幾乎總是查找,而不是數據的傳輸。當您一次拉一個字段時,您正在導致數據庫一遍又一遍地執行「硬」部分。

+0

我只是想知道這將如何影響服務器。當然,我不會有成千上萬的列,但是在70左右。如果我一次加載100行,總共將有7000個字段,這就是我想到的。 – donnikitos

+1

我會更關心7000個查詢以獲得100行數據,而1個查詢則獲得7000個字段。即使每個字段都是20個字節,我們仍然只談論140 KB的數據。 – jchook

+0

再說一遍,你說10秒鐘就可以加載60行。這太瘋狂了。 MySQL可以查詢60行,並在眨眼間連接11個表(每行有數百行和25列)。 – jchook