2012-09-27 57 views
0

所以這裏是我的問題,我寫了一個存儲過程來完成以下任務。在表events中,對於不再存在的場所可能存在事件。並非所有事件都與場地相關聯,但是場館ID字段中有整數值,否則它是NULL(或可能爲零,但這是佔的)。定期地,場地會從我們的系統中刪除,當發生這種情況時,無法在該確切時間刪除與該場地相關的所有事件。相反,稍後會定期運行一個任務,刪除場地標識不再引用場館表中現有記錄的每個事件。我寫了一個存儲過程,它似乎工作。MySQL - 優化孤兒記錄疏導

這是存儲過程:

DROP PROCEDURE IF EXISTS delete_synced_events_orphans; 
DELIMITER $$ 
CREATE PROCEDURE delete_synced_events_orphans() 
BEGIN 

    DECLARE event_count int(11) DEFAULT 0; 
    DECLARE active_event_id int(11) DEFAULT 0; 
    DECLARE active_venue_id int(11) DEFAULT 0; 
    DECLARE event_to_delete_id int(11) DEFAULT NULL; 

    CREATE TEMPORARY TABLE IF NOT EXISTS possible_events_to_delete (
     event_id int(11) NOT NULL, 
     venue_id_temp int(11) NOT NULL 
    ) engine = memory; 

    # create an "array" which is a table that holds the events that might need deleting 
    INSERT INTO possible_events_to_delete (event_id, venue_id_temp) SELECT `events`.`id`, `events`.`venue_id` FROM `events` WHERE `events`.`venue_id` IS NOT NULL AND `events`.`venue_id` <> 0; 
    SELECT COUNT(*) INTO `event_count` FROM `possible_events_to_delete` WHERE 1; 

    detector_loop: WHILE `event_count` > 0 DO 
     SELECT event_id INTO active_event_id FROM possible_events_to_delete WHERE 1 LIMIT 1; 
     SELECT venue_id_temp INTO active_venue_id FROM possible_events_to_delete WHERE 1 LIMIT 1; 

     # this figures out if there are events that need to be deleted 
     SELECT `events`.`id` INTO event_to_delete_id FROM `events`, `venues` WHERE `events`.`venue_id` <> `venues`.`id` AND `events`.`id` = active_event_id AND `events`.`venue_id` = active_venue_id; 

     #if no record meets that query, the active event is safe to delete 
     IF (event_to_delete_id <> 0 AND event_to_delete_id IS NOT NULL) THEN 
      DELETE FROM `events` WHERE `events`.`id` = event_to_delete_id; 
      #INSERT INTO test_table (event_id_test, venue_id_temp_test) SELECT `events`.`id`, `events`.`venue_id` FROM `events` WHERE `events`.`id` = event_to_delete_id; 
     END IF; 

     DELETE FROM possible_events_to_delete WHERE `event_id` = active_event_id AND `venue_id_temp` = active_venue_id; 
     SET `event_count` = `event_count` - 1; 

    END WHILE; 

END $$ 
DELIMITER ; 

這裏是有問題的兩個表的表結構:

CREATE TABLE IF NOT EXISTS events (
    id int(11) NOT NULL, 
    event_time timestamp NOT NULL, 
    venue_id_temp int(11) NOT NULL 
); 

CREATE TABLE IF NOT EXISTS venues (
    event_id int(11) NOT NULL, 
    venue_id_temp int(11) NOT NULL 
); 

作品作爲編寫的存儲過程,但我想知道如何可以讓它運行得更好。看起來它爲了達到目標要做很多額外的處理。是否有更好的方法可以查詢手邊的數據,還有其他更有用的命令和關鍵詞我可以使用,我只是不知道,這可以讓我更好地完成這項任務(更少的行少計算)。我仍然在學習如何使用存儲過程,因此我正在使用它們以儘可能務實的方式完成任務,我想了解如何使用此特定查詢來更好地利用MySQL中的全部功能。謝謝你們。

+0

此問題更適合[DBA](http://dba.stackexchange.com)。投票結束並遷移到那裏。 –

+0

我在那裏沒有賬戶,這將如何影響我獲得答案的能力? – usumoio

+0

與新用戶在此發佈問題時的方式相同 - 完全沒有。這裏的新用戶可以獲得與長期用戶所做的相同的工作(有時甚至更多):-)您甚至可以合併您的帳戶信息,以便此處的帳戶與其中的帳戶連接,並顯示在用戶個人資料中。只需使用您在此使用的相同憑據登錄即可。 –

回答

2

Everithing簡單得多:

DROP PROCEDURE IF EXISTS delete_synced_events_orphans; 
DELIMITER $$ 
CREATE PROCEDURE delete_synced_events_orphans() 
BEGIN 

    DELETE 
    FROM `events` 
    WHERE `venue_id` IS NOT NULL AND `venue_id` <> 0 
     AND `venue_id` NOT IN (SELECT `id` FROM `venues`) 
    ; 

END $$ 
DELIMITER ; 

就是這樣。 :)

你認爲勢在必行,試圖說MySQL 如何來完成你的任務。但SQL是一種說明性語言,專門用於說什麼要做。

+0

很好的答案。是的,我完全忘記了一個子查詢可以解決這個問題。這是我今天的教訓。謝謝。 – usumoio