我尝试创建一个规范化的数据库。因此,我试图加入21个表。我正在使用连接中几乎所有表的索引,如EXPLAIN
语句的下面屏幕截图所示。
所有lookup_xxxxx
表在2列上都有一个索引(content_id和xxxxxx_id)
所有xxxxxx
表在1列(xxxxx_id)上都有一个索引
我每张表中只有大约10行。我看到的问题是两个goup_concat
将查询延长了200ms。我允许提交字段peripheral
和programming language
具有多个值。没有它们,查询小于80毫秒。
我的问题是我是否应该取消group_concats
并为他们做个别查询或重建我的数据库。
lookup_xxxxx
表存储每个允许的值,然后其他表(例如peripheral
)通过content_id将提交链接到允许的值。所有内容都以提交content_id
为参考。 content
表包含成员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 :(得分:0)
我认为您还应该INDEX_ lookup_peripheral.peripheral_id字段。索引外键使INNER JOIN更快。另外,你真的需要DISTINCT子句,因为你连接ID字段? 第二个想法,也许你可以省略GROUP_CONCATs和INNER JOINs(我相信你的一些JOIN条件重叠,如果我弄错了,请纠正我)
... (SELECT GROUP_CONCAT(l.peripheral_id) from lookup_peripheral lp where lp.content_id = 76) as peripheral_id, ...
希望这有帮助。