简体   繁体   English

慢的Group_concat查询

[英]Slow Group_concat query

I tried to create a normalized database. 我试图创建一个规范化的数据库。 Because of this, I am attempting to join 21 tables. 因此,我试图加入21个表。 I am using an index on almost all of the tables in the join as seen in the below screenshot of the EXPLAIN statement. 我正在联接中几乎所有表上使用索引,如下面的EXPLAIN语句屏幕截图所示。

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

All lookup_xxxxx tables have one index on 2 columns (content_id and xxxxxx_id) All xxxxxx tables have one index on 1 column (xxxxx_id) 所有lookup_xxxxx表在2列上都有一个索引(content_id和xxxxxx_id)所有xxxxxx表在1列上都有一个索引(xxxxx_id)

I only have about 10 or so rows in each table . 每个表中只有大约10行左右 The problem I am seeing is that the two goup_concat prolong the query an extra 200ms. 我看到的问题是两个goup_concat将查询延长了200 goup_concat I allow the submission fields, peripheral and programming language to have multiple values. 我允许提交字段, peripheralprogramming language具有多个值。 Without them, the query is less than 80ms. 没有它们,查询时间将少于80ms。 My question is whether or not I should do away with the group_concats and do individual query's for them or reconstruct my database. 我的问题是我是否应该group_concats并对其进行单个查询或重建我的数据库。

The lookup_xxxxx tables store each allowed value and then the other tables such as peripheral link the submission to the allowed value via the content_id. lookup_xxxxx表存储每个允许的值,然后其他表(例如peripheral通过content_id将提交链接到允许的值。 Everything is referenced to the submission content_id . 一切都引用到提交content_id The content table holds essential info such as member id, name, etc. content表包含基本信息,例如成员ID,姓名等。

I apologize if my post is not clear enough. 如果我的帖子不够清楚,我深表歉意。

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'  

I think you should also INDEX the lookup_peripheral.peripheral_id field . 我认为您还应该索引lookup_peripheral.peripheral_id字段。 Indexing foreign keys makes INNER JOINs faster. 索引外键使INNER JOIN更快。 Also, do you really need the DISTINCT clause since you are concatenating ID fields? 另外,由于要串联ID字段,您是否真的需要DISTINCT子句? On second thought, maybe you could omit the GROUP_CONCATs and INNER JOINs (some of your JOIN conditions overlap I believe, correct me if I'm mistaken) 再次考虑,也许您可​​以忽略GROUP_CONCAT和INNER JOIN(我相信您的某些JOIN条件重叠,如果我弄错了,请更正我)

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM