2016-04-25 28 views
0

我遇到問題在2個大型表上運行插入查詢。一桌是六千七百萬,另一桌是十萬。我正在嘗試在2個表格上做一個左和右加入,並將結果放到另一個表格中。查詢在1M條目下的較小表上運行完美。但是當到達更高的條目時,它會爆炸。我得到這個錯誤:MySQL從左側和右側的結果插入加入結果在內存問題

Incorrect key file for table 'C:\Windows\TEMP\#sql3838_2_6.MYI'; try to repair it 

在線閱讀解決方案後,他們說增加mysql使用的內存,它是索引的關鍵。我試過這個,我仍然遇到同樣的問題。我不確定在這一點上,如果它是一個錯誤的配置爲MySQL或條形碼查詢。

所以我真的在尋找優化我的查詢的解決方案,以便更有效地利用內存或更改my.config來處理查詢。或將查詢分割成2個不同的插入符號?會有幫助嗎?

MySQL查詢

INSERT INTO schema.orphan_results (_Doc_ID, Orphan_Entries, Entries_Table, Orphan_File) 
    SELECT C.A__Doc_ID, C.A_File, C.A_Table, C.B_File 
    FROM(SELECT A._Doc_ID AS A__Doc_ID, A.File AS A_File, A.Table AS A_Table, B.File AS B_File 
    FROM schema.Temp_Entries A 
    LEFT JOIN schema.temp_dir_scan B ON A.File = B.File 
    UNION SELECT A._Doc_ID as A__Doc_ID, A.File AS A_File, A.Table AS A_Table, B.File AS B_File 
    FROM schema.Temp_Entries A 
    RIGHT JOIN schema.temp_dir_scan B ON A.File = B.File) C 
WHERE C.A_File IS NULL OR C.B_File IS NULL 

這裏是my.config用於MySQL的

default-storage-engine=INNODB 
max_connections=800 
query_cache_size=186M 
table_cache=1520 
tmp_table_size=900M 
thread_cache_size=38 
myisam_max_sort_file_size=100G 
myisam_sort_buffer_size=268M 
key_buffer_size=1160M 
read_buffer_size=128K 
read_rnd_buffer_size=512K 
sort_buffer_size=512K 
innodb_additional_mem_pool_size=96M 
innodb_buffer_pool_size=563M 

我的系統

16 Gigs of Mem 
52 Gigs of Free disk space. 

回答

1

錯誤消息通常是從低磁盤空間的結果,但由於52gigs應足夠了(我假設你的文件系統可以處理> 2GB的文件),它可能會有所不同。

以下兩件事情應該努力限制所需的臨時空間:

  • 您應該創建temp_dir_scan.File和Temp_Entries.File的索引。

  • 您應該使用「union all」而不是「union」(或者,如您所建議的那樣,拆分查詢)。

而且你可以重寫你的代碼(當然,創建索引,請):

INSERT INTO schema.orphan_results (_Doc_ID, Orphan_Entries, Entries_Table, Orphan_File) 
SELECT A._Doc_ID, A.File, A.Table, null 
FROM schema.Temp_Entries A 
where not exists (select 1 from schema.temp_dir_scan B where A.File = B.File) 
-- or a.file is null -- you might need that if a.file can be null 

INSERT INTO schema.orphan_results (_Doc_ID, Orphan_Entries, Entries_Table, Orphan_File) 
select null, null, null, B.File 
from schema.temp_dir_scan B 
where not exists (select 1 from schema.Temp_Entries A where A.File = B.File) 

自聯盟有一個內置的distinct(雖然我不知道你是否意識到這一點),您可能需要使用select distinct A._Doc_ID ...,但如果您不需要它,請不要!