大家好
我有一个奇怪的查询。假设我有一个包含复合主键(2列)的表。
CREATE TABLE `testtable` (
`ifk1` INT(10) NOT NULL,
`ifk2` INT(10) NOT NULL,
`data1` VARCHAR(10) DEFAULT NULL,
PRIMARY KEY (`ifk1`,`ifk2`),
UNIQUE KEY `keyName` (`data1`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4
让我们添加一些基本数据
INSERT INTO testtable(ifk1 , ifk2 , data1)
VALUES (1 , 2 , 'a') , (5 , 2 , 'b') , (2 , 4 , 'c') , (5 , 8 , 'd') , (2 , 2 , 'e') , (2 , 5 , 'f');
让我们执行一个简单的SELECT来查看数据的输出顺序:
ifk1 ifk2 data1
1 2 a
2 2 e
2 4 c
2 5 f
5 2 b
5 8 d
现在,如果我想编写一些代码来遍历表,一次获取X条记录,该怎么办?对于一个小的数据集,这很简单:
SELECT * FROM testtable LIMIT 0 , 2;
SELECT * FROM testtable LIMIT 2 , 2;
SELECT * FROM testtable LIMIT 4 , 2;
当表变得更大时,这将遇到一些问题,因为它没有使用WHERE子句,因此也没有使用INDEX。我如何使用WHERE子句来复制上面的SELECTS?
SELECT * FROM testtable WHERE ifk1 > 0 AND ifk2 > 0 LIMIT 2; -- this will work
第一个很容易,但其他的呢?有没有办法做到这一点?
3条答案
按热度按时间pbossiut1#
没有
ORDER BY
子句的LIMIT
子句是任意的。您显示的所有三个查询:可以返回完全相同的两行。因此,您必须添加一个
ORDER BY
子句以使其可靠地工作:ORDER BY ifk1, ifk2
.但是,是的,每次访问都要一次又一次地对数据进行排序,这会花费很多时间,这就是为什么我们尽量避免使用偏移量,而是使用键:
分页几乎总是很慢。但是这种访问方法可以使用主键的唯一索引(ifk1,ifk2),并且可以非常快地访问接下来的两行。这取决于MySQL的实现和它的版本。
rjee0c152#
我不确定我是否理解了你的问题中的索引部分。但是一般来说,如果你想迭代一个更大的结果集,你可以使用游标,如下所述:
https://www.mysqltutorial.org/mysql-cursor/
这将用于存储过程,但其他语言的数据库驱动程序将公开类似的功能。
jv2fixgn3#
如果您的请求是使用索引:逻辑是一样的:
以上使用KeyName索引:也许您应该停用或删除KeyName索引,并启用查询以使用PK复合索引:请按照以下步骤操作:
DROP keyName索引第一:
然后再次运行查询,查看查询中是否使用了PK组合键,我认为这会使查询更快: