MYSQL:在表格中优化排序

时间:2012-12-26 14:08:24

标签: mysql join

我正在为我的学院网站开发一个应用程序,我想从数据库中按升序日期顺序提取所有事件。总共有四个表:

表格事件1

event_id, mediumint(8), Unsigned
date,     date,                   

Index -> Primary Key (event_id)
Index -> (date)

表events_users

event_id, smallint(5),  Unsigned
user_id,  mediumint(8), Unsigned

Index -> PRIMARY (event_id, user_id)

表user_bm

link,    varchar(26)
user_id, mediumint(8)

Index -> PRIMARY (link, user_id)

表user_eoc

link,    varchar(8)
user_id, mediumint(8)

Index -> Primary (link, user_id)

查询:

EXPLAIN SELECT * FROM events1 E INNER JOIN event_users EU ON E.event_id = EU.event_id
 RIGHT JOIN user_eoc EOC ON EU.user_id = EOC.user_id
 INNER JOIN user_bm BM ON EOC.user_id = BM.user_id
WHERE E.date >= '2013-01-01' AND E.date <= '2013-01-31'
  AND EOC.link = "E690"
  AND BM.link like "1.1%"
ORDER BY E.date

说明:

上面的查询做了两件事。

1)通过user_bm和user_eoc表搜索并过滤掉所有学生。 “链接”列是非规范化列,可以按主要/年/校园等快速过滤学生。

2)应用过滤器后,MYSQL抓取所有匹配学生的user_ids并查找他们参加的所有事件并按升序输出。

QUERY OPTIMIZER EXPLAIN:

id  select_type     table   type      possible_keys     key     key_len     ref rows    Extra
1   SIMPLE  EOC     ref     PRIMARY     PRIMARY     26  const   47  Using where; Using index; Using temporary; Using f...
1   SIMPLE  BM  ref     PRIMARY,user_id-link    user_id-link    3   test.EOC.user_id    1   Using where; Using index
1   SIMPLE  EU  ref     PRIMARY,user_id     user_id     3   test.EOC.user_id    1   Using index
1   SIMPLE  E   eq_ref  PRIMARY,date-event_id   PRIMARY     3   test.EU.event_id    1   Using where

问题:

查询工作正常,但可以进行优化。具体来说 - 使用filesort和使用临时代价很高,我想避免这种情况。我不确定这是否可行,因为我希望按日期“排序”事件与匹配用户有1:n的关系。 Order BY适用于连接表。

非常感谢任何帮助或指导。谢谢你,节日快乐!

1 个答案:

答案 0 :(得分:0)

订购可以通过两种方式完成。按索引或临时表。您在表Events1中按日期排序,但它使用的是不包含日期的PRIMARY KEY,所以在这种情况下,结果需要在临时表中排序。

虽然不一定贵。如果结果足够小以适应内存,那么它就不会是磁盘上的临时表,只是在内存中而且并不昂贵。

也不是filesort。 “使用filesort”并不意味着它将使用任何文件,它只是意味着它不是按索引排序。

因此,如果您的查询执行得很快,您应该感到高兴。如果结果集很小,它将在内存中排序,不会创建任何文件。