[주간 복습] 6주차 - createdb 방식과 execute, query의 차이 (Node.js, mysql)

김지환·2024년 4월 7일

1. createdConnection과 createPool

1.1 createdConnection 활용

createdConnection을 활용한 데이터 베이스 연결은 아래와 같다.

// Get the client
const mysql = require('mysql2');

// Create the connection to database
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  database: 'test',
});

위와 같은 방법을 사용할 경우 한 번에 오직 1개의 connection을 쿼리문을 실행할 때마다 새로 생성한다.
직접 connection을 해제하거나 쿼리 문 실행 이후 mysql에서 connection을 해제시킨다.

이러한 방식은 여러가지 단점을 가진다.
오직 1개의 connection은 하나의 쿼리를 실행하는 도중에는 다른 쿼리들을 실행할 수 없어진다.
또한 매번 새로운 connection을 생성하는 방식이기 때문에 많은 리소스를 낭비하게 된다.

1.2 createPool 활용

createPool을 활용한 데이터 베이스 연결은 아래와 같다.

const mysql = require("mysql2/promise");

// Create the connection pool. The pool-specific settings are the defaults
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  database: 'test',
  waitForConnections: true,
  connectionLimit: 10,
  maxIdle: 10, // max idle connections, the default value is the same as `connectionLimit`
  idleTimeout: 60000, // idle connections timeout, in milliseconds, the default value 60000
  queueLimit: 0,
  enableKeepAlive: true,
  keepAliveInitialDelay: 0,
});

pool은 connection들을 저장하는 장소이다.
사용자가 pool에게 connection을 요청할 경우
1. 기존에 사용되지 않던 connection을 받거나
2. 새로운 connection을 받는다.
만약 받을 수 있는 connection이 없다면(connection limit), connection을 받을 때까지 기다리게 된다.

이러한 방식은 어떤 connection이 쿼리를 처리하고 있을 때에도, 다른 쿼리를 또 다른 connection이 처리할 수 있다는 장점이 있다.

2. execute vs query

mysql2는 prepared statement라는 것을 지원한다.
prepared statement를 사용하면 매번 동일한 쿼리 실행을 위해 준비할 필요가 없어지기 때문에 성능이 좋아진다.

2.1 query에서의 parameter substitution

const { email, pwd } = req.body;

const sql = "SELECT * FROM users WHERE email = ? AND pwd = ?"
const params = [email, pwd]
const [response] = await dbPool.query(sql, params);

query의 경우 parameter substitution가 client 측에서 추가된다.

2.2 execute에서의 parameter substitution

사실 정확히 execute에서는 parameter substitution가 아닌 prepared statement가 맞는 표현이다.

const { email, pwd } = req.body;

const sql = "SELECT * FROM users WHERE email = ? AND pwd = ?"
const params = [email, pwd]
const [response] = await dbPool.execute(sql, params);

왜냐하면, execute는 위의 params를 sql문 안에 채우는 과정이 server 측에서 일어나기 때문이다.

한 가지 예시를 들어 query와 execute의 차이를 더 살펴보면

INSERT INTO documents SET name="누구누구"

위와 같은 sql문을 실행한다고 가정하면
query의 경우는 다음과 같고

실행하는 sql : INSERT INTO documents SET name="김아무개"
client -> server : INSERT INTO documents SET name="김아무개"
server -> client : ok, INSERT ...

실행하는 sql : INSERT INTO documents SET name="최아무개"
client -> server : INSERT INTO documents SET name="최아무개"
server -> client : ok, INSERT ...

execute를 사용한다면

실행하는 sql : INSERT INTO documents SET name="김아무개"
client -> server : prepare INSERT INTO documents SET name=?
server -> client : statement id = 1

client -> server : statement 1 execute, params = "김아무개"
server -> clent : ok, INSERT ...

실행하는 sql : INSERT INTO documents SET name="최아무개"
client -> server : statement 1 execute, params = "최아무개"
server -> client : ok, INSERT ...

따라서 executequery보다 나은 성능을 보인다.

profile
세상의 문제 해결을 즐기는 프론트엔드 개발자

0개의 댓글