简体   繁体   English

选择满足标准MySQL的四个并发事件

[英]Select Four Concurrent Events Meeting a Criteria MySQL

I have a MySQL query which is used to determine if a piece of equipment, which there are only 3 of, is being used by four concurrent events at once. 我有一个MySQL查询,该查询用于确定只有四个设备同时被四个并发事件使用的设备。 I have a working query, but it seems inefficient and I am curious if there is a better way to do the select. 我有一个有效的查询,但效率似乎很低,我很好奇是否有更好的选择方法。

Table structure (columns not relevant to the query have been removed) The table currently contains around 7-8k rows. 表结构(与查询无关的列已被删除)该表当前包含约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;

Current (working) query: 当前(工作)查询:

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

Query EXPLAIN statement: 查询EXPLAIN语句:

查询说明

Start with changing the inequalities to less than/greater than comparisons. 首先将不等式更改为小于/大于比较。 That simplifies things a lot as well: 这也大大简化了事情:

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

After that you would do good to add an index on CrewStartTime , that should help quite a bit in performance. 之后,您最好在CrewStartTime上添加一个索引,这应该对性能有很大帮助。 Indexes on other columns which you filter by could also be helpful. 筛选依据的其他列上的索引也可能会有所帮助。

You just want to know if there is a conflict, which is 4 users at the same time. 您只想知道是否存在冲突,即同时有4个用户。 For this, you can just look at the event start time and check how many concurrent events there are: 为此,您可以仅查看事件开始时间并检查有多少个并发事件:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM