查询好友和好友的好友优化


Querying for friends and friends of friends optimization

我需要运行一个查询,以获取数据透视表上的所有好友ID及其好友ID。

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

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

问题是:

要获取朋友的所有好友ID,我需要为每个当前用户的好友ID运行一个查询(其中accepter_id == currentUsersFriendId和其中requester_id == currentUsersFriendId)。

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

问题是:

我可以做些什么来减少完成此查询所需的时间?

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

更新

对于该表,我使用的是Laravel Schema构建器(我不是sql专家)。因此,我可以向您展示的是createtable语句的php代码表示。以下是架构生成器的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();
    });

以下是吸引朋友的精选语句。请注意,我正在为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` = ?

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

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