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을 생성하는 방식이기 때문에 많은 리소스를 낭비하게 된다.
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이 처리할 수 있다는 장점이 있다.
mysql2는 prepared statement라는 것을 지원한다.
prepared statement를 사용하면 매번 동일한 쿼리 실행을 위해 준비할 필요가 없어지기 때문에 성능이 좋아진다.
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 측에서 추가된다.
사실 정확히 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 ...
따라서 execute가 query보다 나은 성능을 보인다.