- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的项目中,我经常需要将 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
是一个典型原因)、服务器版本和源表中包含的数据,所以我想可以说使用此方法行顺序是不可预测的。可能这取决于内部优化。
但是,问题现在是我想不出任何替代解决方案来提供我预期的结果。
由于结果集可能有数千行,将所有数据加载到内存中然后手动INSERT
ing 是不可行的。
有什么建议吗?
编辑:要进一步说明,请查看这些查询:
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/
我是一名优秀的程序员,十分优秀!