Laravel MySQL 按 ID Desc 查询顺序很慢

Posted

技术标签:

【中文标题】Laravel MySQL 按 ID Desc 查询顺序很慢【英文标题】:Laravel MySQL Query Order By ID Desc Is Slow 【发布时间】:2021-10-28 09:53:22 【问题描述】:

我有一个表 prospects,它有 600 万行。

我有这样的代码sn-p,它的性能让我很生气。

 $prospects = Prospect::where('channel_id', 1)
            ->orderBy('id', 'desc')
            ->offset(0)
            ->limit(100)
            ->get();

select id from prospects where channel_id = 1 order byid desc limit 100 offset 0

需要 17.0426 秒。

    $prospects = Prospect::where('channel_id', 1)
        ->orderBy('id', 'asc')
        ->offset(0)
        ->limit(100)
        ->get();

prospects 中选择id,其中prospects.deleted_at 是 null order by id desc limit 100 offset 0

这样的版本需要 0.0262 秒(升序)

订单为DESC时如何提高性能? id 是一个PK,channel_id 我有一个索引。我还在id 上创建了一个 DESC 索引(我在某处读到两个索引:一个 ASC 和一个 desc 可能会有所帮助),但它没有。

我还注意到,如果sql中没有这样的WHERE:

    $prospects = Prospect::orderBy('id', 'desc')
        ->offset(0)
        ->limit(100)
        ->get();

prospects 中选择 *,其中 prospects.deleted_at 为空 order by id desc limit 100 offset 0

然后需要 0.0284 秒

channel_idchannels 表的 FK。我有两条记录,id 为 1 和 2。我注意到这样的

    $prospects = Prospect::where('channel_id', 2)->orderBy('id', 'desc')
        ->offset(0)
        ->limit(100)
        ->get();

查询(其中 channel_id 为 2)需要 0.0262 秒。

我有 520 万个 channel_id 为 2 的潜在客户和 170 万个 channel_id 为 1 的潜在客户。因此,以某种方式查询 channel_id = 2 比 channel_id = 1 快 100 倍。这怎么可能?行数据的大小会影响这一点吗? (因为 channel_id = 1 的潜在客户有一个 data 列,其中包含比 channel_id = 2 的潜在客户更多的数据)

【问题讨论】:

您是否尝试过在channel_idid 上使用复合索引 你有多少条记录? 嗨,我更新了问题。我有大约 700 万条记录。 为了帮助您解决query-optimization 的问题,我们需要更多信息。请read this,然后edit您的问题。 【参考方案1】:
INDEX(channel_id,    -- because of WHERE channel_id = constant
      id)            -- because of ORDER BY id

this 查询中,索引可用于WHEREORDER BY。但是,如果你有,比如OFFSET 234000,它必须扫描 234000+100 行才能得到结果;也就是说,OFFSET 很大时可能会成为性能杀手。

您真的希望用户翻阅 170 万行吗?

【讨论】:

以上是关于Laravel MySQL 按 ID Desc 查询顺序很慢的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 中的索引,用于按 DESC、BETWEEN 和几个可能的字段集进行查询

Laravel:按位置排序

Laravel 多订单按天分组查看

在laravel中按模型从数据库中获取数据时如何附加关系

MYSQL 按升序和降序排序

MYSQL 按文本排序