2010-04-08 45 views
5

我有一個有100萬行的「items」表和一個有20,000行的「users」表。當我從「items」表中選擇時,我在「users」表(items.user_id = user.id)上做了一個連接,這樣我就可以從users表中獲取「username」。我可以期望從刪除此JOIN中獲得性能提升嗎?

我正在考慮向物品表添加一個用戶名列並刪除連接。我可以期待這樣的表現有不俗的表現嗎?它已經很快了,但是減少我的負載(這非常高)會很好。

缺點是,如果用戶更改他們的用戶名,項目仍然會反映他們的舊用戶名,但如果我可以期待體面的性能提升,這對我來說可以。

我在問stackoverflow,因爲基準測試並沒有告訴我太多。這兩個查詢都很快完成。無論如何,我想知道刪除聯接是否會減輕數據庫的負擔,並達到任何顯着的程度。

連接示例查詢:
選擇ItemidItemsubmitter_idItemsource_imageItemcached_imageItemsource_titleItemsource_urlItemwidthItemheightItemstatusItempopularItemmade_popularItemfave_countItemtagsItemuser_artItemnudityItemcreatedItemmodifiedItemremovedItemnofrontItemtestItemrecsItemrecs_dataUseridUserusernameUserpasswordUseremailUserfullnameUserprofileurlUserhomepageUserbioUserlocationUseravatarUserff_userUserff_keyUserff_last_faveidUsertwitter_userUsertwitter_passUseremailalertsUsershowunsafeUserviewUserfb_uidUserfb_sessionUserfb_avatarUsertwitter_uidUsertwitter_dataUsertwitter_autopostUseruriUsercreatedUsermodified FROM items AS Item LEFT JOIN users AS User ON(Itemsubmitter_id = Userid)其中Itemnofront!= 1 AND Itemremoved!= 1 AND Itemmade_popular不是NULL和裸露!= 1 ORDER BY Itemmade_popular DESC LIMIT 1040,290;

例子查詢無連接:
選擇ItemidItemsubmitter_idItemsource_imageItemcached_imageItemsource_titleItemsource_urlItemwidthItemheightItemstatusItempopularItemmade_popularItemfave_countItemtagsItemuser_artItemnudityItemcreatedItemmodifiedItemremovedItemnofrontItemtestItemrecsItemrecs_data FROM items AS Item WHERE Itemnofront!= 1 AND Itemremoved!= 1 AND Itemmade_popular不是NULL和裸露!= 1 ORDER BY Itemmade_popular DESC LIMIT 1040,290;

+0

當你正在做什麼在你的where子句中選擇什麼? – Avitus 2010-04-08 03:39:38

+0

添加了上面發佈的兩個查詢。 – makeee 2010-04-08 03:59:03

+0

您可以發佈上述查詢的解釋計劃嗎?它看起來像是從用戶表中檢索大量數據。你需要這一切嗎?如果您使用id和名稱爲用戶表建立索引,那麼使用連接檢索user_name應該非常快。 MySQL也應該很容易有效地緩存表。我希望通過刪除每行返回的額外用戶數據而不是刪除用戶表上的快速索引查找來獲得更大的好處。 – TheJacobTaylor 2010-04-08 04:51:46

回答

5

正確答案是在目標環境中測量它,,看看它是否有所作爲。然後進行成本/收益分析,看看它是否值得。

成本是增加的存儲空間和的可能性數據不同步(但請參閱下面有關如何緩解此問題)。好處是提高了速度或降低了負載。

數據庫模式是而不是設置和忘記操作,它們應該隨着基礎數據更改而週期性地進行調整。這就是數據庫管理員所付出的代價,持續的監控和調整。

在任何情況下,通過使用觸發器,在一個體面的DBMS中可以很容易地控制列的重複。因此,我的意思是在用戶表上放置一個插入/更新觸發器,這樣,如果用戶更改其用戶名,它也會在項目表中更改(可能反之亦然)。

無論MySQL是否滿足我對一個體面的DBMS的定義,我都無法評論 - 我自己是一個DB2 bod。但是,從第三種正常形式迴歸是一種經過驗證的測試技術,可以從數據庫中榨取每一分鐘的性能,並且只要您瞭解其後果,就完全可以接受。很少有人抱怨他們的數據庫佔用了太多的磁盤空間。 很多抱怨他們的查詢運行得有多慢。

