ZA.*_*ZA. 25 mysql performance limit
在使用大偏移LIMIT的mysql 时遇到性能问题SELECT:
SELECT * FROM table LIMIT m, n;
Run Code Online (Sandbox Code Playgroud)
如果偏移m量大于1,000,000,则操作非常慢.
我必须使用limit m, n; 我不能用类似的东西id > 1,000,000 limit n.
如何优化此声明以获得更好的性能?
Pau*_*xon 13
也许您可以创建一个索引表,该表提供与目标表中的键相关的顺序键.然后,您可以将此索引表连接到目标表,并使用where子句更有效地获取所需的行.
#create table to store sequences
CREATE TABLE seq (
seq_no int not null auto_increment,
id int not null,
primary key(seq_no),
unique(id)
);
#create the sequence
TRUNCATE seq;
INSERT INTO seq (id) SELECT id FROM mytable ORDER BY id;
#now get 1000 rows from offset 1000000
SELECT mytable.*
FROM mytable
INNER JOIN seq USING(id)
WHERE seq.seq_no BETWEEN 1000000 AND 1000999;
Run Code Online (Sandbox Code Playgroud)
互联网上有一篇博客文章,说明如何最好地选择要显示的行应该尽可能紧凑,因此:只有ids; 然后生成完整的结果应该只为您选择的行获取所需的所有数据.
因此,SQL可能是这样的(未经测试,我不确定它实际上会做什么好事):
select A.* from table A
inner join (select id from table order by whatever limit m, n) B
on A.id = B.id
order by A.whatever
Run Code Online (Sandbox Code Playgroud)
如果你的SQL引擎太原始而不允许这种SQL语句,或者它没有改进任何东西,而不是希望,那么将这个单个语句分解为多个语句并将id捕获到数据结构中可能是值得的.
更新:我找到了我正在谈论的博客文章:这是关于编码恐怖的杰夫阿特伍德的"所有抽象都是失败的抽象".
小智 5
如果记录很大,则缓慢可能来自加载数据.如果id列被索引,那么只选择它会快得多.然后,您可以使用IN子句为相应的id执行第二次查询(或者可以使用第一个查询中的min和max id来表示WHERE子句.)
慢:
SELECT * FROM table ORDER BY id DESC LIMIT 10 OFFSET 50000
Run Code Online (Sandbox Code Playgroud)
快速:
SELECT id FROM table ORDER BY id DESC LIMIT 10 OFFSET 50000
SELECT * FROM table WHERE id IN (1,2,3...10)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23843 次 |
| 最近记录: |