2017-07-28 17 views
3

これをどのように修正すればよいか、これが私のクエリやデータベースの問題であったとしても、ここでそれは行きます。 3つのテーブル、製品、リレーションおよびタグがあります。次のようにこれらのカテゴリの間Laravelが複数のテーブルを照会しようとしています

'products' (
    'ID' bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    'user_id' bigint(20) unsigned NOT NULL, 
    'name' varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'primary_image' bigint(20) DEFAULT NULL, 
    'description' longtext COLLATE utf8mb4_unicode_ci, 
    'price' float DEFAULT NULL, 
    'sale_price' float DEFAULT NULL, 
    'currency' varchar(25) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'primary_color' varchar(7) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'secondary_color' varchar(7) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'status' varchar(15) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'quantity' bigint(20) DEFAULT NULL, 
    'origin' varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'type' varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'size' varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'processing_time' varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, 
    'date_added' int(11) DEFAULT NULL, 
    PRIMARY KEY ('ID') 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 

'relations' (
    'ID' bigint(20) unsigned NOT NULL, 
    'relation_id' bigint(20) unsigned NOT NULL, 
    'type' varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, 
    'options' text COLLATE utf8mb4_unicode_ci, 
    KEY 'ID' ('ID'), 
    KEY 'relation_id' ('relation_id') 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 

'tags' (
    'ID' bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    'name' varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL, 
    'slug' varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL, 
    PRIMARY KEY ('ID') 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 

関係が行く:

  • products.ID = relations.ID
  • relations.relation_id = tags.ID

50K製品、250Kがあります。テスト用にデータベースに追加された25k個のタグを使用します。

私は、製品名、説明、タグ内で検索するクエリを作成しています。

このクエリの実行:

Product::select('ID', 'name')->where('name', 'like', '%'.$search_query.'%')->orWhere('description', 'like', '%'.$search_query.'%')->orWhereHas('relations', function($query) use($search_query) { 
    $query->where('type', 'tags')->whereHas('tags', function($query) use($search_query) { 
     $query->where('name', 'like', '%'.$search_query.'%'); 
    }); 
})->paginate(25); 
  • このクエリは、私は特定のタグを照会あれば、それは限り、私は同様のを建て
  • 1.8sとして取り、データを見つけるために、0.8秒の周りにかかりますジョインでクエリを実行すると、それ以上時間がかかりましたので、今は上記のクエリにとどまっていました。

私が間違っていると思われることはありますか?ここでの主な問題は、クエリの実行時間です。

+1

、Laravelスカウトhttps://laravel.com/docs/5.4/scout MySQLドライバを持っていhttps://github.com/damiantw/laravel-scout -mysql-driver。長い時間がかかりますが、クエリに間違いはありませんか? – Jeff

+0

ありがとう、私はスカウトを見ていきます。私が気付いているのではなく、ただの純粋な実行時間であり、より多くのデータを期待しているので、実行時間が問題になるのではないかと心配しています。 – John

答えて

0

私が知っているこのクエリを最適化する方法はありません。 'LIKE', searchquery.'%'(先行%なし)を使用している場合は、スピードブーストのためにテキスト列にインデックスを付けることができます。両方のワイルドカードでこの機能が必要な場合は、フルテキスト索引検索プロバイダを使用する必要があります。 Algolia https://www.algolia.com/は私が知っているものであり、Laravel Scoutは彼らの検索で動作するように作られています。このother questionは、http://sphinxsearch.com/http://lucene.apache.org/core/も参照していますが、わかりません。

編集:ケースあなたが興味を持っているにもhttps://www.elastic.co/products/elasticsearch

関連する問題