简体   繁体   English

MySQL ORDER BY多个连接的优化

[英]MySQL ORDER BY Optimization on Multiple Joins

I need some help optimizing some queries for my database. 我需要一些帮助来优化我的数据库的一些查询。 I do understand the use of indexes in helping with joins and order by statements to help speed things up, but I was wondering if there were some techniques available to avoid using filesort and using temporary when I use the EXPLAIN command. 我确实理解使用索引来帮助加入和按顺序排序以帮助加快速度,但我想知道是否有一些技术可以避免在使用EXPLAIN命令时使用filesort和使用临时。 Here's an example of what I am using. 这是我正在使用的一个例子。

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

Again, indexes are being used properly in my queries like the one up above. 同样,索引正在我的查询中正确使用,如上面的那个。 If I take out the ORDER BY clause, then the query executes quickly from using the proper indexes. 如果我取出ORDER BY子句,则使用正确的索引快速执行查询。 I understand that the order of the joins can affect the performance of the query. 我知道连接的顺序可能会影响查询的性能。 When I test using the ORDER BY on the users table, since it is the next table after the "const", it will only use "Using where, Using Filesort" on EXPLAIN. 当我在users表上使用ORDER BY进行测试时,由于它是“const”之后的下一个表,因此它将仅使用EXPLAIN上的“Using where,Using Filesort”。 If I drop to any of the other tables, we get into the "Using Temporary" issue. 如果我放到任何其他表,我们进入“使用临时”问题。

My question is: what would be the best way to optimize queries like this to run faster and in the best case scenario, avoid using filesort/temporary in EXPLAIN? 我的问题是:优化查询的最佳方法是运行得更快,在最佳情况下,避免在EXPLAIN中使用filesort / temporary? I'm open to any possibilities :) I'm more or less interested in the theory on how to make queries like this perform better, than this exact query as I am having to perform more and more of these deep level ORDER BY queries in the database I'm working on. 我对任何可能性开放:)我或多或少对如何使这样的查询表现更好的理论感兴趣,而不是这个确切的查询,因为我必须执行越来越多这些深层次的ORDER BY查询我正在研究的数据库。

--EDIT-- - 编辑 -

Here's the explain of the query above..... 这是以上查询的解释.....

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   

Couple of things. 几件事。

  1. Are you sure you need to use 'LEFT JOIN'? 你确定你需要使用'LEFT JOIN'吗? Looking at the query it looks like you can get away with 'INNER JOIN' which will reduce the number of potential rows. 查看查询,看起来您可以使用'INNER JOIN'来减少潜在行数。

  2. You didn't post your schema, but I assume that users.id, applications.user_id, score_table.applications_id, applications.id, sections.id and score_table.section_id are all ints? 您没有发布您的架构,但我认为users.id,applications.user_id,score_table.applications_id,applications.id,sections.id和score_table.section_id都是整数? If they are non-ints I would strongly urge you to convert them. 如果它们是非英特尔,我强烈建议你转换它们。 And if not primary keys, be sure they are indexed. 如果不是主键,请确保它们已编入索引。

  3. I wouldn't run any mysql level data formatting (ie DATE_FORMAT), as it will create some overhead during the query, rather I would format data like this at the app layer. 我不会运行任何mysql级别的数据格式化(即DATE_FORMAT),因为它会在查询期间产生一些开销,而是我会在app层格式化这样的数据。

  4. The ORDER BY forces MySQL to create a temp table in order to sort correctly, so be sure you absolutely need this functionality. ORDER BY强制MySQL创建临时表以便正确排序,因此请确保您绝对需要此功能。 If so, be sure that sections.type is indexed. 如果是这样,请确保将sections.type编入索引。

  5. I would consider using a different alias naming convention. 我会考虑使用不同的别名命名约定。 data1 and data2 are so abstract it's difficult to discern what they are actually referring to. data1和data2如此抽象,很难分辨出它们实际指的是什么。 I would suggest you use an abbreviated construct of the table you are aliasing, for example; 我建议你使用表格的缩写结构,例如; applications becomes app (instead of a), score_table becomes score (instead of data1), etc. 应用程序变为app(而不是a),score_table变为分数(而不是data1)等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM