데이터베이스 쿼리 최적화 - 루프에서

2493 단어 databasesqljavascript
객체 배열이 있다고 상상해보십시오.
그러나 배열에서 일부 개체는 여러 데이터를 가질 수 있습니다.
예를 들어

const transactions = [
    {
        "player_id": 1,
        "transaction_id": "xxx",
        "amount": "100",
    },
    {
        "player_id": 2,
        "transaction_id": "xxx",
        "amount": "100",
    },
    {
        "player_id": 3,
        "transaction_id": "xxx",
        "amount": "100",
    },
    {
        "player_id": 1,
        "transaction_id": "xxx",
        "amount": "100",
    }
]


그런 다음 데이터베이스에서 플레이어 정보를 가져와야 합니다.

for (let i = 0; i<= transactions.length; i++) {
    const player = PlayerModel.findByPk(transactions[i].player_id)
// equals to SELECT * FROM users WHERE player_id = 1

    const saveTransaction = TransactionModel.create({
        id: transactions[i].transaction_id,
        player_id: transactions[i].player_id,
        player_before_balance: player.balance,
        player_after_balance: player.balance - transactions[i].amount
    });
}


각 루프에서 데이터베이스 tcp 연결을 생성하게 되며 이는 성능에 좋지 않습니다(데이터베이스가 다른 호스트에 있는 경우 더 나쁨).
전화를 걸 때마다 흐름이 다음과 같이 진행되기 때문입니다.

open the db connection -> execute the query -> close the connection


따라서 그런 방식을 사용하는 대신 player_id로 트랜잭션 배열을 구분할 수 있습니다.

const distinctPlayers = [...new Set(transactions.map(transaction => transaction.player_id))] 
// result [1,2,3]


where in 절을 사용하여 데이터베이스 쿼리를 한 번만 호출하고 변수에 저장합니다.

const players = PlayerModel.findAll({
        where: {
            id: distinctPlayers
        }
    })
// equals to SELECT * FROM users WHERE player_id IN (1,2,3)

for (let i = 0; i<= transactions.length; i++) {
    const player = players.find(player => player.player_id === players.player_id);

    const saveTransaction = TransactionModel.create({
        id: transactions[i].transaction_id,
        player_id: transactions[i].player_id,
        player_before_balance: player.balance,
        player_after_balance: player.balance - transactions[i].amount
    });
}


하지만 배열이 너무 크면 단점이 있습니다.
메모리가 너무 많이 걸립니다

더 나은 접근 방식이 있으면 알려주세요.

좋은 웹페이지 즐겨찾기