2012-08-31 124 views
0

我試圖讓我們的服務器上的響應時間縮短到250毫秒的範圍內的大多數查詢需要比這毫秒一個需要很長的時間在它自己的少..超過1500毫秒由於行數很多。這裏是數據結構,有沒有什麼可以減少這個查詢的時間,但使用不同的查詢或以更快的速度設置我的數據?SQL優化和選擇基於關鍵

mysql> describe variant_bikes; 

+------------+-----------------------+------+-----+---------+-------+ 
| Field  | Type     | Null | Key | Default | Extra | 
+------------+-----------------------+------+-----+---------+-------+ 
| variant_id | mediumint(8) unsigned | NO | PRI | 0  |  | 
| bike_id | mediumint(8) unsigned | NO | PRI | 0  |  | 
+------------+-----------------------+------+-----+---------+-------+ 

mysql> describe cscart_product_option_variants; 

+----------------------+-----------------------+------+-----+---------+----------------+ 
| Field    | Type     | Null | Key | Default | Extra   | 
+----------------------+-----------------------+------+-----+---------+----------------+ 
| variant_id   | mediumint(8) unsigned | NO | PRI | NULL | auto_increment | 
+----------------------+-----------------------+------+-----+---------+----------------+ 
15 rows in set (0.00 sec) 

mysql> describe bikefilter_cache; 
+---------+-----------------------+------+-----+---------+----------------+ 
| Field | Type     | Null | Key | Default | Extra   | 
+---------+-----------------------+------+-----+---------+----------------+ 
| bike_id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment | 
| year | smallint(6) unsigned | NO | PRI | NULL |    | 
| make | varchar(20)   | NO | PRI | NULL |    | 
| line | varchar(20)   | NO | PRI | NULL |    | 
| model | varchar(90)   | NO | PRI | NULL |    | 
+---------+-----------------------+------+-----+---------+----------------+ 

mysql> select count(*) from variant_bikes; 

+----------+ 
| count(*) | 
+----------+ 
| 7577597 | 
+----------+ 
1 row in set (1.85 sec) 

mysql> select variant_id from variant_bikes where bike_id=112; 
9366 rows in set (2.30 sec) 

有一件事我以前試過,我認爲至少是與它的大小是那麼慢得多,是有variant_bikes與variant_id表作爲不過是bike_ids場爲VARCHAR和/或文字和你用逗號分隔的列表進行搜索。

我想到的另一件事可能是將所有表格安排到不同的更高效的數據結構中。

+1

怎麼樣'EXPLAIN'ing這些查詢? – raina77ow

+1

Erm ...我可能是錯的,但它在我看來只有一個索引 - '(variant_id,bike_id)' - 在'variant_bikes'中;這兩個字段都不是外鍵。真的嗎? ) – raina77ow

+0

我可以,如果它仍然有用拉尼娜。主鍵對索引作爲一個單位不是外鍵。但是每個部分都是。如果這是有道理的。 – Wolfe

回答

3

對於查詢的最佳性能,添加索引ON variant_bikes (bike_id, variant_id)

這將是用於查詢的「覆蓋物」指數,和MySQL將能夠滿足「使用指數」僅僅塊查詢,而不必從該表中引用(查找)的任何數據塊。

問:爲什麼我們在(variant_id, bike_id)已經有索引時需要這個索引?

答:它與索引中的列的順序做。查詢中的謂詞(WHERE子句)位於bike_id列中。爲了讓MySQL使用索引,該列需要作爲索引中的主要列出現。

問:如果我只有(bike_id)列的索引,該怎麼辦?

答: MySQL是非常有可能使用該索引。該查詢還需要返回variant_id列中的值以獲得最佳性能,我們只想滿足來自索引塊的查詢。根據MySQL和存儲引擎的版本,MySQL可能能夠從(bike_id)的索引返回variant_id,因爲主鍵列的值是「指針」返回到數據塊。

您可以嘗試添加該索引,然後運行EXPLAIN SELECT ...,您希望看到的最後一列(額外)是「使用索引」,表示查詢滿足索引而無需引用塊從桌子上。

... key    Extra   
--- ------------- ------------- 
    bike_id_index Using index 
+0

在variant_bikes(bike_id,variant_id)上創建索引bike_id_index;現在還不到一毫秒,謝謝。我的問題是,爲什麼我要添加這個索引,如果主鍵已經是索引。這是命令嗎?是在variant_bikes(variant_id,bike_id)一個不同的索引?如果我只在variant_bikes(bike_id)上做什麼? – Wolfe

1

variant_bikes主鍵是複合鍵(variant_id, bike_id)和你對複合鍵下半年搜索。所以你不會使用索引。

bike_id上添加索引,一切都會好的。