MySQL 从 left & Right Join 的结果插入导致内存问题
MySQL Insert from results of left & Right Join results in memory issue
我在 运行 2 个大 table 上的插入查询时遇到问题。一个table是6700万,一个是10万。我正在尝试在 2 table 上进行 LEFT 和 RIGHT Join,并将结果放入另一个 table。该查询在 1M 条目下的较小 tables 上运行完美。但是当进入更高的条目时,它会爆炸。我收到此错误:
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.
错误消息通常是由于磁盘不足 space,但由于 52gigs 应该足够了(并且我假设您的文件系统可以处理 >2gb 的文件)它可能有所不同。
以下两件事应该可以限制所需的临时space:
您应该为 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)
由于 UNION 有一个内置的 distinct
(虽然我不确定你是否知道),你可能想使用 select distinct A._Doc_ID ...
,但如果你真的不需要它,不要!
我在 运行 2 个大 table 上的插入查询时遇到问题。一个table是6700万,一个是10万。我正在尝试在 2 table 上进行 LEFT 和 RIGHT Join,并将结果放入另一个 table。该查询在 1M 条目下的较小 tables 上运行完美。但是当进入更高的条目时,它会爆炸。我收到此错误:
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.
错误消息通常是由于磁盘不足 space,但由于 52gigs 应该足够了(并且我假设您的文件系统可以处理 >2gb 的文件)它可能有所不同。
以下两件事应该可以限制所需的临时space:
您应该为 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)
由于 UNION 有一个内置的 distinct
(虽然我不确定你是否知道),你可能想使用 select distinct A._Doc_ID ...
,但如果你真的不需要它,不要!