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
fromprospects
wherechannel_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 byid
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 byid
desc limit 100 offset 0
然后需要 0.0284 秒
channel_id
是 channels
表的 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_id
和id
上使用复合索引
你有多少条记录?
嗨,我更新了问题。我有大约 700 万条记录。
为了帮助您解决query-optimization 的问题,我们需要更多信息。请read this,然后edit您的问题。
【参考方案1】:
INDEX(channel_id, -- because of WHERE channel_id = constant
id) -- because of ORDER BY id
在this 查询中,索引可用于WHERE
和ORDER BY
。但是,如果你有,比如OFFSET 234000
,它必须扫描 234000+100 行才能得到结果;也就是说,OFFSET
很大时可能会成为性能杀手。
您真的希望用户翻阅 170 万行吗?
【讨论】:
以上是关于Laravel MySQL 按 ID Desc 查询顺序很慢的主要内容,如果未能解决你的问题,请参考以下文章