2013-08-27 69 views
0

我正在研究「在線數據流」項目,我需要一些幫助來構建最佳性能的數據庫。目前,我有一個包含玩家,包括文件,海報圖像,POST_ID等構建數據庫以獲得最佳性能

+---------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+---------------+-------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| post_id  | int(11)  | YES |  | NULL |    | 
| file   | mediumtext | NO |  | NULL |    | 
| thumbs_img | mediumtext | YES |  | NULL |    | 
| thumbs_size | mediumtext | YES |  | NULL |    | 
| thumbs_points | mediumtext | YES |  | NULL |    | 
| poster_img | mediumtext | YES |  | NULL |    | 
| type   | int(11)  | NO |  | NULL |    | 
| uuid   | varchar(40) | YES |  | NULL |    | 
| season  | int(11)  | YES |  | NULL |    | 
| episode  | int(11)  | YES |  | NULL |    | 
| comment  | text  | YES |  | NULL |    | 
| playlistName | text  | YES |  | NULL |    | 
| time   | varchar(40) | YES |  | NULL |    | 
| mini_poster | mediumtext | YES |  | NULL |    | 
+---------------+-------------+------+-----+---------+----------------+ 

一個有100K記錄大約需要0.5秒,查詢和性能的不斷降低,因爲我有更多的記錄所有相關信息的一個表。 ('7000')AND類型='1';其中post_id('7000')AND_type ='1'中的post_id解釋SELECT * FROM dle_playerFiles

+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ 
| id | select_type | table   | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ 
| 1 | SIMPLE  | dle_playerFiles | ALL | NULL   | NULL | NULL | NULL | 61777 | Using where | 
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+ 

我該如何改進DB結構? youtube等大型網站如何構建數據庫?

+0

您創建了哪些索引? – MatBailie

+0

無,從解釋'possible_keys' = null – user2696962

+0

也許創建一些? *(和/或谷歌他們瞭解如何以及爲什麼?)* – MatBailie

回答

2

通常,當查詢時間成正比的行數,即提出了一種表掃描,這意味着對於像

SELECT * FROM dle_playerFiles where post_id in ('7000') AND type='1' 

查詢該數據庫執行該字面上,如,遍歷每單排並檢查它是否符合標準。

對此的典型解決方案是一個索引,它是一列(或一組列)的值的預先計算值列表以及具有所述值的行的列表。

如果創建上dle_playerFiles的POST_ID列的索引,那麼指數將基本上說

1: <some row pointer>, <some row pointer>, <some row pointer> 
2: <some row pointer>, <some row pointer>, <some row pointer> 
... 
100: <some row pointer>, <some row pointer>, <some row pointer> 
... 
7000: <some row pointer>, <some row pointer>, <some row pointer> 
250000: <some row pointer>, <some row pointer>, <some row pointer> 

因此,在發生這樣的指標,上述查詢將單純看指數的節點7000並知道哪些行包含它。

則數據庫只需要讀取其中POST_ID是7000行,並檢查他們的類型是1

這將是更快,因爲數據庫從來不需要看每一行來處理查詢。索引的成本:

  1. 的存儲空間 - 這是更多的數據,它必須保存在某個地方
  2. 更新時間 - 數據庫保持同步指標與變化自動錶,這意味着INSERT,UPDATE而DELETE語句將需要更長的時間,因爲它們需要更新數據。對於小而高效的索引,這種折衷通常是值得的。

對於您的查詢,我建議您在2列上創建一個索引。讓他們在同一指數的一部分,而不是2個獨立的指標:

create index ix_dle_playerFiles__post_id_type on dle_playerFiles (post_id, type) 

注意事項這個工作效率:

  1. SELECT *是壞在這裏。如果您要返回每列,那麼數據庫必須轉到表以讀取列,因爲索引只包含用於過濾的列。如果您確實只需要一個或兩個列,請在SELECT子句中顯式指定它們並將它們添加到索引中。不要爲許多列執行此操作,因爲它會使索引膨脹。
  2. 函數和類型轉換傾向於防止索引使用。您的SQL包裝整數類型post_id並鍵入引號,以便它們被解釋爲字符串。數據庫可能會覺得索引無法使用,因爲它必須轉換所有內容。刪除好措施的引號。
1

如果我正確地讀取了您的持續時間,它似乎需要0.04630675(秒?)來運行您的查詢,而不是0.5秒。

無論如何,正確的索引可以減少返回查詢結果所需的時間。根據您的查詢SELECT * FROM dle_playerFiles where post_id in ('7000') AND type='1',建議使用post_idtype索引。

此外,如果您不需要絕對需要返回所有字段,請使用所需字段的單個列引用而不是*。字段越少,查詢將返回的越快。

優化查詢的另一種方法是確保您使用可能的最小數據類型 - ,特別是主/外鍵和索引字段中的。切勿使用bigintintmediumintsmallint或者更好的是,一個tinyint會做。從來沒有,有史以來使用PK或FK中的文本字段,除非你沒有別的選擇(這是一個數據庫設計的罪行,即使是經常有足夠的訓練和經驗的人更好地知道IMO)使用盡可能小的精確數字類型會好得多。所有這些都對存儲規模產生了積極的影響。

相關問題