기본 최적화 전략
1. Prepared Statements 사용
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);
2. 인덱스 활용
// 인덱스를 활용한 쿼리
$query = "SELECT * FROM users
WHERE email = ?
AND status = 'active'
USE INDEX (email_status)";
3. 필요한 컬럼만 선택
// 전체 컬럼 대신 필요한 컬럼만 선택
$stmt = $pdo->prepare("SELECT id, name, email FROM users");
고급 최적화 기법
1. 배치 처리
$stmt = $pdo->prepare("INSERT INTO logs (user_id, action) VALUES (?, ?)");
$pdo->beginTransaction();
foreach ($logs as $log) {
$stmt->execute([$log['user_id'], $log['action']]);
}
$pdo->commit();
2. 조인 최적화
$query = "SELECT u.name, o.order_date
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.status = 'completed'
LIMIT 100";
3. 캐싱 구현
function getCachedData($key, $callback) {
$cache = new Redis();
$result = $cache->get($key);
if ($result === false) {
$result = $callback();
$cache->set($key, $result, 3600);
}
return $result;
}
성능 모니터링
1. 쿼리 프로파일링
$startTime = microtime(true);
// 쿼리 실행
$endTime = microtime(true);
$executionTime = $endTime - $startTime;
2. 실행 계획 분석
$stmt = $pdo->prepare("EXPLAIN SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
최적화 클래스 구현
class QueryOptimizer {
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function batchInsert($table, $data, $columns) {
$placeholders = str_repeat('(?),', count($data) - 1) . '(?)';
$sql = "INSERT INTO $table (" . implode(',', $columns) . ") VALUES " . $placeholders;
return $this->pdo->prepare($sql)->execute($data);
}
}
모범 사례
- 적절한 인덱스 사용
- 불필요한 조인 제거
- LIMIT 절 활용
- 캐싱 전략 수립
- 정기적인 성능 모니터링
실제 구현 예시
// 최적화된 페이지네이션 쿼리
function getPaginatedResults($page, $limit) {
$offset = ($page - 1) * $limit;
$stmt = $pdo->prepare("
SELECT id, title, created_at
FROM posts
WHERE status = 'published'
ORDER BY created_at DESC
LIMIT ? OFFSET ?
");
return $stmt->execute([$limit, $offset]);
}