用limt做分页时,不添加排序语句就会有问题,请问是啥原因
后续无论偏移量是多少 都会查出 limit 20,10的数据
给语句加上order by后才能正确查询

方便提供下observer的版本么
4.1.0社区版,全表查询过一次后,不加order by又能正确查询出了
我这边按提供的信息执行了一遍,以下是我测试的sql,我这边暂时没有复现,方便的话麻烦看下这个case在你那是否有复现,此外想问下你的‘id’是对应数据的主键么
select version();
use test;
drop table if exists t;
CREATE TABLE `t` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`d` INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `t` (d) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45),(46),(47),(48),(49);
select * from t;
select d from t limit 10;
select d from t limit 10,10;
select d from t limit 20,10;
select d from t limit 30,10;
我使用以上case在我这也能正确执行,id是主键。
SELECT
cr.id,
cr.application_id,
cr.product_id,
cr.item_id,
cr.quantity,
cr.unit_price,
cr.charges,
cr.charge_user,
cr.charge_time,
cr.charge_type,
cr.match_result_id,
cr.urgent_id,
cr.match_send_id,
cr.charge_his_status,
cr.charge_his_message,
cr.charge_pres_no,
cr.is_refund,
cr.match_back_id,
cr.refund_user,
cr.refund_reason,
cr.refund_time,
cr.charge_node,
api.admission_code,
bpii.NAME,
ai.CODE,
bci.item_code,
bci.item_name,
bpi.bag_code
FROM
charges_record cr
LEFT JOIN application_patient_info api ON cr.application_id = api.application_id
AND api.is_deleted = 0
LEFT JOIN application_info ai ON cr.application_id = ai.id
AND ai.is_deleted = 0
LEFT JOIN blood_product_info bpi ON cr.product_id = bpi.id
AND bpi.is_deleted = 0
LEFT JOIN base_charge_item bci ON cr.item_id = bci.id
AND bci.is_deleted = 0
LEFT JOIN base_patient_info bpii ON cr.patient_id = bpii.id
AND bpii.is_deleted = 0
WHERE
cr.is_deleted = 0
AND ai.CODE LIKE (’%2023041804%’)
AND cr.application_id = 3083357741444497465
– ORDER BY cr.id
LIMIT 30,10;
找了个32条的,最后2条又能正确分页
这边和负责同学确认下默认排序和limt的返回的具体实现
表数据存在动态变化么,是否可能是数据被推移了
盲猜一下。
分布式数据库会把查询任务分配到各个节点上去,因为每个节点查询的速度并不一样,最后在汇总结果的时候顺序可能就不一样。
如果要获得固定的结果集顺序,就需要显式的使用order by语句,这也是SQL规范里推荐的用法。
那查出来的第二页和第三页的数据咋会是一模一样呢,如果只是顺序被打乱是否每页的数据会有重复但不应该相同
我也是猜测,具体原因看官方怎么说
获取到最新的反馈是limit 是随机性的。查询完数据之后 limit 不确定是按照主键 还是以其他列为维度 所以正常情况下 都需要根据客户的需求进行order by之后再limit 。 不进行order by 和进行order by 之后的limit 肯定是不一样的。
问题在于不进行order by就无法得到正确的结果集,同样的数据在mysql中却是可以正确查询
方便提供复现场景么,这边现在没有对应的复现场景,不好定位对应的逻辑是否一致
drop table if exists t;
CREATE TABLE t
(
id
INT(11) NOT NULL AUTO_INCREMENT,
d
INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t
(d) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45),(46),(47),(48),(49);
CREATE TABLE t1
(
id
INT(11) NOT NULL AUTO_INCREMENT,
d
INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t1
(d) VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
SELECT t1.* FROM t1 LEFT JOIN t ON t.id = t1.d;
SELECT t1.* FROM t1 LEFT JOIN t ON t.id = t1.d limit 10;
SELECT t1.* FROM t1 LEFT JOIN t ON t.id = t1.d limit 10,10;
SELECT t1.* FROM t1 LEFT JOIN t ON t.id = t1.d limit 20,10;
SELECT t1.* FROM t1 LEFT JOIN t ON t.id = t1.d limit 30,10;
我这边的查询结果如下:
我这边复现了,也对应验证了mysql下的场景,这边推给负责同学界定下是否符合设计
没有深测,我中午的时候好像还发现没有加order by的sql语句在不同时间查询,排序方式都不一样
稍微等下,正在反馈