如何在 MySQL 中从 60 万行数据中快速随机抽取 10 行?

从数据库中同时随机选择行是 SQL 中的一项常见任务,尤其是在处理大型数据集时。选择多行对于数据采样或生成用于分析的随机子集非常有用。在 MySQL 中,我们可以通过多种方法来实现这一目标,每种方法都有其优势。

在本文中,我们将探索在 MySQL 中从 60 万行数据集中检索 10 行随机记录的三种方法。我们将介绍它们的语法、示例和解释,帮助您深入了解如何高效地随机选择行。

在 MySQL 中从 60 万行数据中检索 10 个随机行

RAND() 函数是 SQL 中的一种函数,它帮助我们从表的现有数据中选择多行。让我们探讨一些选择多行的常用方法。常见的方法如下:

  • 使用 RAND() 函数
  • 使用主键进行随机选择
  • 结合用户变量进行随机采样

设置环境

我们可以使用以下代码创建 Employee 表,该代码定义了包含 ‘empId‘、‘name‘ 和 ‘dept‘ 列的表结构。

创建 EMPLOYEE 表的查询:

CREATE TABLE EMPLOYEE (
  empId INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  dept TEXT NOT NULL
);

向 EMPLOYEE 表中插入数据:

INSERT INTO EMPLOYEE VALUES (1, ‘Clark‘, ‘Sales‘);
INSERT INTO EMPLOYEE VALUES (2, ‘Dave‘, ‘Accounting‘);
INSERT INTO EMPLOYEE VALUES (3, ‘Ava‘, ‘Marketing‘);
INSERT INTO EMPLOYEE VALUES (4, ‘GFG‘, ‘Development‘);
INSERT INTO EMPLOYEE VALUES (5, ‘Adam‘, ‘Testing‘);
INSERT INTO EMPLOYEE VALUES (6, ‘Evan‘, ‘Operations‘);
INSERT INTO EMPLOYEE VALUES (7, ‘Avanya‘, ‘Accounting‘);
INSERT INTO EMPLOYEE VALUES (8, ‘Ziv‘, ‘Sales‘);
INSERT INTO EMPLOYEE VALUES (9, ‘Gia‘, ‘Development‘);
INSERT INTO EMPLOYEE VALUES (10, ‘Ele‘, ‘Testing‘);
INSERT INTO EMPLOYEE VALUES (11, ‘Jonas‘, ‘Operations‘);
INSERT INTO EMPLOYEE VALUES (12, ‘Hany‘, ‘Accounting‘);
INSERT INTO EMPLOYEE VALUES (13, ‘Sam‘, ‘Sales‘);

输出:

!employeeEmployee Table

1. 使用 RAND() 函数

选择随机行最简单、最直接的方法就是使用 RAND() 函数。该函数为每一行生成一个 0 到 1 之间的随机浮点值,允许我们对结果进行排序并限制选择数量。

语法:

> SELECT * FROM Table name

>

>

>

> ORDER BY RAND()

>

>

>

> LIMIT 10;

示例:为 Employee 表使用 RAND()

查询:

SELECT * FROM Employee
ORDER BY RAND()
LIMIT 10;

该查询从 EMPLOYEE 表中选择 10 个随机行。ORDER BY RAND() 子句使行顺序随机化,而 LIMIT 10 子句将输出限制为 10 行。

输出:

!Using RAND() function使用 RAND() 函数

解释:SQL 查询从 Employee 表 中选择 10 个随机行,并按随机顺序排列。输出显示了这 10 行数据的随机排列结果。

2. 使用主键进行随机选择

如果表具有数值主键且间隙相对较少,我们可以利用它来实现更高效的随机选择。

语法:

> SELECT * FROM Table Name

>

>

>

> WHERE columnname >= (SELECT FLOOR(MAX(columnname) * RAND()) FROM Employee)

>

>

>

> ORDER BY column_name

>

>

>

> LIMIT 10;

示例:为 Employee 表使用主键

查询:

SELECT * FROM Employee
WHERE empId >= (SELECT FLOOR(MAX(empId) * RAND()) FROM Employee)
ORDER BY empId
LIMIT 10;

该查询基于 主键 随机选择一个起始点,并检索接下来的 10 行。

输出:

!2使用主键

解释: 该 SQL 查询通过设置一个最小 empId 值(该值等于表中最大 empId 和 0 之间随机生成的一个数)来从 Employee 表中选择 10 个随机行。然后,它按 empId 对选定的行进行排序。

3. 结合用户变量进行随机采样

为了对随机性进行更多控制,特别是在大型数据集中,我们可以使用用户变量为每一行分配一个随机数,然后基于这些数字进行选择。

语法:

> SET @row_number = 0;

>

>

>

> SELECT *

>

>

>

> FROM (

>

>

>

> SELECT *, (@rownumber:=@rownumber + 1) AS num

>

>

>

> FROM Table Name

>

>

>

> ORDER BY RAND()

>

>

>

> ) AS t

>

>

>

> WHERE num % (SELECT ROUND(COUNT(*) / 10) FROM Table Name) = 0

>

>

>

> LIMIT 10;

示例:为 Employee 表使用随机采样

查询:

SET @row_number = 0;
SELECT *
FROM (
    SELECT *, (@row_number:=@row_number + 1) AS num
    FROM Employee
    ORDER BY RAND()
) AS t
WHERE num % (SELECT ROUND(COUNT(*) / 10) FROM Employee) = 0
LIMIT 10;

解释:

  • INLINECODEca345c8f:首先初始化一个用户变量 INLINECODE028954ba 为 0。
  • 内层查询:从 INLINECODEb14ca7fd 表中选择所有数据,使用 INLINECODEb97821ab 对数据进行随机排序,并利用变量 INLINECODE2012fc2e 为每一行生成一个递增的序号 INLINECODE3507cdb3。
  • 外层查询:从内层查询的结果中筛选数据。num % (SELECT ROUND(COUNT(*) / 10) FROM Employee) = 0 这一条件通过取模运算,试图以近似均匀的间隔从随机排序后的数据中抽取行。
  • LIMIT 10:最终只返回 10 行数据。

这种方法结合了变量的顺序控制和随机排序,旨在提供一种不同于直接排序取前 N 行的随机采样思路。

结论

在本文中,我们探讨了三种不同的方法,用于从大型 MySQL 数据集中随机选择 10 个行。每种方法都有其适用场景:

  • 使用 RAND() 函数:最简单直接,适合中小规模数据表。在数据量极大(如 60 万行)时,由于需要对全表进行排序,可能会导致性能下降。
  • 使用主键进行随机选择:如果主键是连续的数字且分布均匀,这种方法效率较高。它避免了全表排序,而是通过计算随机起始点来选取数据,但需要主键列建立索引。
  • 结合用户变量进行随机采样:提供了更灵活的控制,通过随机打乱顺序并结合取模算法进行采样。这种方法逻辑较复杂,但在某些特定场景下(如需要特定的采样间隔)可能有用。

选择哪种方法取决于具体的表结构、数据量大小以及对性能的要求。通过理解这些方法的内部机制,我们可以做出更明智的决策,以优化数据库查询性能。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/43524.html
点赞
0.00 平均评分 (0% 分数) - 0