title: Slow Group_concat query
body: <p>I tried to create a normalized database. Because of this, I am attempting to join 21 tables. I am using an index on almost all of the tables in the join as seen in the below screenshot of the <code>EXPLAIN</code> statement. </p>
  
  <p><a href="http://i.imgur.com/V5hQu.png" rel="nofollow">http://i.imgur.com/V5hQu.png</a></p>
  
  <p>All <code>lookup_xxxxx</code> tables have one index on 2 columns (content_id and xxxxxx_id)
  All <code>xxxxxx</code> tables have one index on 1 column (xxxxx_id)</p>
  
  <p><strong>I only have about 10 or so rows in each table</strong>. The problem I am seeing is that the two <code>goup_concat</code> prolong the query an extra 200ms. I allow the submission fields, <code>peripheral</code> and <code>programming language</code> to have multiple values. Without them, the query is less than 80ms. 
  My question is whether or not I should do away with the <code>group_concats</code> and do individual query's for them or reconstruct my database. </p>
  
  <p>The <code>lookup_xxxxx</code> tables store each allowed value and then the other tables such as <code>peripheral</code> link the submission to the allowed value via the content_id. Everything is referenced to the submission <code>content_id</code>. The <code>content</code> table holds essential info such as member id, name, etc.  </p>
  
  <p>I apologize if my post is not clear enough.  </p>
  
  <pre><code>mysql&gt; 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&gt; select * from peripheral;
  +---------------+-----------------+------------------+
  | peripheral_id | peripheral      | peripheral_total |
  +---------------+-----------------+------------------+
  |             1 | periph 1        |                0 |
  |             2 | periph 2        |                1 |
  |             3 | periph 3        |                3 |
  +---------------+-----------------+------------------+
  </code></pre>
  
  <p>:</p>
  
  <pre><code>mysql&gt; describe lookup_peripheral;
  +---------------+---------+------+-----+---------+-------+
  | Field         | Type    | Null | Key | Default | Extra |
  +---------------+---------+------+-----+---------+-------+
  | content_id    | int(10) | NO   | MUL | NULL    |       |
  | peripheral_id | int(2)  | NO   |     | NULL    |       |
  +---------------+---------+------+-----+---------+-------+  
  
  
  mysql&gt; mysql&gt; select * from lookup_peripheral;
  +------------+---------------+
  | content_id | peripheral_id |
  +------------+---------------+
  |         74 |             2 |
  |         74 |             5 |
  |         75 |             2 |
  |         75 |             5 |
  |         76 |             3 |
  |         76 |             4 |
  +------------+---------------+
  </code></pre>
  
  <p></p>
  
  <pre><code>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'  
  </code></pre>