【问题标题】:laravel how to use force index in eloquentlaravel 如何在 eloquent 中使用力指数
【发布时间】:2018-09-09 07:37:40
【问题描述】:

我有一个如下所示的 SQL 查询:

SELECT * FROM orders FORCE INDEX(order_type_index) WHERE `type` = 1

我可以使用查询生成器重新创建:

DB::table(DB::raw('orders force index(orders_type_index)'))
    ->where('type', 1)
    ->get();

但是有没有办法让 Eloquent 使用这个索引,比如:

Order::forceIndex('orders_type_index')->where('type', 1)->get();

【问题讨论】:

标签: php mysql laravel eloquent


【解决方案1】:

您可以通过创建local scope 来实现此目的,该local scope 在应用时会更改构建器的表名。在使用该表之前,应检查该表的索引。如果提供了无效的索引名称,您可以抛出异常或忽略它(我选择了后一种方法。)

<?php

namespace App;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/*
 * Class Order
 *
 * @method \Illuminate\Database\Eloquent\Builder useIndex(string $index)
 * @method \Illuminate\Database\Eloquent\Builder forceIndex(string $index)
 */
class Order extends Model
{
    private function tableIndexExists(string $index): boolean
    {
        $table = $this->getTable();
        $index = strtolower($index);
        $indices = Schema::getConnection()
            ->getDoctrineSchemaManager()
            ->listTableIndexes($table);

        return array_key_exists($index, $indices);
    }

    public function scopeUseIndex(Builder $query, string $index): Builder
    {
        $table = $this->getTable();

        return $this->tableIndexExists($index)
            ? $query->from(DB::raw("`$table` USE INDEX(`$index`)"))
            : $query;
    }

    public function scopeForceIndex(Builder $query, string $index): Builder
    {
        $table = $this->getTable();

        return $this->tableIndexExists($index)
            ? $query->from(DB::raw("`$table` FORCE INDEX(`$index`)"))
            : $query;
    }
}

如果您需要在多个模型上执行此操作,可以轻松地将其添加到特征并导入。 docblock 确保您的 IDE 知道代码完成的神奇方法。

那么你可以这样使用它:

$orders = Order::forceIndex("orders_type_index")->where("type", 1)->get();

// or this:
$orders = Customer::find(234)
    ->orders()
    ->forceIndex("orders_type_index")
    ->where("type", 1)
    ->get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2021-09-29
    • 2021-08-05
    • 2018-07-01
    相关资源
    最近更新 更多