这似乎是一个非常普遍的问题,但并未解决所有情况。
我搜索了很多文章以优化MYSQL中的分页查询,我发现Seek Method是最佳解决方案。
但是在seek方法的每个示例中,我发现在number或date类型字段上的order by子句,如果我们通过也可能包含空值和null值的varchar类型列(例如first_name)排序,该怎么办?尝试(first_name,id)<(null,15)AND(first_name,id)<('',15)显示不确定的结果。
请提出在搜索方法中我们也应如何处理这些情况。
答案 0 :(得分:1)
WHERE (first_name, id) < ('', 15)
是漂亮的语法但是性能糟透了!优化器不知道如何使用任何索引来提供帮助。您必须将其转换为复杂的AND
和OR
表达式。 并且您必须按 顺序使用INDEX(first_name, id)
。
关于表达式等,详细信息将详细说明here。
PS,请勿使用first_name < NULL
;与任何事物相比,NULL
始终是FALSE
。例如:
mysql> SELECT 'Rick' < NULL, 'Rick' > NULL, 'Rick' = NULL, 'Rick' != NULL;
+---------------+---------------+---------------+----------------+
| 'Rick' < NULL | 'Rick' > NULL | 'Rick' = NULL | 'Rick' != NULL |
+---------------+---------------+---------------+----------------+
| NULL | NULL | NULL | NULL |
+---------------+---------------+---------------+----------------+
(在NULL
中进行测试时,FALSE
的作用类似于WHERE
。)
答案 1 :(得分:0)
用于排序行的列的类型无关紧要,只要它们可以被数据库“排序”即可。这几乎包括所有数字,varchar,日期/时间等。
常见的例外是繁重的数据字段,例如BLOB
,CLOB
,BINARY
等。此列表是特定于数据库的,因此请检查哪些数据类型可以参与{ {1}}在您的数据库中。
另外,请注意,要正确使用“查找方法”,您要订购的列列表必须产生一个唯一键。否则,分页可能会“有趣”。
答案 2 :(得分:0)
除了使用NULL外,还没有任何答案指出另一个问题。
您不能在MySQL中使用该语法。 例如:(first_name,id)<('Alex',15)
这称为“行值”语法。即使您不使用NULL并提供适当的值,MySQL也会理解它,但无法以正确的方式使用索引来产生所需的排序顺序,因此您看不到预期的结果。
尽管行值语法是SQL标准的一部分,但只有少数数据库支持它。 SQL Server 2017根本不支持行值。 Oracle数据库原则上支持行值,但是不能在它们上应用范围运算符(ORA-01796)。 MySQL会正确评估行值表达式,但不能在索引访问期间将它们用作访问谓词。但是,DB2(从10.1开始只有LUW)和PostgreSQL(从8.4开始)都对行值谓词提供了适当的支持,并在有相应索引可用时使用它们来访问索引。
有关此主题的好资源:https://use-the-index-luke.com/sql/partial-results/fetch-next-page