【问题标题】:Improving Efficiency of my SQL提高 mySQL 的效率
【发布时间】:2013-02-07 12:49:45
【问题描述】:

我有一个 LIKES(likeID、userID、objectID、likeDate)的 MySQL 表,我希望能够计算在相关用户之后所做的所有“喜欢”。

通常我会得到日期:

SELECT likeDate FROM LIKES WHERE userID = <logged in user's ID>

然后像这样查找所有日期并计算返回的行(或使用mysql COUNT):

SELECT * FROM LIKES WHERE likeDate > <given date>

但是,我确信有一种方法可以在一次查询中执行此操作,而不是对数据库进行两次调用。有人可以帮忙吗?

谢谢

【问题讨论】:

    标签: mysql sql subquery


    【解决方案1】:

    将第一个查询的结果直接输入第二个:

    SELECT COUNT(*)
    FROM LIKES
    WHERE likeDate > (
        SELECT max(likeDate)
        FROM LIKES
        WHERE userID = <logged in user's ID>
    )
    

    但请注意,您需要在第一个查询中添加 max() 的使用。

    此查询应该是获得答案的最快方式。为确保最佳性能,请在 userID 和 likeDate 上添加索引:

    create index likes_userId on likes(userID);
    create index likes_likeDate on likes(likeDate);
    

    【讨论】:

    • 感谢@Bohemian,但 lc 的回答不是更有效率吗?
    • 绝对不是!他的问题很糟糕——他的问题是 O(n),我的问题是 O(1)。即他的子查询对表中的每一行执行一次!我无法想象一个更糟糕的查询,如果它甚至有效的话。
    • 对于索引,最好建立两个索引,一个在两行 userID、likeDate 上,一个在 likeDate 上。这样你就可以让数据库更快地找到 max(likeDate) (much)
    • @Argeman 可能,但这是一个特定于用例的索引,其中仅用户 ID 上的索引会更加通用。我会建议尝试所有选项,看看什么最有效,并平衡你可以保持事情的简单程度
    • @Bohemian 考虑到 OP 从未符合条件,他们只想要 one 结果,您的评论有点苛刻。当我读到这个问题时,“......然后找到所有日期并计算......”我明白OP想要在每个喜欢的日期之后计算喜欢的次数。我的查询就是这样做的,为您在问题的查询中返回的每个日期提供一个计数。我想你一定是因为你的 ESP 而走运了。
    【解决方案2】:
    SELECT l1.likeDate, 
        (SELECT COUNT(1) FROM LIKES l2 WHERE l2.likeDate > l1.likeDate) AS likesAfter
    FROM LIKES l1
    WHERE userID = ?
    GROUP BY l1.likeDate
    

    或者作为一个连接,

    SELECT l1.likeDate, COUNT(1)
    FROM LIKES l1
    LEFT OUTER JOIN LIKES l2 ON l2.likeDate > l1.likeDate
    WHERE userID = ?
    GROUP BY l1.likeDate
    

    【讨论】:

    • 对,这里有一些很好的答案——关于哪个最有效的想法?
    【解决方案3】:
    SELECT * FROM LIKES WHERE likeDate > 
    IFNULL((SELECT max(likeDate) FROM LIKES WHERE userID = <logged in user's ID> 
                                      adn  objectId=<question's Id>),0)
    and objectId=<question's Id>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2017-12-06
      • 2012-06-30
      • 2012-06-18
      相关资源
      最近更新 更多