我需要一些帮助来优化我的数据库的一些查询。我确实理解使用索引来帮助加入和按顺序排序以帮助加快速度,但我想知道是否有一些技术可以避免在使用EXPLAIN命令时使用filesort和使用临时。这是我正在使用的一个例子。
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
答案 0 :(得分:4)
一些事情。
您确定需要使用'LEFT JOIN'吗?查看查询,看起来您可以使用“INNER JOIN”来减少可能的行数。
您没有发布您的架构,但我认为users.id,applications.user_id,score_table.applications_id,applications.id,sections.id和score_table.section_id都是整数?如果它们是非英特尔,我强烈建议你转换它们。如果不是主键,请确保它们已编入索引。
我不会运行任何mysql级数据格式化(即DATE_FORMAT),因为它会在查询期间产生一些开销,而是我会在应用层格式化这样的数据。
ORDER BY强制MySQL创建临时表以便正确排序,因此请确保您绝对需要此功能。如果是这样,请确保将sections.type编入索引。
我会考虑使用不同的别名命名约定。 data1和data2如此抽象,很难分辨出它们实际指的是什么。我建议你使用表格的缩写结构,例如;应用程序变为app(而不是a),score_table变为分数(而不是data1)等。