【问题标题】:Mysql - Using temporary; Using filesortMysql - 使用临时的;使用文件排序
【发布时间】:2016-09-27 10:18:33
【问题描述】:

我有两张这样的桌子

CREATE TABLE `vendors` (
  vid int(10) unsigned NOT NULL AUTO_INCREMENT,
  updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (vid),
  key(updated)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `products` (
  vid int(10) unsigned NOT NULL default 0,
  pid int unsigned default 0,
  flag int(11) unsigned DEFAULT '0',
  PRIMARY KEY (vid),
  KEY (pid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这是一个简单的查询

> explain select vendors.vid, pid from products, vendors where pid=1 and vendors.vid=products.vid order by updated;
+------+-------------+----------+--------+---------------+---------+---------+---------------------+------+----------------------------------------------+
| id   | select_type | table    | type   | possible_keys | key     | key_len | ref                 | rows | Extra                                        |
+------+-------------+----------+--------+---------------+---------+---------+---------------------+------+----------------------------------------------+
|    1 | SIMPLE      | products | ref    | PRIMARY,pid   | pid     | 5       | const               |    1 | Using index; Using temporary; Using filesort |
|    1 | SIMPLE      | vendors  | eq_ref | PRIMARY       | PRIMARY | 4       | social.products.vid |    1 |                                              |
+------+-------------+----------+--------+---------------+---------+---------+---------------------+------+----------------------------------------------+

我想知道为什么 mysql 需要使用临时表和文件排序来进行如此简单的查询。如您所见,ORDER BY 字段具有索引。

这里的mysql小提琴:http://sqlfiddle.com/#!9/3d9be/30

【问题讨论】:

  • 可能没有什么可修复的。您希望结果集中有多少行?不用担心对 100 行进行排序。

标签: mysql join explain


【解决方案1】:

在这种情况下,这将是最佳查询,并不总是必须去索引以获得最快的结果。当记录数增加时,优化器可能会选择使用索引。您可以尝试插入 10,000 条虚拟记录,看看是否是这种情况。

如果我在这里翻转条件,你会发现它会使用索引,因为我已经提供了在查询后面加入 where 条件的表。连接完成后,我们需要查看表产品中的记录,所以本质上我做得比较辛苦,所以使用了索引。它仍然会同时运行。您可以尝试将 2 个查询相互对照,看看会发生什么。这里是:

EXPLAIN
SELECT vendors.vid, products.pid 
FROM vendors 
INNER JOIN products ON vendors.vid = products.vid
WHERE pid = 1
ORDER BY vendors.updated DESC

你可以在这里找到详细的解释:Fix Using where; Using temporary; Using filesort

【讨论】:

  • 您的查询应该产生相同的执行计划。如果要强制 MySQL 首先从供应商表中读取,则需要使用 STRAIGHT_JOIN 或 FORCE INDEX(updated)。
猜你喜欢
  • 2016-09-04
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 2012-05-23
相关资源
最近更新 更多