Performance Optimization
Performance Optimization Overview
Section titled “Performance Optimization Overview”This guide covers comprehensive performance optimization strategies for the Elasticsearch integration system, including database tuning, search optimization, caching strategies, and system-level improvements.
Database Performance
Section titled “Database Performance”PostgreSQL Optimization
Section titled “PostgreSQL Optimization”Connection Pooling
Section titled “Connection Pooling”// Implement connection poolingclass DatabasePool { private static $connections = []; private static $max_connections = 10;
public static function getConnection() { // Reuse existing connection if (!empty(self::$connections)) { return array_pop(self::$connections); }
return create_new_connection(); }
public static function releaseConnection($connection) { if (count(self::$connections) < self::$max_connections) { self::$connections[] = $connection; } else { pg_close($connection); } }}Query Optimization
Section titled “Query Optimization”-- Optimize product queries with composite indexesCREATE INDEX idx_product_sync_composite ON product(added_search, id)WHERE title IS NOT NULL;
-- Optimize category joinsCREATE INDEX idx_category_parent ON core_category(parent_id);
-- Optimize updated_at queries for incremental syncCREATE INDEX idx_product_updated ON product(updated_at DESC)WHERE added_search = FALSE;
-- Partial indexes for better performanceCREATE INDEX idx_active_products ON product(id) WHERE is_active = TRUE;Database Configuration
Section titled “Database Configuration”# postgresql.conf optimizationsmax_connections = 200shared_buffers = 4GBeffective_cache_size = 12GBwork_mem = 50MBmaintenance_work_mem = 1GBcheckpoint_completion_target = 0.9wal_buffers = 16MBdefault_statistics_target = 100Query Performance Monitoring
Section titled “Query Performance Monitoring”-- Monitor slow queriesSELECT query, calls, total_time, mean_time, rowsFROM pg_stat_statementsORDER BY mean_time DESCLIMIT 20;
-- Check index usageSELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetchFROM pg_stat_user_indexesORDER BY idx_scan DESC;
-- Analyze table statisticsANALYZE product;ANALYZE core_category;Elasticsearch Performance
Section titled “Elasticsearch Performance”Index Optimization
Section titled “Index Optimization”Index Settings
Section titled “Index Settings”{ "settings": { "number_of_shards": 3, "number_of_replicas": 1, "refresh_interval": "30s", "max_result_window": 10000, "index": { "translog": { "flush_threshold_size": "512mb", "sync_interval": "30s" } } }}Mapping Optimization
Section titled “Mapping Optimization”{ "mappings": { "properties": { "title": { "type": "text", "analyzer": "lithuanian_analyzer", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "price": { "type": "float", "index": true, "doc_values": true }, "category": { "type": "keyword", "eager_global_ordinals": true } } }}Search Query Optimization
Section titled “Search Query Optimization”Use Filters Instead of Queries
Section titled “Use Filters Instead of Queries”// Optimized search queryprivate function buildOptimizedSearchQuery($query, $filters) { $filter_clauses = []; $query_clauses = [];
// Convert exact matches to filters (faster) if (!empty($filters['category'])) { $filter_clauses[] = ['term' => ['category' => $filters['category']]]; }
if (!empty($filters['brand'])) { $filter_clauses[] = ['terms' => ['brand' => (array)$filters['brand']]]; }
if (!empty($filters['min_price']) || !empty($filters['max_price'])) { $range = []; if (!empty($filters['min_price'])) $range['gte'] = $filters['min_price']; if (!empty($filters['max_price'])) $range['lte'] = $filters['max_price']; $filter_clauses[] = ['range' => ['price' => $range]]; }
// Keep fuzzy search in query if (!empty($query)) { $query_clauses[] = [ 'multi_match' => [ 'query' => $query, 'fields' => ['title^3', 'brand^2', 'description'], 'fuzziness' => 'AUTO' ] ]; }
return [ 'bool' => [ 'must' => $query_clauses, 'filter' => $filter_clauses ] ];}Search Performance Tuning
Section titled “Search Performance Tuning”// Optimize search parametersprivate $search_optimizations = [ 'preference' => '_local', // Prefer local shards 'timeout' => '5s', // Request timeout 'terminate_after' => 10000, // Limit results 'track_total_hits' => false, // Skip total count for large results 'size' => 20, // Limit result size 'from' => 0 // Pagination offset];Bulk Operations Optimization
Section titled “Bulk Operations Optimization”Batch Size Tuning
Section titled “Batch Size Tuning”// Dynamic batch size based on system resourcesprivate function optimizeBatchSize() { $memory_limit = ini_get('memory_limit'); $memory_bytes = $this->parseMemoryLimit($memory_limit);
if ($memory_bytes < 256 * 1024 * 1024) { // Less than 256MB return 100; } elseif ($memory_bytes < 512 * 1024 * 1024) { // Less than 512MB return 250; } else { return 500; // Default }}
// Optimize bulk requestsprivate function optimizeBulkRequest($documents) { $bulk_body = [];
foreach ($documents as $doc) { $bulk_body[] = [ 'index' => [ '_index' => $this->index_name, '_id' => $doc['id'] ] ]; $bulk_body[] = $doc; }
return $bulk_body;}PHP Performance
Section titled “PHP Performance”Memory Management
Section titled “Memory Management”Memory Optimization
Section titled “Memory Optimization”// Optimize memory usageini_set('memory_limit', '512M');set_time_limit(300);
// Garbage collectiongc_enable();gc_collect_cycles();
// Memory monitoringprivate function checkMemoryUsage() { $memory_usage = memory_get_usage(true); $memory_limit = ini_get('memory_limit'); $memory_limit_bytes = $this->parseMemoryLimit($memory_limit);
$usage_percentage = ($memory_usage / $memory_limit_bytes) * 100;
if ($usage_percentage > 80) { $this->log("High memory usage: {$usage_percentage}%", 'WARNING'); gc_collect_cycles(); }}OPcache Configuration
Section titled “OPcache Configuration”; php.ini optimizationsopcache.enable=1opcache.memory_consumption=256opcache.max_accelerated_files=10000opcache.revalidate_freq=60opcache.fast_shutdown=1opcache.enable_cli=1Code Optimization
Section titled “Code Optimization”Efficient Data Processing
Section titled “Efficient Data Processing”// Process data in chunksprivate function processInChunks($items, $chunk_size, $processor) { $chunks = array_chunk($items, $chunk_size); $results = [];
foreach ($chunks as $chunk) { $results = array_merge($results, $processor($chunk));
// Memory management unset($chunk); gc_collect_cycles(); }
return $results;}
// Optimize array operationsprivate function optimizeArrayOperations($data) { // Use array_column for better performance $ids = array_column($data, 'id');
// Use array_combine for key-value pairs $keyed_data = array_combine($ids, $data);
return $keyed_data;}Caching Strategies
Section titled “Caching Strategies”WordPress Object Cache
Section titled “WordPress Object Cache”Search Result Caching
Section titled “Search Result Caching”// Cache search resultspublic function getCachedSearchResults($cache_key, $callback) { $cached = wp_cache_get($cache_key, 'elasticsearch_search');
if ($cached === false) { $cached = $callback(); wp_cache_set($cache_key, $cached, 'elasticsearch_search', 300); // 5 min cache }
return $cached;}
// Cache aggregationspublic function getCachedAggregations($cache_key, $callback) { $cached = wp_cache_get($cache_key, 'elasticsearch_aggregations');
if ($cached === false) { $cached = $callback(); wp_cache_set($cache_key, $cached, 'elasticsearch_aggregations', 600); // 10 min cache }
return $cached;}Redis Integration
Section titled “Redis Integration”// Redis caching (if available)class RedisCache { private $redis;
public function __construct() { if (class_exists('Redis')) { $this->redis = new Redis(); $this->redis->connect('127.0.0.1', 6379); } }
public function get($key) { if ($this->redis) { $data = $this->redis->get($key); return $data ? json_decode($data, true) : false; } return false; }
public function set($key, $value, $ttl = 300) { if ($this->redis) { return $this->redis->setex($key, $ttl, json_encode($value)); } return false; }}Application-Level Caching
Section titled “Application-Level Caching”Query Result Caching
Section titled “Query Result Caching”// Cache database queriesprivate function getCachedQuery($query, $params, $ttl = 300) { $cache_key = 'query_' . md5($query . serialize($params)); $cached = wp_cache_get($cache_key, 'database_queries');
if ($cached === false) { $connection = $this->getDatabaseConnection(); $result = pg_query_params($connection, $query, $params); $cached = pg_fetch_all($result); wp_cache_set($cache_key, $cached, 'database_queries', $ttl); }
return $cached;}System-Level Optimization
Section titled “System-Level Optimization”Server Configuration
Section titled “Server Configuration”PHP-FPM Optimization
Section titled “PHP-FPM Optimization”; php-fpm.confpm = dynamicpm.max_children = 50pm.start_servers = 5pm.min_spare_servers = 5pm.max_spare_servers = 35pm.max_requests = 1000Apache/Nginx Optimization
Section titled “Apache/Nginx Optimization”# Apache optimization<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript</IfModule>
# Enable KeepAliveKeepAlive OnMaxKeepAliveRequests 100KeepAliveTimeout 5Network Optimization
Section titled “Network Optimization”Connection Optimization
Section titled “Connection Optimization”// Optimize cURL settingsprivate function optimizeCurlSettings($ch) { curl_setopt_array($ch, [ CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_HTTPHEADER => [ 'Connection: close', // Don't keep connections alive 'Content-Type: application/json' ], CURLOPT_TCP_NODELAY => true, CURLOPT_TCP_FASTOPEN => true ]);}Monitoring and Profiling
Section titled “Monitoring and Profiling”Performance Monitoring
Section titled “Performance Monitoring”Response Time Monitoring
Section titled “Response Time Monitoring”// Monitor response timesprivate function monitorResponseTime($operation, $callback) { $start_time = microtime(true); $result = $callback(); $end_time = microtime(true);
$duration = ($end_time - $start_time) * 1000; // Convert to milliseconds
$this->log("Operation '{$operation}' took {$duration}ms", 'INFO');
// Alert on slow operations if ($duration > 1000) { // 1 second $this->log("Slow operation detected: {$operation} took {$duration}ms", 'WARNING'); }
return $result;}Memory Usage Monitoring
Section titled “Memory Usage Monitoring”// Monitor memory usageprivate function monitorMemoryUsage($operation) { $memory_usage = memory_get_usage(true); $peak_memory = memory_get_peak_usage(true);
$this->log("Memory usage for '{$operation}': {$memory_usage} bytes (peak: {$peak_memory})", 'INFO');
// Alert on high memory usage if ($memory_usage > 100 * 1024 * 1024) { // 100MB $this->log("High memory usage detected: {$memory_usage} bytes", 'WARNING'); }}Profiling Tools
Section titled “Profiling Tools”Query Profiling
Section titled “Query Profiling”// Profile database queriesprivate function profileQuery($query, $params) { $start_time = microtime(true); $connection = $this->getDatabaseConnection(); $result = pg_query_params($connection, $query, $params); $end_time = microtime(true);
$duration = ($end_time - $start_time) * 1000;
if ($duration > 100) { // 100ms $this->log("Slow query detected: {$duration}ms - {$query}", 'WARNING'); }
return $result;}Load Testing
Section titled “Load Testing”Performance Testing
Section titled “Performance Testing”Search Load Testing
Section titled “Search Load Testing”// Load test search functionalitypublic function loadTestSearch($iterations = 100) { $queries = [ 'smartphone', 'laptop', 'tablet', 'headphones', 'camera' ];
$total_time = 0; $success_count = 0;
for ($i = 0; $i < $iterations; $i++) { $query = $queries[array_rand($queries)]; $start_time = microtime(true);
try { $results = $this->searchProducts($query); $end_time = microtime(true);
$duration = ($end_time - $start_time) * 1000; $total_time += $duration; $success_count++;
if ($duration > 1000) { $this->log("Slow search: {$query} took {$duration}ms", 'WARNING'); } } catch (Exception $e) { $this->log("Search failed: {$query} - {$e->getMessage()}", 'ERROR'); } }
$avg_time = $total_time / $success_count; $success_rate = ($success_count / $iterations) * 100;
$this->log("Load test results: {$success_count}/{$iterations} successful, avg time: {$avg_time}ms", 'INFO');
return [ 'iterations' => $iterations, 'success_count' => $success_count, 'success_rate' => $success_rate, 'avg_response_time' => $avg_time ];}Best Practices
Section titled “Best Practices”Code Optimization
Section titled “Code Optimization”Efficient Data Structures
Section titled “Efficient Data Structures”// Use appropriate data structuresprivate function optimizeDataStructures($data) { // Use associative arrays for lookups $lookup = array_flip(array_column($data, 'id'));
// Use generators for large datasets function processLargeDataset($items) { foreach ($items as $item) { yield processItem($item); } }
// Use array functions efficiently $filtered = array_filter($data, function($item) { return $item['active'] === true; });}Memory-Efficient Processing
Section titled “Memory-Efficient Processing”// Process large datasets efficientlyprivate function processLargeDataset($items) { $batch_size = 1000; $processed = 0;
foreach (array_chunk($items, $batch_size) as $batch) { $this->processBatch($batch); $processed += count($batch);
// Memory management unset($batch); gc_collect_cycles();
// Progress logging if ($processed % 10000 === 0) { $this->log("Processed {$processed} items", 'INFO'); } }}Configuration Optimization
Section titled “Configuration Optimization”Environment-Specific Settings
Section titled “Environment-Specific Settings”// Environment-specific optimizationprivate function getOptimizedSettings() { $environment = getenv('APP_ENV') ?: 'production';
switch ($environment) { case 'development': return [ 'batch_size' => 100, 'cache_ttl' => 60, 'log_level' => 'DEBUG' ];
case 'staging': return [ 'batch_size' => 250, 'cache_ttl' => 300, 'log_level' => 'INFO' ];
case 'production': default: return [ 'batch_size' => 500, 'cache_ttl' => 600, 'log_level' => 'WARNING' ]; }}Performance Metrics
Section titled “Performance Metrics”Key Performance Indicators
Section titled “Key Performance Indicators”Search Performance
Section titled “Search Performance”- Response Time: < 100ms for 95% of queries
- Throughput: > 100 queries/second
- Error Rate: < 1%
- Cache Hit Rate: > 80%
Sync Performance
Section titled “Sync Performance”- Processing Speed: > 1000 products/minute
- Memory Usage: < 512MB
- Error Rate: < 5%
- Uptime: > 99.9%
System Performance
Section titled “System Performance”- CPU Usage: < 80%
- Memory Usage: < 80%
- Disk I/O: < 1000 IOPS
- Network Latency: < 50ms
Monitoring Dashboard
Section titled “Monitoring Dashboard”// Performance metrics collectionpublic function collectPerformanceMetrics() { return [ 'search' => [ 'avg_response_time' => $this->getAverageSearchTime(), 'queries_per_second' => $this->getQueriesPerSecond(), 'error_rate' => $this->getSearchErrorRate(), 'cache_hit_rate' => $this->getCacheHitRate() ], 'sync' => [ 'products_per_minute' => $this->getProductsPerMinute(), 'memory_usage' => $this->getMemoryUsage(), 'error_rate' => $this->getSyncErrorRate(), 'uptime' => $this->getUptime() ], 'system' => [ 'cpu_usage' => $this->getCpuUsage(), 'memory_usage' => $this->getSystemMemoryUsage(), 'disk_io' => $this->getDiskIO(), 'network_latency' => $this->getNetworkLatency() ] ];}Next Steps
Section titled “Next Steps”- Troubleshooting - Common issues and solutions
- Monitoring & Management - Console and monitoring
- Deployment - Installation and setup
- Configuration - System configuration