PHP项目数据库查询性能优化指南
索引优化
-- 为常用查询字段添加索引 CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_order_user_id ON orders(user_id, created_at); -- 复合索引要注意最左前缀原则 -- 下面索引适用于 WHERE user_id = ? AND status = ? CREATE INDEX idx_order_user_status ON orders(user_id, status);
查询优化技巧
// 1. 选择性字段,避免 SELECT *
$sql = "SELECT id, name, email FROM users WHERE status = 1";
// 2. 使用 LIMIT 限制返回数量
$sql = "SELECT * FROM articles WHERE category_id = 5 LIMIT 10";
// 3. 避免在 WHERE 中使用函数
// 不推荐
$sql = "SELECT * FROM users WHERE DATE(created_at) = '2025-01-01'";
// 推荐
$sql = "SELECT * FROM users WHERE created_at >= '2025-01-01' AND created_at < '2025-01-02'";
// 4. 使用 EXISTS 代替 IN(子查询较大时)
$sql = "SELECT * FROM users u WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id
)";
使用查询缓存
// Redis 缓存示例
class QueryCache {
private $redis;
private $ttl = 300;
public function get($key, $callback) {
$cacheKey = 'query:' . $key;
$data = $this->redis->get($cacheKey);
if ($data === false) {
$data = $callback();
$this->redis->setex($cacheKey, $this->ttl, serialize($data));
}
return unserialize($data);
}
}
// 使用示例
$users = $cache->get('users:active', function() {
return DB::select("SELECT * FROM users WHERE status = 1");
});
数据库连接优化
// 1. 使用连接池(PDO 持久连接)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4',
$user, $pass, [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false
]
);
// 2. 使用读写分离
class DatabaseManager {
public function getConnection($isWrite = false) {
if ($isWrite) {
return $this->writeConnection;
}
return $this->readConnection; // 连接从库
}
}
分页优化
// 使用游标分页替代 OFFSET 分页
// 不推荐
$sql = "SELECT * FROM orders ORDER BY id DESC LIMIT 10 OFFSET 100000";
// 推荐 - 记住最后一条记录的 ID
$sql = "SELECT * FROM orders
WHERE id < $lastId
ORDER BY id DESC
LIMIT 10";
避免N+1查询问题
// 不推荐 - N+1 查询
$users = User::all();
foreach ($users as $user) {
$posts = $user->posts; // 每个用户都执行一次查询
}
// 推荐 - 使用 JOIN 或预加载
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->select('users.*', 'posts.title as post_title')
->get();
分表分库策略
// 根据用户ID进行分表
class UserRepository {
public function getTableName($userId) {
$tableIndex = $userId % 10;
return "users_{$tableIndex}";
}
public function getById($userId) {
$table = $this->getTableName($userId);
$sql = "SELECT * FROM {$table} WHERE id = ?";
return DB::select($sql, [$userId]);
}
}
监控和日志
// 慢查询日志配置(MySQL)
// my.cnf 配置
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
// PHP 端监控
class QueryLogger {
public static function logSlowQuery($sql, $params, $time) {
if ($time > 1) { // 超过1秒的查询
Log::warning('Slow query', [
'sql' => $sql,
'params' => $params,
'time' => $time
]);
}
}
}
使用批量操作
// 批量插入
DB::table('users')->insert([
['name' => '张三', 'email' => 'zhangsan@example.com'],
['name' => '李四', 'email' => 'lisi@example.com'],
// ...
]);
// 批量更新
DB::table('users')
->whereIn('id', [1, 2, 3])
->update(['status' => 1]);
优化数据库配置
# MySQL 配置优化 [mysqld] innodb_buffer_pool_size = 4G innodb_log_file_size = 256M max_connections = 500 thread_cache_size = 50 query_cache_type = 1 query_cache_size = 128M
代码优化建议
// 1. 使用预处理语句避免 SQL 注入
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
// 2. 延迟加载不需要的数据
class User {
private $orders = null;
public function getOrders() {
if ($this->orders === null) {
$this->orders = DB::select("SELECT * FROM orders WHERE user_id = ?");
}
return $this->orders;
}
}
使用文件缓存策略
class DataCache {
public static function remember($key, $ttl, $callback) {
$file = storage_path("cache/{$key}.json");
if (file_exists($file) && (time() - filemtime($file) < $ttl)) {
return json_decode(file_get_contents($file), true);
}
$data = $callback();
file_put_contents($file, json_encode($data));
return $data;
}
}
通过这些优化策略,可以显著提升 PHP 项目的数据库查询性能,关键是找到合适的优化方案,并持续监控和调优。

版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播