如何用Go在内存中实现两个CSV文件的类MySQL内连接匹配?
Go实现CSV内连接的高效方案
针对你的场景(小CSV全量内存加载,大CSV流式处理),最佳方案是先把小文件的匹配列存入哈希集合,再逐行扫描大文件做匹配,既避免大文件占满内存,又保证匹配效率。
核心思路
- 处理小CSV(18MB):读取所有行,提取第2列的值,存入
map[string]struct{}(空结构体不占内存,比bool更高效),构建O(1)查找的匹配集合。 - 处理大CSV(3.2GB):逐行读取(不一次性加载到内存),提取第4列,检查是否在匹配集合中,符合条件的行就输出或保存。
代码实现示例
package main import ( "encoding/csv" "fmt" "os" ) func main() { // 1. 加载小CSV的匹配列到哈希集合 smallFile, err := os.Open("small.csv") if err != nil { fmt.Printf("打开小文件失败: %v\n", err) return } defer smallFile.Close() smallReader := csv.NewReader(smallFile) // 如果有表头,先读取跳过(根据实际情况注释或保留) // _, err = smallReader.Read() // if err != nil { // fmt.Printf("读取小文件表头失败: %v\n", err) // return // } matchSet := make(map[string]struct{}) for { record, err := smallReader.Read() if err != nil { break // 读取完毕或出错,退出循环 } // 检查第2列索引是否合法(CSV列从0开始,第2列对应索引1) if len(record) < 2 { fmt.Println("小文件行列数不足,跳过该行") continue } key := record[1] matchSet[key] = struct{}{} } fmt.Printf("已加载小文件匹配列,共%d个唯一值\n", len(matchSet)) // 2. 逐行处理大CSV,匹配输出 largeFile, err := os.Open("large.csv") if err != nil { fmt.Printf("打开大文件失败: %v\n", err) return } defer largeFile.Close() largeReader := csv.NewReader(largeFile) // 如果有表头,先读取跳过(根据实际情况注释或保留) // header, err := largeReader.Read() // if err != nil { // fmt.Printf("读取大文件表头失败: %v\n", err) // return // } // // 如果需要输出表头,先打印 // fmt.Println(header) for { record, err := largeReader.Read() if err != nil { break // 读取完毕或出错,退出循环 } // 检查第4列索引是否合法(CSV列从0开始,第4列对应索引3) if len(record) < 4 { fmt.Println("大文件行列数不足,跳过该行") continue } key := record[3] // 检查是否在匹配集合中 if _, exists := matchSet[key]; exists { // 匹配成功,输出该行(或写入结果文件) fmt.Println(record) // 如果要写入文件,可提前创建文件并使用csv.Writer // writer.Write(record) } } }
关键优化点
- 内存效率:用
map[string]struct{}存储匹配值,比map[string]bool节省约一半内存(空结构体不占用空间)。 - 流式处理:大文件采用逐行读取,内存占用仅为当前行的大小,不会因为3.2GB文件导致内存溢出。
- 错误处理:包含文件打开、行读取、列索引越界等场景的错误提示,避免程序崩溃。
额外注意事项
- 如果CSV包含带引号的字段、多行字段,标准库
encoding/csv会自动处理,无需额外处理。 - 若需要将匹配结果写入新CSV,可提前创建结果文件,使用
csv.Writer替代fmt.Println,保证输出格式正确。 - 若小文件的第2列有重复值,存入map时会自动去重,不影响匹配结果(内连接只需要存在性检查)。
内容的提问来源于stack exchange,提问作者luam
相关产品推荐
相关产品推荐

