MST
星途 面试题库

面试题:MySQL专家难度:复杂查询设计与简单查询替代分析

有一个社交媒体数据库,用户表(users)包含用户ID(user_id)、用户名(username)等字段,关系表(relationships)表示用户之间的关注关系,包含关注者ID(follower_id)和被关注者ID(followed_id),动态表(posts)包含动态ID(post_id)、用户ID(user_id)、发布时间(post_time)、动态内容(post_content)。现在要求获取每个用户及其所关注用户发布的最新5条动态,并且按照动态发布时间倒序排列。请深入探讨简单查询能否解决此问题,如果不能请详细设计复杂查询,并阐述复杂查询中使用到的关键技术及其对性能的影响。
18.6万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

简单查询分析

简单查询难以解决此问题。简单查询通常适用于单表操作或多表简单关联获取直接数据。而本题需求涉及多表复杂关联(用户表、关系表、动态表),要获取每个用户及其关注用户的最新动态,还需按发布时间倒序并限制数量,简单查询无法满足这种复杂逻辑。

复杂查询设计

以MySQL为例:

WITH UserFollowedPosts AS (
    SELECT 
        r.follower_id,
        p.post_id,
        p.user_id,
        p.post_time,
        p.post_content
    FROM 
        relationships r
    JOIN 
        posts p ON r.followed_id = p.user_id
    UNION ALL
    SELECT 
        u.user_id AS follower_id,
        p.post_id,
        p.user_id,
        p.post_time,
        p.post_content
    FROM 
        users u
    JOIN 
        posts p ON u.user_id = p.user_id
)
SELECT 
    uf.follower_id,
    uf.post_id,
    uf.user_id,
    uf.post_time,
    uf.post_content
FROM (
    SELECT 
        follower_id,
        post_id,
        user_id,
        post_time,
        post_content,
        ROW_NUMBER() OVER (PARTITION BY follower_id ORDER BY post_time DESC) AS rn
    FROM 
        UserFollowedPosts
) uf
WHERE 
    uf.rn <= 5
ORDER BY 
    uf.follower_id, uf.post_time DESC;

关键技术及性能影响

  1. CTE(Common Table Expression,公用表表达式)
    • 关键作用:通过WITH UserFollowedPosts AS (...)定义了一个临时表UserFollowedPosts,它结合了用户自身发布的动态以及其关注用户发布的动态。使得复杂查询逻辑可以模块化,提高了查询的可读性和可维护性。
    • 性能影响:在计算CTE时,数据库会将其结果集缓存起来,如果后续多次引用该CTE,不会重复计算,在一定程度上提高了效率。但如果CTE生成的结果集非常大,会占用较多的内存或临时存储,可能影响整体性能。
  2. UNION ALL
    • 关键作用:用于合并用户自身发布动态的结果集和其关注用户发布动态的结果集。UNION ALL不会去重,保留所有记录,满足本题获取所有相关动态的需求。
    • 性能影响:相比UNION(会去重),UNION ALL性能更好,因为它无需进行额外的去重操作。但如果存在大量重复记录,会增加后续处理的数据量,对内存和处理时间有一定影响。
  3. 窗口函数(ROW_NUMBER())
    • 关键作用ROW_NUMBER() OVER (PARTITION BY follower_id ORDER BY post_time DESC)根据follower_id分区,在每个分区内按post_time倒序为每条记录生成一个唯一的行号。通过这种方式,可以方便地筛选出每个用户(follower_id)对应的最新5条动态。
    • 性能影响:窗口函数的计算依赖于整个分区的数据,当数据量较大时,计算成本较高。但合理使用窗口函数可以避免复杂的自连接操作,在某些情况下整体性能可能优于其他方法。
  4. 子查询和过滤条件
    • 关键作用:最外层子查询中WHERE uf.rn <= 5用于筛选出每个用户对应的最新5条动态,ORDER BY uf.follower_id, uf.post_time DESC按用户ID和动态发布时间倒序排列最终结果。
    • 性能影响:合理的过滤条件可以减少最终返回的数据量,提高查询性能。但如果过滤条件不合理,如使用函数操作列,可能导致索引无法使用,从而降低查询效率。