請記住,如果和當你有性能問題,你會做。這不是因爲你認爲它可以減輕負載而應該完成的事情。除非負載(或花費的時間)實際上是一個問題,否則您的成本/收益分析的利益部分爲零,所以任何正常的bean計數器都會告訴你,這意味着「不變」。


根據您的附加查詢,我有幾個點,讓:

  • 首先,nudity列。請告訴我,我怎麼能訪問這個數據庫:-)
  • 你應該只提取您需要的列。如果用戶名是你從User表要求,你不應該讓所有多餘的東西在第一個查詢。可能同樣爲Item的東西 - 只得到你需要的東西。
  • 請確保您有在WHERE子句中使用的所有列的索引 - 這可能還需要組合索引(那些有多於一列)。獲取索引的內容取決於您的查詢,但WHERE子句中使用的每列都是分析的良好開端。
  • 對於大表,可以考慮定期「清掃」已刪除項目到一個單獨的表(例如,RemovedItems)以最小化的Items大小和加快查詢。但請記住,這僅僅是有用的,如果你很少需要尋找romoved項目,因爲它會(通過迫使他們在兩個表中,而不是一個搜索)這些查詢的複雜化。再次,這是一個成本/收益的事情。一百萬行並不是真的那麼大(至少在我的世界裏)。
+0

感謝您的建議。關於只提取我需要的列的好點。我正在審查所有的疑問,以確保我只獲得我需要的東西。我確信我所有的索引都很好。通過「清掃」你是指刪除列嗎?我聽說最好把它們放在那裏.. – makeee 2010-04-08 04:49:49

+0

通過「清掃」,他意味着刪除(或移入「存檔」表)不再活動的行,或者您希望訪問次數少於其他(分區)。) – vladr 2010-04-08 04:54:27

+0

我不需要「刪除」行,但我記得聽說刪除行會減慢查找/導致其他問題。這是不是真的? – makeee 2010-04-08 05:21:13

0

如果您缺少items.user_iduser.id的索引,或者您使用的是糟糕的數據庫,則只會看到顯着的性能提升。否則,性能不會顯着提高。

0

連接總是佔用比簡單的SELECT語句更多的資源。所以是的,刪除JOIN應該會提高性能。

1

我建議你保持它的方式來保存規範化的表格。我認爲將用戶名放在項目表上並不是一個好主意,因爲它會使數據變得冗餘。你有沒有嘗試重新索引你的表?

0

我有一個100萬行的「項目」表和20000行的「用戶」表。

也就是說,獨立於是否JOIN或反規範化,你會仍然轉印大致1M/20K = 50倍以上User信息在導線比嚴格必要的。編碼,傳輸和解碼數據會增加負載。

我在考慮給items表添加一個username列並刪除連接。

你爲什麼那麼,在你原來JOIN,也帶來了這一切其他(潛在的大量)的信息(如User.profileurlUser.homepage等),如果你需要的是用戶名?請記住,對於User列,您平均每次傳輸50個信息位。你有沒有考慮大幅修剪下來你SELECTJOIN荷蘭國際集團的列(無論是從User還有Item表?)

我在問stackoverflow,因爲基準測試並沒有告訴我太多。這兩個查詢都很快完成。無論如何,我想知道刪除聯接是否會減輕數據庫的負擔,並達到任何顯着的程度。

在第一階段中,刪除列不打算使用可以減少負載,因爲較少的數據必須被編碼,傳送(從服務器到客戶端應用程序),那麼解碼。

在第二階段,讓我從我自己的問題開始:你真的需要在一個鏡頭中一百萬行嗎?如果您沒有,例如如果您是用戶界面驅動的並且將它們分頁(使用OFFSET ... LIMIT ...),那麼您將不一定關心50x User信息重複(除非LIMIT進入成千上萬)。否則,您可能需要度量優點的通過第一SELECT荷蘭國際集團User.idUser.username到應用存儲器(20K對,爲哈希表/圖),則消除了50倍複製SELECT荷蘭國際集團Item行(1M迭代)每次解析,在針對散列表/映射的應用程序級別Item.user_id

當然,總是使用EXPLAIN來確保在使用索引時存在正在使用的索引,並且在任何表的數量從幾百行增長到數千或數百萬之後運行ANALYZE TABLE

+0

你是正確的有更多的用戶信息。我沒有意識到這是一件很大的事情,但回想起來是有道理的。我將從修剪那個開始。 – makeee 2010-04-08 05:24:45

相關問題