2017-06-16 60 views
3

我有7个表格。表1是“父表”和表2-7的关系。mysql 7 +加入桌面,如何加速?

我想进行一次查询,获取表1的行,以及表2-7中的id列表。我已经尝试了下面的查询,但对于大型数据库,我的查询需要15秒。我想知道如何让这个查询更快?

编辑有两点要注意: - >删除几个不同的不仅节省了4秒钟,然后我仍然得到10-11秒

查询

- >删除1从连接表(并不重要)该查询将时间从15秒减少到2-3秒。删除2个连接表(再次无关紧要)将查询减少到1/2秒。

SELECT 
    table1.table1_id as table1Id, 
    GROUP_CONCAT(DISTINCT table2.table2_id) AS table2Ids, 
    GROUP_CONCAT(DISTINCT table3.table3_id) AS table3Ids, 
    GROUP_CONCAT(DISTINCT table4.table4_id) AS table4Ids, 
    GROUP_CONCAT(DISTINCT table5.table5_id) AS table5Ids, 
    GROUP_CONCAT(DISTINCT table6.table6_id) AS table6Ids, 
    GROUP_CONCAT(DISTINCT table7.table7_id) AS table7Ids 
    FROM table1 
    LEFT JOIN table2 ON table1.table1_id = table2.table1_id 
    LEFT JOIN table3 ON table1.table1_id = table3.table1_id 
    LEFT JOIN table4 ON table1.table1_id = table4.table1_id 
    LEFT JOIN table5 ON table1.table1_id = table5.table1_id 
    LEFT JOIN table6 ON table1.table1_id = table6.table1_id 
    LEFT JOIN table7 ON table1.table1_id = table7.table1_id 
    WHERE table1.archived = false 
    GROUP BY table1.table1_id LIMIT 1000 

我解释查询:

+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------------------------+---------------------------+---------+--------------------------+------+----------+-------------+ 
| id | select_type | table   | partitions | type | possible_keys                      | key      | key_len | ref      | rows | filtered | Extra  | 
+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------------------------+---------------------------+---------+--------------------------+------+----------+-------------+ 
| 1 | SIMPLE  | table1   | NULL  | index | PRIMARY,unique_name_in_table8, table8_idx,table9_idx,table10_idx         | PRIMARY     | 4  | NULL      | 1 | 10.00 | Using where | 
| 1 | SIMPLE  | table2   | NULL  | ref | PRIMARY                       | PRIMARY     | 4  | db.table1.table1_id  | 20 | 100.00 | Using index | 
| 1 | SIMPLE  | table3   | NULL  | ref | table3_to_table1_id_idx                   | table3_to_table1_id_idx | 4  | db.table1.table1_id  | 824 | 100.00 | Using index | 
| 1 | SIMPLE  | table4   | NULL  | ref | table4_word_unique,table4_to_table1_id_idx               | table4_to_table1_id_idx | 4  | db.table1.table1_id  | 4 | 100.00 | Using index | 
| 1 | SIMPLE  | table5   | NULL  | ref | table5_to_table1_id_idx                   | table5_to_table1_id_idx | 4  | db.table1.table1_id  | 26 | 100.00 | Using index | 
| 1 | SIMPLE  | table6   | NULL  | ref | table6_to_table1_id_idx                   | table6_to_table1_id_idx | 4  | db.table1.table1_id  | 3 | 100.00 | Using index | 
| 1 | SIMPLE  | table7   | NULL  | ref | table7_to_table1_id_idx                   | table7_to_table1_id_idx | 4  | db.table1.table1_id  | 483 | 100.00 | Using index | 
+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------------------------+---------------------------+---------+--------------------------+------+----------+-------------+ 
+0

是否可以消除'distinct'? AFAIK,它在后端造成负担。 –

+0

@PrabhatG我已添加评论。消除不同的只保存4秒,我宁愿没有重复。有没有更有效的方法来运行此查询? –

+0

你可以加入这个[chat](http://chat.stackoverflow.com/rooms/146828/chat-for-mysql-7-joins-on-a-table-how-to-speed-up) –

回答

0

我试图重写查询。试着让我知道。我没有测试过它。

SELECT 
    t1.table1Id, 
    GROUP_CONCAT(DISTINCT table2.table2_id) AS table2Ids, 
    GROUP_CONCAT(DISTINCT table3.table3_id) AS table3Ids, 
    GROUP_CONCAT(DISTINCT table4.table4_id) AS table4Ids, 
    GROUP_CONCAT(DISTINCT table5.table5_id) AS table5Ids, 
    GROUP_CONCAT(DISTINCT table6.table6_id) AS table6Ids, 
    GROUP_CONCAT(DISTINCT table7.table7_id) AS table7Ids 
FROM (
    SELECT table1_id as table1Id 
    FROM table1 
    WHERE table1.archived = false 
    GROUP BY table1.table1_id LIMIT 1000 
    ) AS t1 
    INNER JOIN table2 ON t1.table1Id = table2.table1_id 
    INNER JOIN table3 ON t1.table1Id = table3.table1_id 
    INNER JOIN table4 ON t1.table1Id = table4.table1_id 
    INNER JOIN table5 ON t1.table1Id = table5.table1_id 
    INNER JOIN table6 ON t1.table1Id = table6.table1_id 
    INNER JOIN table7 ON t1.table1Id = table7.table1_id 
0

的解释说,table2不会对table1Id的索引。

尝试:

create index table2_to_table1_id_idx on table2(table1Id); 

这可能会提高性能足够了,但对于这个特定的查询创建覆盖索引,以最大限度地提高性能:

create index table2_table1_id_idx on table2(table1Id, table2Id); 
create index table3_table1_id_idx on table3(table1Id, table3Id); 
create index table4_table1_id_idx on table4(table1Id, table4Id); 
create index table5_table1_id_idx on table5(table1Id, table5Id); 
create index table6_table1_id_idx on table6(table1Id, table6Id); 
create index table7_table1_id_idx on table7(table1Id, table7Id); 

有了这些指标意味着你能避免击中基表完全。

+0

学习者的好奇心。你能解释一下你的答案吗?你怎么确定索引是否通过'explain'来解决。覆盖指数如何避免完全撞击基表? –