SQL_CALC_FOUND_ROWS란?SQL_CALC_FOUND_ROWS는 MySQL에서 사용되는 쿼리 힌트로, SELECT문과 함께 사용하여 쿼리에서 페이징 처리를 할 때 유용합니다.
페이징 처리는 데이터베이스의 특정 범위 데이터를 가져오면서, 전체 데이터의 개수(totalCount)도 함께 구해야 할 때 자주 사용됩니다.
LIMIT을 사용.SQL_CALC_FOUND_ROWS를 사용하면 제한된 결과(LIMIT)뿐만 아니라 쿼리가 필터링된 전체 데이터 개수도 계산 가능.기본 쿼리:
LIMIT과 함께 사용.SELECT SQL_CALC_FOUND_ROWS column1, column2
FROM table_name
WHERE conditions
LIMIT 10 OFFSET 0;
전체 데이터 개수 가져오기:
FOUND_ROWS()를 호출하여 전체 데이터 개수를 얻음.SELECT FOUND_ROWS();
-- Step 1: 데이터 가져오기 (LIMIT 적용)
SELECT SQL_CALC_FOUND_ROWS id, name
FROM users
WHERE age > 18
LIMIT 10 OFFSET 0;
-- Step 2: 전체 데이터 개수 가져오기
SELECT FOUND_ROWS();
SQL_CALC_FOUND_ROWS는 성능이 저하될 수 있음.COUNT(*)를 사용하여 전체 개수를 별도로 계산:SELECT COUNT(*) FROM table_name WHERE conditions;COUNT(*)를 사용하는 것이 좋음.SQL_CALC_FOUND_ROWS는 페이징 처리와 같은 작업에서 편리하지만, 데이터베이스 성능 최적화 측면에서는 신중히 사용해야 합니다. 최신 MySQL 버전에서는 더 효율적인 방법이 권장되므로 상황에 따라 적절한 대안을 선택하는 것이 좋습니다.
const allBooks = (req, res) => {
let { category_id, newBook, limit, currentPage } = req.query;
// limit : page당 보여줄 갯 수
// currentPage : 현재 페이지(숫자)
// offset : (current-1)*limit
let offset = limit * (currentPage - 1);
let sql = `SELECT *, (SELECT count(*) FROM likes WHERE liked_book_id = books.id) AS 'likes' FROM books `;
let values = [];
if (category_id && newBook) {
// category별 신간
sql += ` WHERE category_id = ? AND pub_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 month) AND NOW()`;
values = [category_id];
} else if (category_id) {
// category별
sql += ` WHERE category_id = ? `;
values = [category_id];
} else if (newBook) {
// 신간
sql += ' WHERE pub_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 month) AND NOW()';
}
sql += ` LIMIT ? OFFSET ?`;
values.push(parseInt(limit), offset);
conn.query(sql, values, (err, results) => {
if (err) {
console.error(err);
return res.status(StatusCodes.BAD_GATEWAY).json({ error: '데이터베이스 오류입니다.' });
}
if (results.length) {
return res.status(StatusCodes.OK).json({
books: results,
pagenation: { currentPage: currentPage },
});
} else {
return res.status(StatusCodes.NOT_FOUND).end();
}
});
};
코드 상단에서 sql 변수에 SQL_CALC_FOUND_ROWS추가해야합니다.
let sql = SELECT SQL_CALC_FOUND_ROWS *, (SELECT count(*)
FROM likes
WHERE liked_book_id = books.id) AS 'likes' FROM books ;
또한 FOUND_ROWS() AS totalCount 로 통해서 SQL_CALC_FOUND_ROWS 데이터를 가져와야 합니다.