2013-07-30 22 views
0

我實際上有一個30列的表。有一天這張桌子可以獲得3000個新紀錄!mysql優化數據內容:多列或簡單列哈希數據

列DATAS樣子:

IMG          Name   Phone  etc.. 

http://www.site.com/images/image.jpg  John Smith 123456789 etc.. 
http://www.site.com/images/image.jpg  Smith John 987654321 etc.. 

我正在尋找一種方式來優化表的大小,還可以把SQL查詢的響應時間。我想在做類似的:

Column1 

http://www.site.com/images/image.jpg|John Smith|123456789|etc.. 

,然後通過PHP的我將每個值存儲到一個數組..

難道是更快?

編輯

所以採取結構的一個例子,比方說,我有兩個表:

package 
package_content 

下面是表package的結構:

id | user_id | package_name | date 

這裏是表package_content的結構:

id | package_id | content_name | content_description | content_price | content_color | etc.. > 30columns 

事情是爲每個包我可以得到16羅的內容。例如:

id | user_id | package_name | date 
260 11  Package 260 2013-7-30 10:05:00 

id | package_id | content_name | content_description | content_price | content_color | etc.. > 30columns 
1  260   Content 1  Content 1 desc  58    white   etc.. 
2  260   Content 2  Content 2 desc  75    black   etc.. 
3  260   Content 3  Content 3 desc  32    blue   etc.. 
etc... 

然後用PHP我做出那樣的

select * from package 
while not EOF { 
    show package name, date etc.. 
    select * from package_content where package_content.package_id = package.id and package.id = package_id 
    while not EOF{ 
     show package_content name, desc, price, color etc... 
    } 
} 
+0

爲什麼你的表有30列?聽起來你可能可以使用[一些標準化](http://en.wikipedia.org/wiki/Database_normalization)。另外,請勿將所有內容放在桌子上的一列中。當你必須更新某人的電話號碼時會發生什麼?首先,您必須將數據庫中的所有行加載到PHP中,然後必須遍歷所有對象,嘗試查找需要更新的特定記錄,然後重新加載。 vs'UPDATE table SET phone = {new phone#} WHERE phone = {old phone#}' – bhamby

回答

1

難道是更快?絕對不是。如果您需要通過NamePhoneetc...進行搜索,則必須每次從Column1中提取這些值。永遠無法優化這些查詢。

如果您想讓表格變小,最好考慮將某些列拆分爲另一個表格。如果你想追求這個選擇,請發佈整個結構。但請注意,列數不會影響速度多。我的意思是它可以,但是它會降低你的速度。

最後,每天3,000行大約每年100萬行。如果數據庫設計合理,MySQL可以輕鬆應對。


附錄:局部表的結構加樣查詢和僞碼添加到質疑。

該僞代碼顯示package表被一次查詢,然後匹配package_content行一次查詢一行。這是一個非常緩慢的方式去做事情;更好地使用一個JOIN

SELECT 
    package.id, 
    user_id, 
    package_name, 
    date, 
    package_content.* 
FROM package 
INNER JOIN package_content on package.id = package_content.id 
WHERE whatever 
ORDER BY whatever 

這將加快事情的馬上。

如果要顯示在網頁上,一定要限制用WHERE條款的結果 - 沒有人會希望看到1000個或3000或1,000,000個包一個網頁上:)

最後,正如我前面所提到的,列數不用於查詢優化一個巨大的擔心,但是......

  1. 有一個很寬的結果行意味着更多的數據具有跨線去從MySQL到PHP,並

  2. 這是不可能的您可以在網頁上顯示30列以上的信息,而不會顯得很糟糕,特別是在閱讀大量行時。

考慮到這一點,你就可以在查詢中選擇特定package_content列,而不是挑選他們都帶着SELECT *的更好。

+0

嗨,Gibbs,謝謝你的回答。我不需要在我的php代碼中選擇任何特定的列,我通常選擇*。我編輯了我的第一篇文章,併發布了表格的結構示例,以便您可以理解我如何組織數據。此外,我已經優化了列類型(如不需要時使用varchar 255) – yves

+0

Hi Yves - 我已經添加了一些更多的信息給我的答案。通過使用單個查詢而不是僞代碼中的多個查詢,您可以加快速度,並且我還建議您確定需要哪些列,並僅選擇那些列,而不是「SELECT *」。即使你選擇了'',它仍然不是超級慢速和超級快速之間的區別,但是如果你不打算使用某些列,沒有理由將它們包含在查詢中。 –

+0

謝謝。好吧,我將使用一個連接,所以我只得到1個查詢。是的,我也使用LIMIT,每頁顯示30個結果。我必須使用所有列(大多數用於顯示在jQuery工具提示中),但有時一些列是空的。就像某些內容可能將content_color設置爲NULL。我不知道我是否可以提出一些關於不選空列的方法...... – yves

1

不要組合任何列,這是沒有用的,甚至可能會更慢。

您應該在查詢的列上使用索引。我有一個網站,其中有大約30列,atm大約有600.000個結果。如果在查詢之前使用EXPLAIN,則應該查看它是否使用任何索引。如果在同一個表中有2個值和一個WHERE JOIN。您應該按照JOIN - > WHERE的順序對3列進行組合索引。如果你加入同一張桌子,你應該看到這是一個單獨的索引。

例如:

SELECT p.name, p.id, c.name, c2.name 
FROM product p 
JOIN category c ON p.cat_id=c.id 
JOIN category c2 ON c.parent_id=c2.id AND name='Niels' 
WHERE p.filterX='blaat' 

你應該在類

parent_id,name 
AND 
id (probably the AI) 

有一個組合索引產品

cat_id 
filterX 

A股指數有了這個簡單的解決方案,您可以從不能優化查詢可以達到0.10秒,甚至更快。

如果你使用MySQL 5.6,你應該切換到INNODB,因爲MySQL優化JOINS和子查詢。另外MySQL會嘗試將它們運行到MEMORY中,這會使它更快速地運行。請記住,回補INNODB表可能需要額外注意。

您可能還會考慮製作MEMORY表以實現超快速查詢(您仍然需要索引)。

您還可以通過使整數大小爲4(4個字節,而不是11個字符)進行優化。並不總是使用VARCHAR 255.

+0

你好尼爾斯,謝謝你的回答。我真的不知道索引是什麼(如果你能解釋我如何使用索引,我發佈了這個結構?)我會在你推薦它時尋找innodb。我的網絡服務器有4GB的RAM是你覺得呢?是的,我已經優化了列類型的大小。提前致謝! – yves

+0

MySQL有多個文件(1個索引文件和其餘表文件)。它將首先使用索引文件來查找他的結果,而不需要打開完整的數據文件。更多信息:http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html我看到你在for循環中使用查詢,請儘量避免!這是從來沒有想過的,並會真正減慢你的網站。 – Niels

+0

是的,我已經改變了我的查詢,因爲吉布斯指出。我會跟隨你的鏈接並對此進行一些研究。謝謝你的時間。 – yves