PHP项目Laravel索引建议怎么加

wen PHP项目 3

本文目录导读:

PHP项目Laravel索引建议怎么加

  1. 使用数据库迁移(推荐)
  2. 使用索引类型
  3. 通过Artisan命令生成迁移
  4. 常见索引建议场景
  5. 检查现有索引
  6. 性能优化建议
  7. 完整的迁移示例
  8. 注意事项

在Laravel中为数据库添加索引,有几种方法,我来详细说明:

使用数据库迁移(推荐)

在迁移文件中创建索引

<?php
// database/migrations/2024_01_01_000000_add_indexes_to_users_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            // 普通索引
            $table->index('email');
            // 复合索引(多个字段)
            $table->index(['country', 'city']);
            // 唯一索引
            $table->unique('phone');
            // 指定索引名称
            $table->index('status', 'idx_user_status');
        });
    }
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            // 删除索引
            $table->dropIndex(['email']);
            $table->dropIndex(['country', 'city']);
            $table->dropUnique(['phone']);
            $table->dropIndex('idx_user_status');
        });
    }
};

在创建表时添加索引

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('sku')->unique();
    $table->decimal('price', 10, 2);
    $table->unsignedBigInteger('category_id');
    // 在创建表时添加索引
    $table->index('name');
    $table->index(['category_id', 'price']);
    $table->foreign('category_id')->references('id')->on('categories');
});

使用索引类型

Laravel支持多种索引类型:

Schema::table('posts', function (Blueprint $table) {
    // 全文索引(MySQL/PostgreSQL)
    $table->fullText('content');
    // 空间索引(MySQL)
    $table->spatialIndex('coordinates');
    // 复合唯一索引
    $table->unique(['user_id', 'post_id']);
    // 索引长度限制(SQLite)
    $table->index(DB::raw('LEFT(title, 100)'));
});

通过Artisan命令生成迁移

# 生成新的迁移文件
php artisan make:migration add_indexes_to_products_table --table=products
# 运行迁移
php artisan migrate
# 回滚最后一个迁移
php artisan migrate:rollback --step=1

常见索引建议场景

常用查询字段

// 用户表经常按邮箱、手机号查询
Schema::table('users', function (Blueprint $table) {
    $table->index('email');
    $table->index('phone');
});

外键字段

Schema::table('orders', function (Blueprint $table) {
    $table->foreignId('user_id')->index();
    $table->foreignId('product_id')->index();
});

组合查询条件

Schema::table('products', function (Blueprint $table) {
    // 当经常按 category_id 和 status 查询时
    $table->index(['category_id', 'status']);
});

检查现有索引

// 在代码中检查表是否已有索引
if (!Schema::hasIndex('users', 'email')) {
    Schema::table('users', function (Blueprint $table) {
        $table->index('email')->name('idx_user_email');
    });
}

性能优化建议

// 为查询频率高的字段添加索引
$table->index('order_number');  // 订单号查询频繁
// 为排序字段添加索引
$table->index('created_at');    // 经常按时间排序
// 避免过度索引,只对WHERE、JOIN、ORDER BY中的字段添加

完整的迁移示例

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    public function up()
    {
        Schema::table('products', function (Blueprint $table) {
            // 添加多个索引
            $table->index('category_id');
            $table->index('brand_id');
            $table->unique('barcode');
            $table->index(['store_id', 'status']);
            $table->index('updated_at');
        });
    }
    public function down()
    {
        Schema::table('products', function (Blueprint $table) {
            $table->dropIndex(['category_id']);
            $table->dropIndex(['brand_id']);
            $table->dropUnique(['barcode']);
            $table->dropIndex(['store_id', 'status']);
            $table->dropIndex(['updated_at']);
        });
    }
};

注意事项

  • 不要过度添加索引:每个索引都会增加写入和存储成本
  • 命名规范:通常使用 idx_ 前缀(普通索引)和 uq_ 前缀(唯一索引)
  • 小表不需要索引:当表行数很少时,全表扫描可能比索引查找更快
  • 测试影响:在添加索引前,使用 EXPLAIN 命令分析查询
-- 在数据库客户端中测试查询性能
EXPLAIN SELECT * FROM products WHERE category_id = 1 AND status = 'active';

使用迁移管理索引是Laravel的最佳实践,它让索引管理版本化、可重复,并支持在团队中协作。

抱歉,评论功能暂时关闭!