如何使这个SQL查询更有效?

时间:2017-11-06 22:29:17

标签: mysql sql query-optimization

我不确定如何使以下SQL查询更有效。现在,查询在一台非常快的服务器上花费了8到12秒,但是当用户尝试加载带有此代码的页面时,这对于网站而言并不足够快。它正在查看包含许多行的表,例如“Post”表有717,873行。基本上,查询列出了与用户所关注的内容相关的所有帖子(从最新到最旧)。

有没有办法通过仅根据PostTimeOrder获得最后20个结果总数来加快速度?

对于可以采取任何措施来改善这种情况,我们将非常感激或深入了解任何帮助。谢谢。

这是完整的SQL查询(大量嵌套):

 public function checkCredentials($credentials, $userInterface $user)
    ...
    $password = $credentials['_password']; 
    $login_format = 'DOMAIN\%s';  // this is the expected format in my case
    $login_username = sprintf($login_format, $user);
    ...
    try {
        // try to bind with the username and provided password
        $this->ldap->bind($login_username, $password);
    } catch (\Symfony\Component\Ldap\Exception\ConnectionException $e) {
        //return false;
        throw new CustomUserMessageAuthenticationException('The submitted LDAP password is invalid.');
    };
        return true;
    };

2 个答案:

答案 0 :(得分:0)

p.ID in (...)谓词更改为具有相关子查询的存在谓词可能有帮助。此外,由于你的union的两半都是从Post表中提取的,并且可能返回几乎相同的记录,你可能能够通过左外连接到UserPostE将两者合并为一个查询添加upe.PostID不是OR子句中的WHERE条件。 UserFollowing仍然会加入UPE。如果您希望同一帖子记录两次upe.PostEchoTime一次,p.PostCreationTime一次PostTimeOrder,则需要保留UNION ALL

SELECT 
       DISTINCT -- <<=- May not be needed
       p.Id
     , UNIX_TIMESTAMP(p.PostCreationTime) AS PostCreationTime
     , p.Content AS Content
     , p.Bu AS Bu
     , p.Se AS Se
     , UNIX_TIMESTAMP(coalesce( upe.PostEchoTime
                              , p.PostCreationTime)) AS PostTimeOrder
  FROM Post p 
  LEFT JOIN UserPostE upe 
       INNER JOIN UserFollowing uf 
          on (upe.UserId = uf.FollowedId AND
             (uf.FollowingId = '100' OR
              upe.UserId = '100'))
    on p.Id = upe.PostId 
 WHERE upe.PostID is not null
    or exists (SELECT 1
                 FROM PostCreator pc
                WHERE pc.PostId = p.ID
                  and pc.UserId = '100'
                   or exists (SELECT 1
                                FROM UserFollowing uf
                               WHERE uf.FollowedId = pc.UserID
                                 and uf.FollowingId = '100')
              )
    OR exists (SELECT 1
                 FROM PostUserMentions pum
                WHERE pum.PostId = p.ID
                  and pum.UserId = '100'
                   or exists (SELECT 1
                                FROM UserFollowing uf
                               WHERE uf.FollowedId = pum.UserId
                                 and uf.FollowingId = '100')
              )
    OR exists (SELECT 1
                 FROM SStreamPost ssp
                WHERE ssp.PostId = p.ID
                  and exists (SELECT 1
                                FROM SStreamFollowing ssf
                               WHERE ssf.SStreamId = ssp.SStreamId
                                 and ssf.UserId = '100')
              )
    OR exists (SELECT 1
                 FROM PostSMentions psm
                WHERE psm.PostId = p.ID
                  and exists (SELECT 
                                FROM StockFollowing sf
                               WHERE sf.StockId = psm.StockId
                                 and sf.UserId = '100' )
              )
 ORDER BY PostTimeOrder DESC

也可以重写from部分以使用带有相关子查询的exists子句:

  FROM Post p 
  LEFT JOIN UserPostE upe 
    on p.Id = upe.PostId 
   and ( upe.UserId = '100'
      or exists (select 1
                   from UserFollowing uf
                  where uf.FollwedID = upe.UserID
                    and uf.FollowingId = '100'))

答案 1 :(得分:0)

IN的示例:

SELECT  ssp.PostId
    FROM  SStreamPost ssp
    WHERE  (ssp.SStreamId IN (
                SELECT  ssf.SStreamId
                    FROM  SStreamFollowing ssf
                    WHERE  ssf.UserId = '100' ))

- &GT;

SELECT  ssp.PostId
    FROM  SStreamPost ssp
    JOIN  SStreamFollowing ssf  ON ssp.SStreamId = ssf.SStreamId
    WHERE  ssf.UserId = '100'

所有WHERE的大INs变为类似

JOIN ( ( SELECT pc.PostId AS id ... )
 UNION ( SELECT pum.PostId ... )
 UNION ( SELECT ssp.PostId ... )
 UNION ( SELECT psm.PostId ... ) )

获取您可以做的那些建议,然后在需要时再回来寻求更多建议。并随身携带SHOW CREATE TABLE

相关问题