MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”
Posted
技术标签:
【中文标题】MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”【英文标题】:MySQL db is using "Using where; Using temporary; Using filesort" when sorting by date 【发布时间】:2011-07-22 07:56:47 【问题描述】:我有一个包含一堆记录的数据库,当我使用以下 SQL 加载页面时,它真的很慢。
SELECT goal.title, max(updates.date_updated) as update_sort
FROM `goal`
LEFT OUTER JOIN `update` `updates` ON (`updates`.`goal_id`=`goal`.`goal_id`)
WHERE (goal.private=0)
GROUP BY updates.goal_id
ORDER BY update_sort desc
LIMIT 12
当我进行解释时,它说它不使用任何键并且它搜索每一行。还告诉我它使用“使用位置;使用临时;使用文件排序”。
非常感谢任何帮助
谢谢
它需要按goal_id 分组,因为select 中的MAX() 只返回一行。
我要做的是从updates
表中为每个目标返回 MAX date_updated 行,然后按该列对其进行排序。
当前索引位于 goal.private 和 update.goal_id
EXPLAIN 的输出(无法上传图片,如果不清楚,请放在这里抱歉:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE goal ref private private 1 const 27 Using temporary; Using filesort
1 SIMPLE updates ref goal_id goal_id 4 goal.goal_id 1
【问题讨论】:
请发布完整的解释输出和表结构。顺便说一句,在对另一列进行分组时,mysql 不能使用索引进行排序(这就是您看到using filesort
的原因)。
goal.private
上有索引吗?使用private=0
可以选择多少行,该表总共有多少行?
请在您的问题中添加其他信息,例如EXPLAIN
的输出。作为评论,它不是很可读。
同时将所有当前索引发布到表中。
【参考方案1】:
SELECT u.date_updated, g.title
FROM updates u
JOIN goal g
ON g.goal_id = u.goal_id
WHERE u.id =
(
SELECT ui.id
FROM updates ui
WHERE ui.goal_id = u.goal_id
ORDER BY
ui.goal_id, ui.date_updated, ui.id
LIMIT 1
)
AND g.private = 0
ORDER BY
u.date_update, u.id
LIMIT 12
在updates
上创建两个索引以使查询快速运行:
updates (goal_id, date_updated, id)
updates (date_updated, id)
【讨论】:
似乎仍然使用这种方法临时使用 @user:请发布SHOW CREATE TABLE updates
和SHOW CREATE TABLE goal
的输出,以及EXPLAIN EXTENDED
的输出
@user:您还没有在update
上创建两个索引。如果您想摆脱filesort
,请创建它们。另外,请发布SHOW CREATE TABLE updates
和SHOW CREATE TABLE goal
的输出。
我确实添加了这些索引,但它没有删除使用临时表位,所以我删除了它们【参考方案2】:
我的猜测是 MAX() 函数会导致这种行为。它需要查看每条记录以决定选择哪些行。你想完成什么样的分组?
【讨论】:
当我不分组时,似乎返回了一个虚假的结果 不确定是什么导致了虚假计数,但是当我对其进行分组时它会修复它。有什么想法吗? 虚假结果是什么意思?是零吗?您能否为您的问题添加一个示例结果集?以上是关于MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”的主要内容,如果未能解决你的问题,请参考以下文章