Как сбросить огромные данные CSV (4 ГБ) в MySQL с помощью Golang? - PullRequest
0 голосов
/ 04 мая 2018

Если бы кто-то пробовал это до использования Golang , пожалуйста, получите идею с кодом, который был бы очень признателен.

Я написал несколько строк, которые медленно

// Это для чтения файла CSV

func usersFileLoader(filename string, channel chan User) {
    defer close(channel)
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer file.Close()
    var user User
    reader := csv.NewReader(file)
    for {
        err := Unmarshal(reader, &user)
        if err == io.EOF {
            break
        }
        if err != nil {
            panic(err)
        }
        channel <- user
    }
}

// Это вставить CSV-файл

func saveUser(channel <-chan User, db *sql.DB) {
    stmt, err := db.Prepare(`
        INSERT INTO Users( id, name, address) values ( ?, ?, ?)`)
    if err != nil {
        log.Fatal(err)
    }

    for usr := range channel {
        _, err := stmt.Exec(
            usr.ID,
            usr.Name,
            usr.Address,
        )
        if err != nil {
            log.Fatal(err)
        }
    }
}

// здесь структура пользователя

type User struct {
    ID      int `csv:"id"`
    Name    int `csv:"name"`
    Address int `csv:"address"`
}

// вот мой главный функционал

func main() {
    db := DBconnect(ConnectionString(dbConfig()))
    channel := make(chan User)
    go usersFileLoader("../user.csv", channel)
    saveUser(channel, db)
    defer db.Close()
}

// Этот код работает, но медленно для меня. Поделитесь своими мыслями и идеями

1 Ответ

0 голосов
/ 04 мая 2018

Я бы не пытался использовать встроенные стандартные функции Go для загрузки очень большого CSV-файла в MySQL (если, конечно, вы просто не пытаетесь узнать, как они работают).

Для лучшей производительности я бы просто использовал встроенную функциональность MySQL LOAD DATA INFILE.

Например:

result, err := db.Exec("LOAD DATA INFILE ?", filename)
if err != nil {
    log.Fatal(err)
}
log.Printf("%d rows inserted\n", result.RowsAffected())

Если вы ранее не использовали LOAD DATA INFILE, внимательно ознакомьтесь с документацией, касающейся LOCAL. В зависимости от конфигурации вашего сервера и разрешений вам может потребоваться вместо этого использовать LOAD DATA LOCAL INFILE. (Если вы намереваетесь использовать, например, контейнеры Docker, вам абсолютно необходимо использовать LOCAL.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...