如何优化 mysql 查询

Posted

技术标签:

【中文标题】如何优化 mysql 查询【英文标题】:how to optimize the mysql Query 【发布时间】:2016-12-10 13:15:13 【问题描述】:

如何提高这个mysql查询的性能

SELECT ''                                           AS sharedid,
       hubber_posts.userID                          AS postowner,
       hubber_posts.*,
       ''                                           AS sharedby,
       hubber_posts.userID                          AS userID,
       hubber_posts.posted_date                     AS DATE,
       ''                                           AS sharebyusr,
       ''                                           AS sharebyusrimg,
       Concat_ws(' ', firstname, lastname)          AS fullname,
       username                                     AS postedBy,
       hubber_user.image,
       hubber_user.gender                           AS gender,
       (SELECT accounttype
        FROM   hubber_user_security us
        WHERE  hubber_user.ID = us.userID
               AND hubber_posts.userID = us.userID) AS accounttype,
       ''                                           AS sharebyusrtype
FROM   hubber_posts
       INNER JOIN hubber_user
               ON hubber_posts.userID = hubber_user.ID
WHERE  hubber_posts.status = 1 

【问题讨论】:

请努力格式化查询。 我投票结束这个问题,因为性能问题应该包括解释分析和一些关于表大小、索引、当前时间性能、期望时间等的信息。慢是一个相对术语我们需要一个真正的价值来比较。 MySQL 也请阅读How-to-Ask 您确实需要阅读本文以获取建议,提出我们可以回答的问题。 meta.***.com/questions/271055/… 【参考方案1】:

您的示例代码有一个相关的子查询。截至 2016 年底,MySQL 在这些方面表现不佳。

尝试将其转换为 JOINed 表。

   SELECT all that stuff,
          us.accounttype
     FROM   hubber_posts
     JOIN hubber_user ON hubber_posts.userID = hubber_user.ID
     LEFT JOIN hubber_user_security us ON hubber_user.ID = us.userID
    WHERE  hubber_posts.status = 1 

我使用了LEFT JOIN。如果没有LEFT,则该表中没有匹配条目的任何行都将从结果集中被抑制。

【讨论】:

【参考方案2】:

你的查询本质上是这样的:

SELECT . . .
       (SELECT accounttype
        FROM   hubber_user_security us
        WHERE  u.ID = us.userID AND
               p.userID = us.userID
       ) AS accounttype,
       . . .
FROM hubber_posts p INNER JOIN
     hubber_user u
     ON p.userID = u.ID
WHERE p.status = 1 ;

对于这个查询,最佳索引是:

hubber_posts(status, userId) hubber_user(Id) hubber_user_security(userId)

我会注意到子查询有一个不必要的额外关联条件——用户 ID 已经相等。而且,如果有多种帐户类型,您可能会遇到错误。

您可能打算:

   (SELECT GROUP_CONCAT(accounttype)
    FROM   hubber_user_security us
    WHERE  u.ID = us.userID
   ) as accounttypes,

【讨论】:

【参考方案3】:

我的建议是支持一个联接,其中 hubber_posts 是基表,其他 2 个表使用嵌套循环联接。

无需为连接索引 hubber_posts。 hubber_user.ID 应该是一个 PK。 hubber_user_security.userID 应该被编入索引(并定义为 FK 引用 hubber_user.ID)。

至于 WHERE 子句 - 只有当 hubber_posts.status = 1 的行数相对较少时,才应在 hubber_posts.status 上添加索引

附言

因为连接包含条件 -

ON hubber_posts.userID = hubber_user.ID 

无需将hubber_posts.userIDhubber_user.IDus.userID 进行比较

【讨论】:

以上是关于如何优化 mysql 查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql如何优化以下语句,查询耗时太久了?

如何优化 mysql 查询

如何优化 mysql 查询

如何在 mysql 查询下进行优化(我是优化新手)

如何迭代优化 MySQL 查询?

如何优化Mysql千万级快速分页