【问题标题】:Laravel trying to query multiple tablesLaravel 尝试查询多个表
【发布时间】:2018-01-04 20:42:12
【问题描述】:

不太清楚如何解决这个问题,如果这甚至是我的查询或数据库的问题,那么就到这里吧。有3个表,产品,关系和标签。

'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 = 关系.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);
  • 这个查询需要0.8s左右找到数据,如果我查询一个特定的标签,需要1.8s左右
  • 我使用连接构建了一个类似的查询,但花费的时间甚至更长,所以我暂时保留了上述查询。

你们知道我做错了什么吗?这里的主要问题是查询执行时间。

【问题讨论】:

  • 如果你有兴趣,Laravel Scout laravel.com/docs/5.4/scout 有一个 MySql 驱动程序 github.com/damiantw/laravel-scout-mysql-driver。除了需要很长时间之外,您的查询有什么问题吗?
  • 谢谢,我会调查一下 Scout。不是我知道的,只是纯粹的执行时间,由于我们期待更多的数据,我担心执行时间会成为一个问题。

标签: php mysql laravel


【解决方案1】:

据我所知,没有办法优化这个查询。如果您有 '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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多