提高SQL查询速度

时间:2017-05-04 04:38:02

标签: mysql sql laravel-5

我使用的是MySQL,我的架构如下:

|------------|-------------|------------|--------------|
|    cities  |category_city|  categories|   companies  |
|------------|-------------|------------|--------------|
|     id     |  city_id    |     id     |     id       |
|    name    | category_id |    name    |subcategory_id|
|            |             |  parent_id |    city_id   |
|            |             |            |...other cols |
|____________|_____________|____________|______________|

关系: 具有类别的城市有->belongsToMany()

public function categories()
{
    return $this->belongsToMany(Category::class);
}

类别有子类别:

public function subcategories()
{
    return $this->hasMany(Category::class, 'parent_id', 'id');
}

我从公司分类并按城市过滤,因为我需要现有的城市公司,因此我有全球范围:

 public function getCompanies($city_id)
    {
        return $this->companies()->whereHas('mainCity', function ($q) use ($city_id) {
            $q->where('city_id', $city_id);
        });
    }

mainCity 方法:

public function mainCity()
{
    return $this->belongsTo(City::class, 'city_id');
}

以下是使用AJAX请求执行查询的方法:

public function getPlaces(City $city, Category $subcategory, $north, $south, $east, $west)
{
    $companies = $subcategory->companies()
        ->withCount('comments')
        ->companiesByBounds($north, $south, $east, $west)
        ->paginate(8);

    $markers = $subcategory->companies()
        ->companiesByBounds($north, $south, $east, $west)
        ->get(['lat', 'lng', 'slug', 'title']);

    return response()->json(['companies' => $companies, 'markers' => $markers], 200, [], JSON_NUMERIC_CHECK);
}

并通过companiesByBounds范围方法:

public function scopeCompaniesByBounds($query, $north, $south, $east, $west)
{
    return $query->whereBetween('lat', [$south, $north])
        ->whereBetween('lng', [$west, $east]);
}

在公司里我有大约200万条记录。主要问题是查询耗时3.5秒。请帮助改进我的疑问。

以下是查询:

select count(*) as aggregate from `companies` where `companies`.`category_id` = '40' and `companies`.`category_id` is not null and `lat` between '53.68540097020851' and '53.749703253622705' and `lng` between '91.34262820463869' and '91.51600619536134'

1 个答案:

答案 0 :(得分:1)

要提高速度,您需要在列latlng上添加索引。

CREATE INDEX idx_lat ON companies (lat);

当列添加到条件时,索引将用于查询。