我有一个MySQL查询,用于确定一个设备(只有3个)是否同时被四个并发事件使用。我有一个工作查询,但似乎效率低下,我很好奇是否有更好的方法来进行选择。
表结构(与查询无关的列已被删除)该表当前包含大约7-8k行。
CREATE TABLE IF NOT EXISTS `tc_event` (
`WorkOrderNumber` int(11) NOT NULL DEFAULT '0',
`EventName` varchar(120) DEFAULT NULL,
`CrewStartTime` datetime DEFAULT NULL,
`CrewEndTime` datetime DEFAULT NULL,
`SoundConsole` varchar(30) DEFAULT NULL,
`Canceled` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`WorkOrderNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
当前(工作)查询:
SELECT UNIX_TIMESTAMP(T1.CrewStartTime) AS ConflictDate
FROM tc_event T1, tc_event T2, tc_event T3, tc_event T4
WHERE
(T1.CrewStartTime BETWEEN T2.CrewStartTime AND T2.CrewEndTime)
AND (T1.CrewStartTime BETWEEN T3.CrewStartTime AND T3.CrewEndTime)
AND (T1.CrewStartTime BETWEEN T4.CrewStartTime AND T4.CrewEndTime)
AND (T2.CrewSTartTime BETWEEN T3.CrewStartTime AND T3.CrewEndTime)
AND (T2.CrewStartTime BETWEEN T4.CrewStartTime AND T4.CrewEndTime)
AND (T3.CrewStartTime BETWEEN T4.CrewStartTime AND T4.CrewEndTime)
AND T1.WorkOrderNumber != T2.WorkOrderNumber
AND T1.WorkOrderNumber != T3.WorkOrderNumber
AND T1.WorkOrderNumber != T4.WorkOrderNumber
AND T2.WorkOrderNumber != T3.WorkOrderNumber
AND T2.WorkOrderNumber != T4.WorkOrderNumber
AND T3.WorkOrderNumber != T4.WorkOrderNumber
AND T1.CrewStartTime > NOW()
AND T1.SoundConsole = '12-Chan/PA-12'
AND T2.SoundConsole = '12-Chan/PA-12'
AND T3.SoundConsole = '12-Chan/PA-12'
AND T4.SoundConsole = '12-Chan/PA-12'
AND (T1.Canceled = 0 AND T1.EventName NOT LIKE '%*NOTC*%')
AND (T2.Canceled = 0 AND T2.EventName NOT LIKE '%*NOTC*%')
AND (T3.Canceled = 0 AND T3.EventName NOT LIKE '%*NOTC*%')
AND (T4.Canceled = 0 AND T4.EventName NOT LIKE '%*NOTC*%')
GROUP BY DATE(T1.CrewStartTime)
ORDER BY T1.CrewStartTime
查询EXPLAIN语句:
答案 0 :(得分:1)
首先将不等式更改为小于/大于比较。这也简化了很多事情:
SELECT UNIX_TIMESTAMP(T1.CrewStartTime) AS ConflictDate
FROM tc_event T1, tc_event T2, tc_event T3, tc_event T4
WHERE
(T1.CrewStartTime BETWEEN T2.CrewStartTime AND T2.CrewEndTime)
AND (T2.CrewSTartTime BETWEEN T3.CrewStartTime AND T3.CrewEndTime)
AND (T3.CrewStartTime BETWEEN T4.CrewStartTime AND T4.CrewEndTime)
AND T1.WorkOrderNumber < T2.WorkOrderNumber
AND T2.WorkOrderNumber < T3.WorkOrderNumber
AND T3.WorkOrderNumber < T4.WorkOrderNumber
AND T1.CrewStartTime > NOW()
AND T1.SoundConsole = '12-Chan/PA-12'
AND T2.SoundConsole = '12-Chan/PA-12'
AND T3.SoundConsole = '12-Chan/PA-12'
AND T4.SoundConsole = '12-Chan/PA-12'
AND (T1.Canceled = 0 AND T1.EventName NOT LIKE '%*NOTC*%')
AND (T2.Canceled = 0 AND T2.EventName NOT LIKE '%*NOTC*%')
AND (T3.Canceled = 0 AND T3.EventName NOT LIKE '%*NOTC*%')
AND (T4.Canceled = 0 AND T4.EventName NOT LIKE '%*NOTC*%')
GROUP BY DATE(T1.CrewStartTime)
ORDER BY T1.CrewStartTime
之后你会在CrewStartTime
上添加一个索引,这对性能有很大帮助。您过滤的其他列上的索引也可能会有所帮助。
答案 1 :(得分:1)
您只想知道如果存在冲突,即同时有4个用户。为此,您只需查看事件开始时间并检查有多少并发事件:
select soundconsole, st.CrewStartTime, count(*)
from (select distinct CrewStartTime, soundconsole
from tc_event
) st join
tc_event e
on st.CrewStratTime between e.CrewStartTime and e.CrewEndTime and
st.soundconsole = e.soundconsole
group by st.CrewStartTime, tc.soundconsole
having count(*) >= 4