在我的项目中,我经常需要将SELECT的结果存储在另一个表中(我们称之为“结果集”)。原因是在Web应用程序中动态显示大量行,同时根据需要只加载小块。如何在另一个表中存储* sorted * SELECT结果?
典型地,这是通过查询完成象这样的:
SET @counter := 0;
INSERT INTO resultsetdata
SELECT "12345", @counter:[email protected]+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;
这通常就像一个魅力,但最近我们注意到,在一些案件结果的顺序不正确。这取决于查询本身(例如,,例如,添加DISTINCT
是典型原因),服务器版本和源表中包含的数据,所以我猜可以这样说,行顺序是不可预测的与此方法。可能取决于内部优化。
但是,问题现在,我想不出任何替代解决方案,给我预期的结果。
由于结果集可能会获得数千行,因此将所有数据加载到内存中,然后手动执行它是不可行的。
有什么建议吗?
编辑:为了进一步澄清,看看这些查询:
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:[email protected]+1, ID
FROM test
ORDER BY ID DESC;
这将产生以下结果为 “预期”:
+-------+----------------------+----+
| 12345 | @counter:[email protected]+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:[email protected]+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错误,我完全理解,我的方法目前提供不可预知的结果。不过,我不知道如何调整这个来获得可预测的结果。
怎样的顺序不正确的?如在最后的'身份证'没有排序你想要它是什么?你已经添加了一个计数器,你的意思是计数器没有正确分类?你如何选择,在柜台上排序?无论如何,总的来说,这整个事情感觉有点像手动实现的缓存系统。你确定你甚至需要这种方法吗?难道你不能更快地将结果保存到某种真正的缓存系统中,或者更新'sometable'和'bigtable',这样不需要很多秒钟? – Nanne 2013-04-10 08:41:35
你能提供正确的'ORDER'ed结果和错误的ORDER'ed一个吗?而你的'SELECT'只是确定的。 – 2013-04-10 08:45:55
我的意思是,在某些情况下,当在控制台上执行不带'INSERT INTO'的'SELECT'时,会看到'ContIdx'按**递减顺序。是的,这与缓存系统有些相关*,但我不认为将大量数据加载到内存(?)是更好的解决方案。这个问题适用于包含大量获取数据的各种查询/表格,所以我无法进一步优化SELECT查询(即,当用户浏览数据时,我无法一次又一次地进行查询)。此外,我需要somthing * static *,因为表格会连续填充数据。 – 2013-04-10 08:49:51