mysql - 以复合主键顺序处理记录 block

标签 mysql sql

我正在使用 mysql 并想处理一个非常大的表,该表的主键包含 4 个部分,每 block 10,000 个(将数据编码到另一个系统)。当我进行处理时数据库处于离线状态,因此我不必担心任何修改。假设主键是 (A, B, C, D) 都是整数。我首先尝试使用 LIMIT OFFSET 来实现这一点:

SELECT * FROM LargeTable ORDER BY (A, B, C, D) LIMIT 10000 OFFSET 0;

我在每次调用时将偏移量增加 10000。当它到达表中较高的行时,这似乎变得非常缓慢。不可能有效地执行此LIMIT OFFSET吗?

然后我尝试了一种不同的方法,即在复合主键上使用比较。我可以这样得到第一个 block :

SELECT * FROM LargeTable ORDER BY (A, B, C, D) LIMIT 10000;

如果该 block 的最后一行有 A = aB = bC = cD = d 然后我可以获得下一个 block :

SELECT * FROM LargeTable
WHERE
    A > a OR
    (A = a AND B > b) OR
    (A = a AND B = b AND C > c) OR
    (A = a AND B = b AND C = c AND D > d)
ORDER BY (A, B, C, D) LIMIT 10000;

然后对每个 block 重复该操作。当我到达表中较高的行时,这似乎也大大减慢了速度。有一个更好的方法吗?我是否遗漏了一些明显的东西?

最佳答案

从一开始就使用简单的方式处理数据

SELECT *
FROM LargeTable
ORDER BY (A, B, C, D)

并在您的客户端代码中逐行获取。如果需要,您可以在获取循环中获取 10000 行,或者添加 LIMIT 10000 子句。当你想停止这个 block 时,记住最后一个被处理的元组 (A, B, C, D),我们称之为 (A1, B1, C1, D1)

现在,当您想从最后一点重新开始时,再次逐行获取行,但这次在 WHERE 子句中使用元组比较:

SELECT *
FROM LargeTable
WHERE (A, B, C, D) > (A1, B1, C1, D1)
ORDER BY (A, B, C, D)

(如果您不想依赖客户端代码过早退出获取循环,您还可以添加 LIMIT 10000 子句)。 这个解决方案的关键是 MySQL 正确地实现了元组比较。

编辑:提到可以添加可选的LIMIT 10000

关于mysql - 以复合主键顺序处理记录 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13213265/

相关文章:

mysql - 什么时候使用关系数据库结构?

java - MySQL Connector/J - 将 Java 字符串映射到 MySQL INT

PHP mysql_num_rows() 在 INNER JOIN 查询中的用法

mysql - 更新非键索引列时 INSERT 或 UPDATE MySQL?

php - Yii 框架 : No Database selected

mysql - 如何连接多个表,确保将较小的表扩展到较大的表

mysql - 如何在两个表之间找到合适的用户

sql - SQL Server Compact Edition 中的子查询

c# - 如何在 lambda 中执行 sql 连接?

php - 使用 php 将动态 LI 发送到 mySQL 表中