我正在构建一个 mysql 查询以根据访问权限访问视频,但我唯一能想到的查询在我们的服务器上执行最多需要 0.5 秒。
访问权限相当灵活,因此有点复杂。表:
vod_reunion每个视频包含 1 行 相关列包括:ID(唯一标识符)和"活动"
每个视频属于下表中的一个或多个类别:
vod_appart_droit ID_theme(分类的ID) ID_reunion(视频的 ID,因此与第一个表的 ID 匹配)
每个用户可以属于某些组:
appartenance_groupe定义哪个组属于哪个用户: ID_groupe ID_membre现在实际权利:
vod_droit: ID_groupe:如果记录是关于管理对组的访问,则为组的 ID,否则为"-1" ID_membre:如果用户的 ID,如果记录是关于直接管理对用户的访问,否则为"-1" ID_theme:用户或组可以访问的类别的 ID 权限:此组或用户对具有以下值的类别的访问权限级别: 2:允许访问 1:允许此类别的视频在第一个表格"vod_reunion"中将其标志"有效"设置为 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
中使用的列)。