rust tiberius bulk insert

wangki·2025년 11월 12일

Rust

목록 보기
53/56

개요

global_db_table을 생성하여 Unique 한 name column을 만들어서 이름 중복이 되지 않는 로직을 작성해야 하는데, 테스트를 위해 많은 데이터를 넣어줘야 했다. bulk insert를 사용하면 빠르게 넣을 수 있다고 했다. 해당 내용을 간단히 정리해 보겠다.

내용

local에 docker로 mssql 서버를 실행했다.

테이블은 위처럼 아주 간단히 만들었고, name에 unique 속성을 주었다.

use tiberius::{Client, ColumnData, Config, IntoRow, Row, ToSql};
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;


#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let con_string = *****ado connection string******;

    let config = Config::from_ado_string(con_string)?;

    let tcp = TcpStream::connect(config.get_addr()).await?;

    // Nagle 알고리즘 비활성화 (성능 최적화)
    tcp.set_nodelay(true)?;

    let mut client = Client::connect(config, tcp.compat_write()).await?;
    client.simple_query("USE GlobalDB").await?.into_results().await?;

    let mut rows: Vec<Row> = Vec::with_capacity(1000);

    let mut req = client.bulk_insert("TB_Global").await?;
    
    for i in 1..=1000 {
        // IDENTITY 컬럼에는 NONE, name 컬럼에는 nchar(20)값을 보낸다. 
        let name = format!("GLOBAL_{}", i);
        let row = (name).into_row();

        req.send(row).await?;
    }

    let res = req.finalize().await?;

    println!("good!");

    Ok(())
}

bulk_insert로 객체를 생성 후, lazy 하게 데이터를 담아준 뒤, finalize를 호출 시 대량으로 넣어지는 구조인 것 같다.

은근 오래 걸려서 name 중복 검사는 다음에 해야겠다...
참조 사이트는 역시나 rust docs다.

https://docs.rs/tiberius/latest/tiberius/struct.Client.html#method.bulk_insert

추가로 cargo.toml

[dependencies]
tiberius = "0.12.3"
tokio = { version = "1.48.0", features = ["full"] }
tokio-util = { version = "0.7.17", features = ["compat"] }

features를 위와 같이 추가해 줘야 한다.

결론

test 데이터를 만들 때, bulk_insert로 하면 좋을 것 같다.
지금은 1000개의 데이터만 넣었지만, 테스트할 때는 100만 개 정도 넣어서 테스트해 볼 예정이다.

0개의 댓글