2011-01-05 62 views
1

好吧我有一個臨時的MySQL表,有135,000行,從這個臨時表我想填充其他幾個表。使用臨時表中的大量數據填充表 - MySQL

首先,這是臨時表

CREATE TEMPORARY TABLE TVTEMPTABLE ( PROGTITLE TEXT, SUBTITLE TEXT, EPISODE TEXT, YR YEAR, DIRECTOR TEXT, PERFORMERS TEXT, PREMIERE BOOL, FILM BOOL, RPEAT BOOL, SUBTITLES BOOL, WIDESCREEN BOOL, NEWSERIES BOOL, DEAFSIGNED BOOL, BNW BOOL, STARRATING TINYINT, CERTIFICATE VARCHAR(5), GENRE VARCHAR(50), DESCRIPTION TEXT, CHOICE BOOL, PROGDATE DATE, STARTIME TIME, ENDTIME TIME, DURATION INT, CHANNELID INT NOT NULL)

的結構,這是我計劃從這個填充一個表的結構。

CREATE TABLE PROGRAMME ( PROGRAMMEID INT NOT NULL AUTO_INCREMENT, GENREID INT NOT NULL, PROGTITLE VARCHAR(50), YR YEAR, DIRECTOR VARCHAR(50), PERFORMERS TEXT, FILM BOOL, WIDESCREEN BOOL, BNW BOOL, CERTIFICATE VARCHAR(5), DESCRIPTION TEXT, PRIMARY KEY(PROGRAMMEID), INDEX (GENREID), FOREIGN KEY (GENREID) REFERENCES GENRE(GENREID) ) ENGINE=INNODB;

這是我做我的插入到節目表

INSERT INTO PROGRAMME ( GENREID, PROGTITLE, YR, DIRECTOR, PERFORMERS, FILM, WIDESCREEN, BNW, CERTIFICATE, DESCRIPTION) SELECT G.GENREID, T.PROGTITLE, T.YR, T.DIRECTOR, T.PERFORMERS, T.FILM, T.WIDESCREEN, T.BNW, T.CERTIFICATE, T.DESCRIPTION FROM TVTEMPTABLE T,GENRE G WHERE G.GENRENAME = T.GENRE AND NOT EXISTS ( SELECT * FROM PROGRAMME P WHERE P.PROGTITLE = T.PROGTITLE)

但是,這是採取了非常非常長的時間做,我應該如何處理呢?

感謝, 保羅

好,謝謝仍然有這個我想左側加入例如幾個問題,大家好,我卻發現,如果我插入到表是空的開始與雖然,然後它插入重複。下面是一個簡單的例子

CREATE TEMPORARY TABLE TEMP(
    GENRENAME TEXT); 

CREATE TABLE GENRE(
    GENREID INT NOT NULL AUTO_INCREMENT, 
    GENRENAME TEXT, PRIMARY KEY(GENREID) 
) ENGINE=INNODB; 

INSERT INTO TEMP(
    GENRENAME) 
VALUES("news"); 

INSERT INTO TEMP(
    GENRENAME) 
VALUES("news"); 

這將「新聞」類型插入臨時表兩次。現在,如果我運行這個SQL命令

INSERT INTO GENRE(
    GENRENAME) 
SELECT 
    T.GENRENAME 
FROM 
    TEMP T 
LEFT JOIN 
    GENRE G ON G.GENRENAME=T.GENRENAME 
WHERE 
    G.GENRENAME IS NULL; 

它將「新聞」兩次插入流派表中,這是錯誤的。如果我再次運行相同的命令,它正確不會插入任何新行。

回答

1

如何:

INSERT INTO PROGRAMME (GENREID, PROGTITLE, YR, DIRECTOR, PERFORMERS, FILM, WIDESCREEN, BNW, CERTIFICATE, DESCRIPTION) 
SELECT G.GENREID, T.PROGTITLE, T.YR, T.DIRECTOR, T.PERFORMERS, T.FILM, T.WIDESCREEN, T.BNW, T.CERTIFICATE, T.DESCRIPTION 
FROM TVTEMPTABLE T,GENRE G 
WHERE G.GENRENAME = T.GENRE 
AND T.PROGTITLE NOT IN (SELECT DISTINCT P.PROGTITLE FROM PROGRAMME P) 

我相信你NOT EXISTS必須執行的每個所選行。用一個靜態子查詢替換它,並檢查它上面的NOT IN

+0

準確。相關的子查詢在這裏是錯誤的。你可以(我會反正)也把它改寫成左連接。 – Mchl 2011-01-05 14:37:28

+0

我也試過這個,但它似乎也跑了很長時間,我是否期待太多? – PDStat 2011-01-05 15:29:10

0

我會先看看嵌入式select語句在插入中的性能,特別是NOT EXISTS子句。確保你有很好的指標。

另一個想法是將其分解爲更小的塊,因此不存在回滾空間問題。因此,看看你是否一次只能插入1000或10,000行,然後提交,然後再次運行。等

0

將您的插入語句包裝在事務中。

start transaction; 

insert into programme (...) select ... from tvtemptable ... 

commit; 

,如果它仍然是緩慢的,然後張貼解釋你的INSERT語句的選擇部分的計劃,所以我們可以看到這是怎麼回事:P

0

創建P.PROGTITLET.PROGTITLE的索引。

1

你正在爲每一行做一個(可能很大)的子選擇。

我建議做一個LEFT JOIN對程序,然後只將行插入其中,連接結果爲NULL,如下:

INSERT INTO PROGRAMME (
    GENREID, PROGTITLE, YR, DIRECTOR, 
    PERFORMERS, FILM, WIDESCREEN, BNW, 
    CERTIFICATE, DESCRIPTION) 
SELECT 
    G.GENREID, T.PROGTITLE, T.YR, T.DIRECTOR, 
    T.PERFORMERS, T.FILM, T.WIDESCREEN, T.BNW, 
    T.CERTIFICATE, T.DESCRIPTION 
FROM 
    TVTEMPTABLE T 
    INNER JOIN GENRE G ON G.GENRENAME=T.GENRE 
    LEFT JOIN PROGRAMME P ON P.PROGTITLE=T.PROGTITLE 
WHERE 
    P.PROGTITLE IS NULL 

順便說一句:你有沒有考慮(一)漂亮,打印您的代碼更具可讀性並且(b)不使用全大寫字段名稱?

+0

感謝所有我正在嘗試一些這些建議,數據庫/ SQL的東西對我來說都是非常新的。出於興趣,我應該期待什麼樣的時間?我已經使用了加入示例,並且在五分鐘後仍然運行。 – PDStat 2011-01-05 15:17:57

0

這是使用左/內連接和distinct關鍵字的組合。