php - mysql多JOIN查询优化

标签 php mysql

我正在构建一个 mysql 查询来根据访问权限访问视频,但我能想到的唯一一个在我们的服务器上执行最多需要 0.5 秒。

访问权限相当灵活,因此有点复杂。 表:

vod_reunion 每个视频包含 1 行内容 相关列是:Id(唯一标识符)和“active”

每个视频属于 1 个或多个类别,如下表所示:

vod_appart_droit ID_theme(类别的 ID) ID_reunion(视频的 ID,因此与第一个表的 ID 匹配)

每个用户可以属于某些组:

appartenance_groupe 定义哪个用户属于哪个组: ID_组 ID_成员 现在实际权利:

vod_droit: ID_groupe:如果记录是关于管理对组的访问,则组的 ID,否则为“-1” ID_membre:如果记录是关于管理直接对用户的访问,则用户的 ID,否则为“-1” ID_theme:用户或组可以访问的类别的Id Droit:该组或用户对类别的访问级别,值为: 2:允许访问 1:允许访问第一个表“vod_reunion”中其标志“active”设置为 1 的此类视频 0:无权访问该类别 -1:禁止该用户或组访问该类别的视频,即使同一视频属于同一组有权访问的其他类别。

所以这是查询:

SELECT
     DISTINCT r.*, vu.vu
FROM
vod_reunion r
LEFT JOIN
    (
        vod_appart_droit ad
    INNER JOIN
        vod_droit vd
        ON
        ad.ID_theme = vd.ID_theme AND 
        (vd.Droit =2 OR vd.Droit=1)
    INNER JOIN
        appartenance_groupe ag
        ON
        vd.ID_groupe = ag.ID_groupe AND
        ag.ID_membre=11
    )
    ON
    r.Id = ad.ID_reunion AND 
    (vd.Droit =2 OR (vd.Droit=1 AND r.active=1))


    LEFT JOIN
    (
        vod_appart_droit adn
    INNER JOIN
        vod_droit vnd
        ON
        adn.ID_theme = vnd.ID_theme AND 
        vnd.Droit =-1
    INNER JOIN
        appartenance_groupe ang
        ON
        vnd.ID_groupe = ang.ID_groupe AND
        ang.ID_membre=11  
    )
    ON
    r.Id = adn.ID_reunion AND
    ag.ID_groupe = ang.ID_groupe


    LEFT JOIN
    (
        vod_appart_droit adm
    INNER JOIN
        vod_droit vdm
        ON
        adm.ID_theme = vdm.ID_theme AND 
        (vdm.Droit =2 OR vdm.Droit=1) AND
        vdm.ID_membre=11
    )
    ON
    r.Id = adm.ID_reunion AND 
    (vdm.Droit =2 OR (vdm.Droit=1 AND r.active=1))

    LEFT JOIN
    (
        vod_appart_droit adnm
    INNER JOIN
        vod_droit vndm
        ON
        adnm.ID_theme = vndm.ID_theme AND 
        vndm.Droit =-1 AND
        vndm.ID_membre=11
    )
    ON
    r.Id = adnm.ID_reunion

    LEFT JOIN 
    vod_vu vu ON r.Id=vu.ID_reunion AND vu.ID_membre='11'

WHERE
    (r.langue = 0 OR r.langue = 2) AND
    ((vd.Droit IS NOT NULL AND vnd.Droit IS NULL) OR
    (vdm.Droit IS NOT NULL AND vndm.Droit IS NULL))

注意,这里的where子句实际上被简化了,我只留下了与访问权限相关的部分,但随后有多个条件用于搜索和排序。

您对如何加速此查询有任何帮助吗? 请注意,当我连续多次运行它时,它可以运行得非常快,但我猜这是由于 mysql 的某些缓存功能所致。

谢谢 蒂莫西

最佳答案

评论太长了。

首先,如果不需要,请删除distinct

其次,将 WHERE 子句编写为 r.langue IN (0, 2) 并确保该列上有索引。

第三,如果您需要不同的值,请删除连接。相反,请在 WHERE 子句中使用 NOT EXISTS

这些是一些可能有助于提高性能的想法。我还假设明显的列已正确索引(例如 join 中使用的列)。

关于php - mysql多JOIN查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30843580/

相关文章:

php - Codeigniter - 插入两个表,第二个表中包含用户 ID

mysql - MySQL 如何选择列..?

php - 这个 `#((?<=\?)|&)openid\.[^&]+#` 正则表达式是什么意思?

javascript - 成功功能在ajax中不起作用

php - 如何将不同模型的两个不同 id 从 Controller 传递到 View

Mysql时间戳类型

mysql - 使用 MySQL 查找所有不具有 “nofollow” 属性的外部链接

mysql - 在 MySql 中计算组内的不同重复项

javascript - 将 HTML 推送到网页(JS VS PHP)

javascript - 根据所选项目提交表格