查询朋友和朋友的朋友优化

时间:2015-03-30 00:31:03

标签: php mysql algorithm laravel optimization

我需要运行一个查询,以便在数据透视表上获取所有朋友ID和他们朋友的ID。

该表有两列(与此问题相关),请求者ID和接受者ID。

要抓住用户的所有朋友,我必须获取accepter_id == currentUserIdrequester_id == currentUserId所有行,因为当前用户可以是请求者或接受者。

问题:

要获取朋友ID的所有朋友,我需要针对当前每个用户朋友的ID(accepter_id == currentUsersFriendIdrequester_id == currentUsersFriendId)进行查询。

很多时候,查询量超过200(取决于当前用户的朋友的数量)。当我对它进行基准测试时,我总是在2.2秒到2.7秒之间完成朋友的朋友和朋友。显然这需要太长时间。

问题:

如何才能减少完成此查询所需的时间?

注意:我正在使用Laravel的Eloquent ORM。

更新

对于表格,我正在使用Laravel Schema构建器(我不是sql专家)。所以我能告诉你的是create table语句的php代码表示。以下是Schema构建器的Laravel文档:http://laravel.com/docs/4.2/schema。希望这有用吗?

Schema::create('friends', function (Blueprint $table)
    {
        $table->increments('id');
        $table->integer('requester_id', false, true);
        $table->integer('accepter_id', false, true);
        $table->tinyInteger('status');

        $table->unique(['requester_id', 'accepter_id']);

        $table->timestamps();
        $table->softDeletes();
    });

以下是抓取朋友的select语句。请注意,我正在为where requester_id = userIdwhere accepter_id = userId运行单独的查询。无法弄清楚如何将两者结合在一起,所以我运行了单独的查询并将它们组合在一起。

select `requester_id` from `friends` where `accepter_id` = ? and `status` = ?
select `accepter_id` from `friends` where `requester_id` = ? and `status` = ?

1 个答案:

答案 0 :(得分:1)

您需要两个单独的复合索引:

INDEX(requester_id, status, accepter_id)
INDEX(accepter_id, status, requester_id)

然后这个UNION运行得更快:

( select `requester_id` from `friends` where `accepter_id` = ? and `status` = ? )
UNION ALL
( select `accepter_id` from `friends` where `requester_id` = ? and `status` = ? )

如果从那两个SELECT返回重复项,并且您需要对列表进行重复数据删除,则使用UNION DISTINCT而不是UNION ALL