2015-04-18 152 views
0

我有這個數據庫「stats19」與從英國事故的所有數據從2005年到2013年加入三個表

現在我必須創建一個DataWarehouse(星型)。

這是我想要在一個表中加入表格,省去這並不重要

stats19.casualty(202萬行),其他一些變量

AccidentIndex varchar(13) 
VehicleReference int(11) 
CasualtyReference_id int(11) 
CasualtyClass int(11) 
CasualtySeverity varchar(7) 
CasualtySex varchar(28) 
CasualtyAgeBand varchar(7) 
... 

stats19.typeperson(202萬行)

CasualtyType_id int(11) 
fk_AccidentIndex varchar(13) 
fk_VehicleReference int(11) 
fk_CasualtyReference_id int(11) 
... 

stats19.accident(1494275行)

AccidentIndex varchar(13) 
AccidentDate date 
AccidentTime time 
... 

決賽桌必須有這個變量

dw.casualtytemporary(應該有202.000行)

AccidentIndex VARCHAR(255), 
VehicleReference INT, 
CasualtyReference INT, 
CasualtyClass INT, 
CasualtyType INT, 
AccidentDate DATE, 
AccidentTime TIME, 
CasualtySex VARCHAR(255), 
CasualtyAgeBand VARCHAR(255) 

我一直在努力執行此項插入

INSERT INTO CasualtyTemp 
    (SELECT c.AccidentIndex,c.VehicleReference,c.CasualtyReference_id, 
    c.CasualtyClass,t.CasualtyType_id,a.AccidentDate,a.AccidentTime, 
    c.CasualtySex, c.CasualtyAgeBand 
    FROM (stats19.Casualty as c 
     INNER JOIN stats19.typeperson as t 
      ON c.CasualtyReference_id = t.cf_CasualtyReference_id 
     INNER JOIN stats19.accident as a 
      ON a.AccidentIndex = c.AccidentIndex)) 
); 

問題是當MYSQL CommandLine或Workbench都無法通過獲取錯誤(斷開連接)或插入太多時間來插入。

決賽桌dw.casualtytemporary應該有2,020,000行,因爲這是原始表所具有的。

+0

那麼,你的問題是如何使查詢更快?或者如何增加客戶端的超時時間,以便在完成之前不斷開連接? – IMSoP

+1

你檢查過你選擇查詢嗎?如果你確信數據,那麼使用'LIMIT 10000'。然後繼續「LIMIT 10000,10000」等等。這只是超時問題 – Alex

+0

我的問題是我做錯了嗎?或者,我是否正確地做,並應該嘗試提高超時或優化? select可以使用限制1000或限制1000,1000(偏移量)。問題出現在連接生成2,020,000行時,以及當做一個2,000,000的偏移量時,它將多達3,000,000行插入到命令表中。 – Napsteir

回答

0

由於您正在進行全表連接而沒有'where',所以我認爲搜索複雜度爲n1*log(n2)*log(n3)其中ni是每個表的行號(如果您在內部連接字段上使用索引)。

我覺得你的SQL語句是正確的,而且mysql優化器會進一步優化SQL,所以我覺得沒必要在SQL上做。但我認爲你可以調整MYSQL部分,我列出一些可能很重要的東西。

  1. 兩個存儲引擎應該是相同的,這可以確保表在引擎級加入,否則他們會加入服務器級別慢。

  2. 如果您使用Innodb,也許您可​​以調整與Inoodb相關的重要參數,如'Innodb_buffer_pool_size',因爲足夠的空間將使innodb在內存中執行哈希索引。

  3. 如果您使用Myisam引擎,也許您可​​以調整myisam索引大小以確保索引可以加載到內存中。此外,由於您將生成派生表,因此tmp_table_size將會很重要,如果tmp_table_size很小,則myisam表將用作tmp表。另外請注意,由於雙重寫入日誌機制,innodb寫入速度非常慢,並且當您使用insert ... select時,這會更加糟糕,因爲併發插入是禁用的。

  4. 其他因素,如您的字段中是否存在NULL,如果該字段嚴重重複,並且如果是這樣,則可以使用比VARCHAR更快的ENUM。另外注意,CHAR比VARCHAR快大約20%,以防磁盤空間不受關注,並且字符串很短也許可以嘗試。

如果所有的上述無法解決您的問題,或者你沒有一個大機器,因爲你正在做的只有三個表,你可以在編程的C/C++的一些代碼,這是最有效的辦法。