Оптимизация конкатенации строк F # - PullRequest
4 голосов
/ 22 июня 2009

Я создаю MySql-запрос, в который пакетно вставляется 4096 записей одновременно. Фактическая вставка довольно быстрая, но узкое место создает запрос. Любые советы по оптимизации этого? Генерация строки в настоящее время занимает примерно в 18 раз больше времени, чем запрос.

                    let builder = StringBuilder(524288)
                    Printf.bprintf builder
                        "
                         INSERT INTO %s
                             (`ID`,
                              `Tag`,
                              `Port`,
                              `Excess`,
                              `Return`,
                              `StartDate`,
                              `EndDate`
                              ) 
                          values "
                        x.evaluationstable

                    evaluations
                    |> Seq.iter(fun (e) ->
                        Printf.bprintf builder 
                            " (%d, '%s', '%s', %A, %A, %A, %A), "
                            e.ID
                            e.Tag
                            e.Port
                            e.Excess
                            e.Return
                            (e.StartDate.ToString(x.datetimeformat))
                            (e.EndDate.ToString(x.datetimeformat))
                    )

Ответы [ 2 ]

10 голосов
/ 22 июня 2009

Попробуйте использовать StringBuilder.AppendFormat вместо Printf.bprintf. Когда я сделал это изменение в своем примере вашего вопроса, я увидел огромное увеличение производительности (~ 80x).

evaluations
|> Seq.iter (fun (e) ->
    builder.AppendFormat(
        " ({0}, '{1}', '{2}', {3}, {4}, {5}, {6}), ",
        e.ID,
        e.Tag,
        e.Port,
        e.Excess,
        e.Return,
        (e.StartDate.ToString("MM/dd/yyyy")),
        (e.EndDate.ToString("MM/dd/yyyy"))
    ) |> ignore
)
3 голосов
/ 22 июня 2009

Я бы постарался избежать встраивания данных непосредственно в SQL для начала. Используйте последовательность подготовленных операторов с параметрами и установите для этих параметров значения (без их форматирования). Это безопаснее и, вероятно, будет намного эффективнее.

Возможно ли, что вы все еще можете сделать это в пакете, а не в нескольких отдельных вызовах только в рамках одной транзакции, я не уверен.

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