gpt4 book ai didi

mysql - 如何将 *sorted* SELECT 结果存储在另一个表中?

转载 作者:行者123 更新时间:2023-11-29 04:48:00 25 4
gpt4 key购买 nike

在我的项目中,我经常需要将 SELECT 的结果存储在另一个表中(我们称之为“结果集”)。原因是在 Web 应用程序中动态显示大量行,同时根据需要仅加载小块。

通常,这是通过如下查询完成的:

SET @counter := 0;
INSERT INTO resultsetdata
SELECT "12345", @counter:=@counter+1, a.ID
FROM sometable a
JOIN bigtable b
WHERE (a.foo = b.bar)
ORDER BY a.whatever DESC;

固定的 "12345" 值只是一个将“结果集”标识为一个整体并随每个查询而变化的值。第二列是递增索引计数器,旨在允许直接访问结果中的特定行,ID 列引用源数据表中的特定行。

当应用程序需要一定范围的结果时,我只需将 resultsetdata 与源表连接起来即可获取详细数据 - 这与 resultsetdata 查询相比更快以上可能需要 2-3 秒才能完成(这解释了为什么我需要这个中间表)。

SELECT 查询本身与这个问题无关。

resultsetdata 具有以下结构:

CREATE TABLE `resultsetdata` (
`ID` int(11) NOT NULL,
`ContIdx` int(11) NOT NULL,
`Value` int(11) NOT NULL,
PRIMARY KEY (`ID`,`ContIdx`)
) ENGINE=InnoDB;

这通常很有效,但最近我们注意到在某些 情况下结果的 ORDER 不正确。这取决于查询本身(例如,添加 DISTINCT 是一个典型原因)、服务器版本和源表中包含的数据,所以我想可以说使用此方法行顺序是不可预测的。可能这取决于内部优化。

但是,问题现在是我想不出任何替代解决方案来提供我预期的结果。

由于结果集可能有数千行,将所有数据加载到内存中然后手动INSERTing 是不可行的。

有什么建议吗?


编辑:要进一步说明,请查看这些查询:

DROP TABLE IF EXISTS test;
CREATE TABLE test (ID INT NOT NULL, PRIMARY KEY(ID)) ENGINE=InnoDB;
INSERT INTO test (ID) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

SET @counter:=0;
SELECT "12345", @counter:=@counter+1, ID
FROM test
ORDER BY ID DESC;

这会产生以下“预期”结果:

+-------+----------------------+----+
| 12345 | @counter:=@counter+1 | ID |
+-------+----------------------+----+
| 12345 | 1 | 10 |
| 12345 | 2 | 9 |
| 12345 | 3 | 8 |
| 12345 | 4 | 7 |
| 12345 | 5 | 6 |
| 12345 | 6 | 5 |
| 12345 | 7 | 4 |
| 12345 | 8 | 3 |
| 12345 | 9 | 2 |
| 12345 | 10 | 1 |
+-------+----------------------+----+
10 rows in set (0.00 sec)

如前所述,在某些情况下(抱歉,我无法在此处提供测试用例),这可能会导致类似于以下的结果:

+-------+----------------------+----+
| 12345 | @counter:=@counter+1 | ID |
+-------+----------------------+----+
| 12345 | 10 | 10 |
| 12345 | 9 | 9 |
| 12345 | 8 | 8 |
| 12345 | 7 | 7 |
| 12345 | 6 | 6 |
| 12345 | 5 | 5 |
| 12345 | 4 | 4 |
| 12345 | 3 | 3 |
| 12345 | 2 | 2 |
| 12345 | 1 | 1 |
+-------+----------------------+----+

我并不是说这是一个 MySQL 错误,我完全理解我的方法目前会提供不可预测的结果。不过,我不知道如何调整它以获得可预测的结果。

最佳答案

这是因为插入记录时的排序顺序与检索它们时的顺序无关。

当您检索它们时,将创建一个查询计划。如果您的 SELECT 语句中没有指定 ORDER BY,那么顺序将取决于生成的查询计划。这就是为什么它是不可预测的,添加 DISTINCT 可以改变顺序。

解决方案是存储足够的数据,以便您可以使用 ORDER BY 子句以正确的顺序检索它们。在您的情况下,您已经通过 a.whatever 订购了您的数据。 a.whatever 可以存储在 resultsetdata 中吗?如果是这样,那么您可以按正确的顺序读出记录。

关于mysql - 如何将 *sorted* SELECT 结果存储在另一个表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15920829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com