【问题标题】:MySQL query performance problem - INNER JOIN, ORDER BY, DESCMySQL查询性能问题——INNER JOIN、ORDER BY、DESC
【发布时间】:2011-08-24 21:23:12
【问题描述】:

我有这个查询:

                SELECT 
                t.type_id, t.product_id, u.account_id, t.name, u.username

                FROM
                types AS t

                INNER JOIN
                ( SELECT user_id, username, account_id 
                  FROM users WHERE account_id=$account_id ) AS u

                ON 

                t.user_id = u.user_id 

                ORDER BY 
                t.type_id DESC

第一个问题:

目前完成此操作大约需要 30 秒,类型表中只有 18k 条记录。

目前唯一的索引只是一个只有 id 的主索引。

会不会是因为缺少更多的索引造成的?还是更多地与这个查询的结构有关?

第二个问题:

如何添加 LIMIT 以便我只能获得 100 条 type_id 最高的记录?

【问题讨论】:

  • 这不可能是真正的查询。您有一个 p 表别名,但没有将任何表别名为 p
  • 我简化了查询,以使其更清楚,对不起,我刚刚更正了。

标签: mysql join sql-order-by inner-join


【解决方案1】:

在不更改结果的情况下,如果您不对用户表进行子选择,我认为速度会快 100 倍。在这种情况下根本不需要它。

您只需添加 LIMIT 100 即可仅获得前 100 个结果(如果没有 100 个则更少)。

SELECT SQL_CALC_FOUND_ROWS /* Calculate the total number of rows, without the LIMIT */
  t.type_id, t.product_id, u.account_id, t.name, u.username
FROM
  types t
  INNER JOIN users u ON u.user_id = t.user_id
WHERE
  u.account_id = $account_id
ORDER BY
  t.type_id DESC
LIMIT 1

然后,执行第二个查询以获取计算的总行数。

SELECT FOUND_ROWS()

【讨论】:

  • 谢谢,我要试试这个。获得 100 个倒数第二个 type_id 有多容易?顺便提一句。抱歉打错了,“p”应该是“t”,请参阅上面的编辑
  • 我复制了那个错误。好吧,你明白了。 :) 我也曾查找过“倒数第二个”,但现在我做到了,我仍然不确定您的意思。
  • 我的意思是分页。如果 LIMIT 100 取范围:100 到 0,我该如何挖掘范围:200 到 100 ? :)
  • LIMIT 允许两个参数,可以这么说。您可以同时指定计数和偏移量,这确实非常适合分页。 php.about.com/od/mysqlcommands/g/Limit_sql.htm
  • 我尝试了您的查询,但它没有返回任何内容,即使我删除了限制
【解决方案2】:

MySQL 上的子选择会减慢您的查询速度。我假设这个

SELECT user_id, username, account_id 
FROM users WHERE account_id=$account_id

根本不返回很多行。如果是这种情况,那么单独的子选择将无法解释您看到的延迟。

尝试在类型表中的 user_id 上添加索引。没有它,您将对该子选择返回的每条记录进行 18k 条记录的全表扫描。

内部加入 users 表并添加该索引,我敢打赌你会看到速度的巨大提升。

【讨论】:

  • 子选择返回大约 14k 行
  • 你的意思是user_id上的单个索引还是type_id的主索引之外的(type_id,user_id)的复杂索引,有吗?
  • user_id 上的单个索引,因为这是您要加入的字段。
  • 子选择在内存中创建一个没有索引的“派生”表。您将它加入到另一个表中的列上,该表也没有索引,因此它正在扫描(派生表的大小)x(用户的大小)行。根据您所说的,大约有 2.5 亿行正在被扫描。我并不惊讶它需要 30 秒。
  • 很好 :) 那么在您看来我应该如何更改此查询轮次以获得最佳性能?
猜你喜欢
  • 2016-03-10
  • 2023-04-02
  • 1970-01-01
  • 2011-03-02
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
相关资源
最近更新 更多