2011-08-30 167 views
2

我試圖創建一個規範化的數據庫。正因爲如此,我試圖加入21個表格。我在聯接的幾乎所有表格上使用索引,如EXPLAIN聲明的下面截圖所示。慢Group_concat查詢

http://i.imgur.com/V5hQu.png

所有lookup_xxxxx表對2列(CONTENT_ID和xxxxxx_id)一個索引 所有xxxxxx表具有1柱(xxxxx_id)

我只有大約10個左右的行中的一個索引每張表。我看到的問題是兩個goup_concat延長了查詢額外的200毫秒。我允許提交字段peripheralprogramming language具有多個值。沒有他們,查詢少於80毫秒。 我的問題是我是否應該廢除group_concats併爲它們執行單個查詢或重建我的數據庫。

lookup_xxxxx表存儲每個允許的值,然後其他表(如peripheral)通過content_id將提交鏈接到允許的值。一切都參考了提交content_idcontent表持有必要的信息,如會員ID,名稱等。

如果我的帖子不夠清晰,我表示歉意。

mysql> describe peripheral; 
+------------------+----------+------+-----+---------+-------+ 
| Field   | Type  | Null | Key | Default | Extra | 
+------------------+----------+------+-----+---------+-------+ 
| peripheral_id | int(2) | NO | PRI | NULL |  | 
| peripheral  | char(30) | NO |  | NULL |  | 
| peripheral_total | int(5) | NO |  | NULL |  | 
+------------------+----------+------+-----+---------+-------+ 

mysql> select * from peripheral; 
+---------------+-----------------+------------------+ 
| peripheral_id | peripheral  | peripheral_total | 
+---------------+-----------------+------------------+ 
|    1 | periph 1  |    0 | 
|    2 | periph 2  |    1 | 
|    3 | periph 3  |    3 | 
+---------------+-----------------+------------------+ 

mysql> describe lookup_peripheral; 
+---------------+---------+------+-----+---------+-------+ 
| Field   | Type | Null | Key | Default | Extra | 
+---------------+---------+------+-----+---------+-------+ 
| content_id | int(10) | NO | MUL | NULL |  | 
| peripheral_id | int(2) | NO |  | NULL |  | 
+---------------+---------+------+-----+---------+-------+ 


mysql> mysql> select * from lookup_peripheral; 
+------------+---------------+ 
| content_id | peripheral_id | 
+------------+---------------+ 
|   74 |    2 | 
|   74 |    5 | 
|   75 |    2 | 
|   75 |    5 | 
|   76 |    3 | 
|   76 |    4 | 
+------------+---------------+ 

SELECT group_concat(DISTINCT peripheral.peripheral_id) as peripheral_id, group_concat(DISTINCT programming_language.programming_language_id) as programming_language_id, c.member_name, c.member_id, c.added_date_time, c.title, c.raw_summary, c.raw_all_content, c.meta_tags, c.main_pic_thumb, application.application_id, architecture.architecture_id, compiler.compiler_id, device_family.device_family_id, difficulty.difficulty_id, ide.ide_id, programmer.programmer_id, table_name.table_name_id, device_name.device_name 
FROM (content as c) 
INNER JOIN lookup_peripheral ON 76 = lookup_peripheral.content_id 
INNER JOIN peripheral ON peripheral.peripheral_id = lookup_peripheral.peripheral_id 
INNER JOIN lookup_programming_language ON 76 = lookup_programming_language.content_id 
INNER JOIN programming_language ON programming_language.programming_language_id = lookup_programming_language.programming_language_id 
....... 
LEFT OUTER JOIN device_name ON device_name.content_id = c.content_id 
INNER JOIN table_name ON table_name.table_name_id = lookup_table_name.table_name_id 
WHERE `c`.`content_id` = '76' 

回答

0

我想你也應該索引lookup_peripheral.peripheral_id領域。索引外鍵使得INNER JOIN更快。另外,你是否真的需要DISTINCT子句,因爲你在連接ID字段? 關於第二個想法,也許你可以省略GROUP_CONCATs和內部聯接(你的一些JOIN條件重疊,我相信,糾正我,如果我錯了)

... (SELECT GROUP_CONCAT(l.peripheral_id) from lookup_peripheral lp where lp.content_id = 76) as peripheral_id, ... 

希望這有助於。