2013-09-25 31 views
1

有足夠大的貨物數據庫穩步增加。現在DB中有超過1000萬的商品。數據庫工作的優化

有一個很好的,有它的類別。每件商品都具有以下屬性:名稱,價格,出售商品數量,擔保標誌和質量等。產品的特徵僅針對特定類別。貨物的屬性具有下一個格式 - 2000:10000(屬性的類別:屬性的值)。某些類別的屬性和屬性本身可能會在各種類別(如品牌)中重疊。過濾,排序和搜索標題和財產是由這些類別和屬性進行的。該產品可以鏈接到一個或多個類別。

起初我們只使用mysql並通過爲每個類別創建表來存儲貨物。通過這種方式,我們有大約6-7,000個有貨物的餐桌。選擇時,我們向每個人發出請求,並在操作員UNION的幫助下合併請求。隨着商品數量和類別的增加,選擇開始需要很長時間並且配置mysql服務器。 之後,我們將所有產品移到一個表中。表格結構如下[http://clip2net.com/s/5OUKXm

該表有1000萬個產品使得現在很難使用mysql。從它的選擇是不可能的,沒有談論排序。我們使用sphinx,索引獅身人面像:。

sql_query = SELECT \ 
ti.item_id, \ 
ti.item_id AS iid, \ 
crc32(ti.item_nick) AS nick, \ 
ti.item_title AS title, \ 
ti.item_sold AS sold, \ 
ti.item_rating AS rating, \ 
ti.item_popular AS popular, \ 
ti.item_warranty AS warranty, \ 
ROUND(ti.item_price*100, 0) AS price, \ 
ti.item_props AS props, \ 
COUNT(c.comment_iid) AS comments, \ 
GROUP_CONCAT(tcir.category_item_ref_tid) AS tids \ 
FROM item AS ti \ 
LEFT JOIN comment AS c ON ti.item_id = c.comment_iid \ 
INNER JOIN category_item_ref AS tcir ON ti.item_id = tcir.category_item_ref_iid \ 
WHERE ti.item_id >= $start AND ti.item_id <= $end \ 
GROUP BY ti.item_id 

sql_attr_uint = sold 
sql_attr_uint = rating 
sql_attr_uint = comments 
sql_attr_uint = warranty 
sql_attr_bigint = iid 
sql_attr_bigint = nick 
sql_attr_bigint = price 
sql_attr_bigint = popular 
sql_attr_multi = uint tids from field; 

搜索通過獅身人面像速度較快,但也有許多屬性,在減緩搜索和600000個貨物分揀採樣時間特別sql_attr_multi TIDS約爲18 -19秒我們試圖扳平產品只有一個類別(一個屬性tids變爲sql_attr_uint),採樣時間減少到3〜5秒,這也不是很好。

你能告訴我,我做錯了什麼,它可能是值得建立一個索引獅身人面像另一種方式,因爲我認爲它應該工作得更快。也許,我需要以另一種方式構建表結構,或者爲數據庫使用不同的平臺,例如MySQL,MongoDB,PostgreSQL,MariaDB。

回答

1

與許多其他遇到大型數據集集的公司一樣,您面臨着許多問題。你很幸運,因爲看起來你的用例是繁重的閱讀,但是由於這兩個問題一起寫得很少,所以寫得很糟糕:-) 理解數據庫系統不是虛擬文件系統,它允許索引和鎖定以及優化用於快速搜索(在數據和索引中)。

沒有理由不使用適當的查詢來快速表中的近10m項目。但是你需要優化系統和查詢。這是什麼意思?

你說你想支持快速排序貨物在一個類別。我應該如何設計它?

  • 比方說有10米項目,10K類別所以每個有100個項目的良好
  • 在一個類別排序按值傳遞意味着有重複的數據,無論是品類和價格,排序方式 - 形式包括類別標識和價格值的索引
  • 以恰當的方式執行查詢只是使用此索引。首先,它搜索快速的類別,因爲它使用索引形式的某種散列表來表示,其中10m行的索引可能會在一次讀取中被讀取,例如, MS SQL在硬盤(驅動器)讀取時高速緩存512kb。一旦在索引中找到了所需的類別,就可以對已排序的100個項目進行排序,從而獲得需要在驅動器上找到的物理行ID的集合。最後一步是物理讀取100個數據庫行id,它們的id可能需要偶數個ms,即使在隨機選擇的標識符中也是如此。

我寫了這個部分來顯示即使一個大型數據庫表可以快速查詢,但您需要調整查詢並提供特定的正確索引。

你應該嘗試經典的方法:

  1. 寫用例 - 這是頂級查詢我想在我的系統優化?
  2. 把這些查詢和優化您的表和索引

這似乎對我來說,這是沒有必要削減在多個表中數據,您應消除數據的查詢,需要通過使用上面的方法來搜索量 - 只使用正確的索引。

你提到了加入表格。對於大數據可能需要很長時間的操作,所以流行的系統是複製數據,只提供一個表(最快的方法)從其他表中搜索重複的數據。明顯的問題是更新這些數據,因爲你需要原子更新兩個表。一旦你談到只讀,它似乎對你來說不是一個真正的問題 - 當你更新原來的數據時,你可以更新重複的數據。

還有其他一些方法如何應對大規模的閱讀和寫作。學習像Twitter或Facebook這樣的頂尖互聯網公司的架構並瞭解他們如何應對類似問題,這是很好的。