【发布时间】:2012-01-30 04:24:12
【问题描述】:
我需要一些帮助来优化我的数据库的一些查询。我确实了解使用索引来帮助连接和 order by 语句以帮助加快速度,但我想知道是否有一些技术可以避免使用文件排序和使用 EXPLAIN 命令时使用临时性。这是我正在使用的示例。
SELECT a.id, DATE_FORMAT(a.submitted_at, '%d-%b-%Y') as submitted_at, a.user_id,
data1.*,
data2.name, data2.type,
u.first_name, u.last_name
FROM applications AS a
LEFT JOIN users AS u ON u.id = a.user_id
LEFT JOIN score_table AS data1 ON data1.applications_id = a.id
LEFT JOIN sections AS data2 ON data2.id = data1.section_id
WHERE category_id = [value] && submitted_at IS NOT NULL
ORDER BY data2.type
再一次,索引在我的查询中得到了正确的使用,就像上面的查询一样。如果我取出 ORDER BY 子句,则查询会通过使用正确的索引快速执行。我了解连接的顺序会影响查询的性能。当我在 users 表上使用 ORDER BY 进行测试时,因为它是“const”之后的下一个表,所以它只会在 EXPLAIN 上使用“Using where,Using Filesort”。如果我转到任何其他表,我们就会遇到“使用临时”问题。
我的问题是:优化这样的查询以更快地运行并且在最佳情况下避免在 EXPLAIN 中使用 filesort/temporary 的最佳方法是什么?我对任何可能性持开放态度:) 我或多或少对如何使这样的查询执行得更好的理论感兴趣,而不是这个确切的查询,因为我必须执行越来越多的这些深层 ORDER BY 查询我正在处理的数据库。
--编辑--
这是上面查询的解释.....
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ref category_id,submitted_at category_id 4 const 49 Using where; Using temporary; Using filesort
1 SIMPLE u eq_ref PRIMARY PRIMARY 4 a.user_id 1
1 SIMPLE data1 ref app id app id 4 a.id 7
1 SIMPLE data2 eq_ref PRIMARY PRIMARY 4 data1.section_id 1
【问题讨论】:
-
在
join conditions中的字段和where子句中的字段和order by中的字段上是否有indexes? -
@piotrekkr 是的(以上所有),我刚刚编辑了我的帖子以反映这一点。
-
由于您对 LEFT JOINed 的表进行 ORDER BY,因此您将无法绕过临时表的创建。这是因为 MySQL 不能从同一个表中驱动查询,它是根据它排序的。
-
提供表格方案和
explain结果会很有帮助
标签: php mysql optimization join sql-order-by