PHP 데이터베이스 쿼리 최적화

프리터코더·2025년 5월 25일

php 문제 해결

목록 보기
11/79

기본 최적화 전략

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]);
}
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글