首页 > 解决方案 > 优化两个表的 SQL 查询

问题描述

我对有很多行的表有一个 SQL 查询。所以这个查询运行了很长时间。如何优化此查询?这些表已经在 id 和friend_id 上有索引

SELECT u.id, u.first, u.last, 
  group_concat(u2.first, " " , u2.last) MyFriends 
  FROM Users u
  INNER JOIN Friends f ON f.user_id = u.id 
  INNER JOIN Users u2 ON u2.id = f.friend_id
  GROUP BY u.id;

这些是表结构:

CREATE TABLE Users ( 
  id int(10) unsigned NOT NULL, 
  first varchar(50) DEFAULT NULL, 
  last varchar(50) DEFAULT NULL, 
  city varchar(20) DEFAULT NULL, 
  country varchar(20) DEFAULT NULL, 
  Age tinyint(3) unsigned NOT NULL, 
  KEY users_idx_id (id)) 
ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE Friends ( 
  user_id int(10) unsigned NOT NULL, 
  friend_id int(10) unsigned NOT NULL, 
  KEY idx_friends (friend_id)) 
ENGINE=InnoDB DEFAULT CHARSET=latin1;

标签: mysqlsqlquery-optimization

解决方案


多对多映射表 ( Friends) 需要改进索引。删除您现在拥有的所有索引并添加

PRIMARY KEY(user_id, friend_id),
INDEX(friend_id, user_id)

更多讨论:http: //mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

Age是一个移动的目标。想一个更好的方法来存储它。

大约有 6 个国家的名字超过 20 个。“圣文森特和格林纳丁斯”是 32 个。

至于城市,“Poselok Uchebnogo Khozyaystva Srednego Professionalno-Tekhnicheskoye Uchilishche Nomer Odin”是 91 个字符。

ALTER TABLE Friends
    DROP INDEX idx_friends,
    ADD PRIMARY KEY(user_id, friend_id),
    ADD INDEX(friend_id, user_id);

每个表都应该有一个PRIMARY KEY

ALTER TABLE Users
    DROP INDEX users_idx_id,
    ADD PRIMARY KEY(user_id)

阅读有关AUTO_INCREMENT.

“执行计划”可以通过运行来获得EXPLAIN SELECT ...但是在这种情况下它不会提供很多线索。


推荐阅读