2013-06-24 48 views
1

我有一個MySQL查詢,用於確定是否有一個設備(只有3個設備)被同時使用四個併發事件。我有一個工作查詢,但它似乎效率低下,我很好奇,如果有更好的方式來做選擇。選擇符合條件的四個併發事件MySQL

表結構(與查詢無關的列已被刪除)該表當前包含大約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語句:

Query EXPLAIN

+0

只要有一個快速瀏覽一下你的'CrewStartTime BETWEEN ...'的事情,是不是隻是一個平等喜歡這個?至少有一些是無用的,你正在檢查T4與T4之間的T3與T3之間的T2,在那種情況下檢查T4與T4之間的關係是沒有用的。 – Wolph

回答

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 
+0

它需要在子查詢中的WHERE子句來指定我正在尋找的特定音板,但除此之外它效果很好,謝謝! –

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添加索引,應該幫助不少性能。您過濾的其他列上的索引也可能有所幫助。