2015-06-24 47 views
2

我有一個MySQL數據庫,每天有2百萬個數據(行/天)在一個表中調用流。我編寫了一個事務來讀取和彙總表中的數據,以寫入臨時表(這裏稱爲top_tcp_ports和top_udp_ports)。當我在Mysql控制檯上執行事務查詢時,通常需要30s或更少的時間來處理數據並將數據插入這兩個表(top_tcp_ports & top_udp_ports)。但相反,當MySQL事件調度程序運行此事務時,需要7分鐘來處理整個事務。該活動每1小時運行一次。這裏的性能和時機正在考慮之中。 有沒有辦法提高mysql事件執行的性能?

DELIMITER | 
    CREATE EVENT IF NOT EXISTS top_tcp_udp_ports_hourly 
    ON SCHEDULE EVERY 1 HOUR starts CURRENT_TIMESTAMP 
    DO 
    BEGIN 
     INSERT INTO messages(message,created_at) VALUES('Start Event Execution Log ....',NOW()); 

     CREATE TABLE IF NOT EXISTS top_tcp_ports 
     (
     time_stamp datetime, 
     tcp_port mediumint(8) signed, 
     octetsTotal bigint(20) unsigned, 
     packetTotal bigint(20) unsigned 
     )ENGINE=MyISAM; 

     CREATE TABLE IF NOT EXISTS top_udp_ports 
     (
     time_stamp datetime, 
     udp_port mediumint(8) signed, 
     octetsTotal bigint(20) unsigned, 
     packetTotal bigint(20) unsigned 
     )ENGINE=MyISAM; 

     start transaction; 

     SET @v1 := (select max(saved_max_id) from saved_id); 

     INSERT INTO top_tcp_ports (time_stamp, tcp_port, octetsTotal, packetTotal) 
     SELECT (timestamp(res2.date, maketime(res2.hour,00,00))), res2.tcp_port, res2.octetsTotal, res2.packetTotal from 
     (SELECT dt as date, hr as hour, tcp_port, sum(byt) as octetsTotal, sum(pkt) as packetTotal from 
      (
       (SELECT -1 as tcp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 6 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by dt, hr) 
      union 
       (SELECT srcport as tcp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 6 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by srcport, dt, hr having byt > 1048576) 
      union 
       (SELECT dstport as tcp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 6 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by dstport, dt, hr having byt > 1048576) 
      ) as res 
     group by tcp_port, dt, hr) as res2; 
     INSERT INTO messages(message,created_at) VALUES('Mid_1 Event Execution Log ....',NOW()); 

     INSERT INTO top_udp_ports (time_stamp, udp_port, octetsTotal, packetTotal) 
     SELECT (timestamp(res3.date, maketime(res3.hour,00,00))), res3.udp_port, res3.octetsTotal, res3.packetTotal from 
     (SELECT dt as date, hr as hour, udp_port, sum(byt) as octetsTotal, sum(pkt) as packetTotal from 
      (
       (SELECT -1 as udp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 17 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by dt, hr) 
      union 
       (SELECT srcport as udp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 17 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by srcport,dt,hr having byt > 1048576) 
      union 
       (SELECT dstport as udp_port, sum(packetTotalCount+reversePacketTotalCount) as pkt, sum(octetTotalCount+reverseOctetTotalCount) as byt, date(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as dt, hour(CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')) as hr FROM flows where protocol = 17 and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00') and (SELECT @v1) < id group by dstport,dt,hr having byt > 1048576) 
      ) as res 
     group by udp_port, dt, hr) as res3; 
     INSERT INTO messages(message,created_at) VALUES('Mid_2 Event Execution Log ....',NOW()); 

     SET SQL_SAFE_UPDATES = 0; 
     update saved_id set saved_max_id=IFNULL((select max(id) from flows where id> (SELECT @v1) and CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM')<DATE_FORMAT(now(),'%Y-%m-%d %H:00:00')),(SELECT @v1)) where row_id=1; 

     commit; 

     INSERT INTO messages(message,created_at) VALUES('End Event Execution Log ....',NOW()); 

    END | 
    DELIMITER ; 

此處的消息表用於跟蹤事件級別的過程。

問題是如何提高MySQL事件的性能 調度或提升它?

有沒有身體面對這個問題?

+0

爲什麼你認爲'EVENT'是瓶頸?就個人而言,我會將任何瓶頸歸因於臨時表! – bishop

+0

@bishop因爲我一步一步地測試了這個事務,Message表記錄了這個事務的執行級別的步驟。此表中記錄的時間顯示事件調度程序的執行時間比在CONSOL中運行的時間長。另外{show processlist}和{innotop命令}顯示每個事件查詢的執行時間。 – omid

+0

@bishop謝謝你,你正確的瓶頸不是事件調度器。 – omid

回答

1

我懷疑@v1是問題所在。請在裏面加上EXPLAIN SELECT ...這個存儲過程看看它是怎麼工作的。然後在之外同樣做SP。我猜EXPLAINs會有所不同,並有希望提供信息。

這些會加速嗎?

CONVERT_TZ(flowEndMilliseconds,'UTC','SYSTEM') < 
    DATE_FORMAT(now(), '%Y-%m-%d %H:00:00') 
--> 
flowEndMilliseconds < CONVERT_TZ(NOW(), 'SYSTEM', 'UTC') 

AND (SELECT @v1) < id 

另外添加

INDEX(protocol, flowEndMilliseconds) 
--> 
AND @v1 < id 
+0

謝謝,我修改了我的查詢,並將數據庫引擎更改爲InnoDB,並使用了分區。我在執行事件中獲得驚豔的表現。 – omid

+0

我喜歡聽到「驚豔的表演」。 :) –

+0

它需要大約10秒鐘:)我將再次優化查詢以便記錄到4秒。 – omid

相關問題