[MySql] Can't create more than max_prepared_stmt_count

hs·2023년 4월 14일
post-thumbnail

문제 코드들

  • 벌크 인설트시 입력되는 데이터 개수가 다를 경우 그 경우의 수만큼 쿼리가 prepared 되는 것으로 보임
// example 1
async function bulkInsert(conn, params) {
  let paramArr = [];
  params.forEach((el) => {
    const { val1, val2, val3 } = el;
    paramArr = [...paramArr, val1, val2, val3];
  });

  let qry = "INSERT INTO table_name (col1, col2, col3)";
  for (let i = 0; i < params.length; i++) {
    qry += i === 0 ? " VALUES (?, ?, ?) " : ", (?, ?, ?) ";
  }

  return new Promise(async (resolve, reject) => {
    try {
      await conn.execute(qry, paramArr);
      resolve(true);
    } catch (err) {
      reject(err);
    }
  });
}
  • 직접 쿼리를 문자열로 만드는 방법도 prepared_stmt_count 수를 증가 시킴
  • WHRER IN 조건 개수의 경우에 따라 n개 늘어남
// example 2
{
  ...
  let qry = " UPDATE table_name SET ";
  qry += `  updated_at = '${time}' `;
  qry += ` WHERE no IN(${noArr})`;
  ...
}


prepared statement 직접 해제

코드 예제

  connection.execute('select 1 + ? + ? as result', [5, 6], (err, rows) => {
    // rows: [ { result: 12 } ]
    // internally 'select 1 + ? + ? as result' is prepared first.
    //On subsequent calls cached statement is re-used
  });

  // close cached statement for 'select 1 + ? + ? as result'. noop if not in cache
  connection.unprepare('select 1 + ? + ? as result');

[참조]

Prepared-Statements



createPool 옵션 설정

코드 예제

  mysql.createPool({
    ...option,
    maxPreparedStatements: number
  })


결론

  • prepared statement 직접 해제 방법 사용
// 변경 전
await conn.execute(qry, paramArr);

// 변경 후
await conn.execute(qry, paramArr);
await conn.unprepare(qry); // ===> 추가

  • 아래의 쿼리로 Prepared_stmt_count 증가가 일정 수준에서 더 이상 발생하지 않음
show global status like '%stmt%';

0개의 댓글