我正在构建一个 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/