这似乎是一个非常常见的问题,但并没有得到解决所有的情况。
我在mysql中搜索了很多优化分页查询的文章,发现seek方法是最好的解决方案。
但在seek方法的每个例子中,我都发现order by子句位于数字或日期类型字段上,如果我们是按varchar类型列(例如:first\u name)排序,它可能也包含空值和空值,我尝试了(first\u name,id)<(null,15)和(first\u name,id)<('',15),这两个列显示了不确定的结果。
请建议我们如何处理这些案件也寻求方法。
3条答案
按热度按时间vsaztqbk1#
使用哪种类型的列对行进行排序并不重要,只要它们可以被数据库“排序”。这包括几乎所有的数字、varchar、日期/时间等。
常见的例外是重数据字段,例如
BLOB
,CLOB
,BINARY
此列表非常特定于数据库,因此请检查哪些数据类型可以参与ORDER BY
在你的数据库里。另外,请注意,要正确使用seek方法,用于排序的列列表必须生成唯一键。否则,分页可能会“搞笑”。
piok6c0g2#
是漂亮的语法,但性能糟糕!优化器不知道如何使用任何索引来帮助处理这些问题。你必须把它变成一个综合体
AND
以及OR
表情。你一定有INDEX(first_name, id)
按这个顺序。至于表达方式等,这里详细说明。
ps,不要使用
first_name < NULL
;NULL
与任何事物相比FALSE
. 例如:(和
NULL
工作方式FALSE
在实验室测试时WHERE
.)qxgroojn3#
除了null的用法之外,还有一个问题还没有得到任何答案。
你不能在mysql中使用这种语法。示例:(名字,id)<('alex',15)
这称为“行值”语法。即使不使用null并给出适当的值,mysql也能理解它,但不能以适当的方式使用index来生成所需的排序顺序,因此无法看到预期的结果。
尽管行值语法是sql标准的一部分,但只有少数数据库支持它。sql server 2017完全不支持行值。oracle数据库原则上支持行值,但不能对其应用范围运算符(ora-01796)。mysql正确计算行值表达式,但在索引访问期间不能将其用作访问 predicate 。然而,db2(从10.1开始只有luw)和postgresql(从8.4开始)对行值 predicate 有适当的支持,如果有相应的索引可用,就使用它们来访问索引。
这方面的好资源:https://use-the-index-luke.com/sql/partial-results/fetch-next-page