我需要一种有效的方法来将“ JOIN” SQL查询的结果切成固态块进行并发处理。
此查询中有两个表,我将它们称为C和P。
C包含以下字段: C_CID,C_f1,C_f2
P包含以下字段: P_CID,P_Cat,P_Order,P_f3,P_f4
这个想法是P元素是C元素的一部分。
第一个查询如下:
SELECT P_CID, C_f1, C_f2, P_Cat, P_Order, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
非常简单。 现在要使用此查询的结果,我只需要逐行检查我是否仍使用相同的C_CID,所以没什么大不了的,但这很慢www。
然后我从我经常使用的db mgmnt GUI的行为中猜测会出现OFFSET和FETCH之类的东西,瞧瞧它们在这里,等着我使用它们,所以这里一切都很好,我尝试第二次查询
基本上是相同的,最后添加了“ OFFSET%d ROWS FETCH NEXT%d ROWS ONLY”,我随处移动了一些代码以适应更改:每个线程都有其数据库访问权限,并且读取了结果部分稍后介绍,但是我可以直接使用数据库中的数据,并且必须在构建查询后通过添加所需的行数来更新偏移量,即在X全新线程中使用的互斥锁中。
我决定按块大约一百行(总连接大小为Xe ^ 6)和8个线程,这是因为按播放,然后由于速度提高而立即融化。
然后我检查结果,哦,男孩。
基本上,由于我随意地将表切成一堆,由多个P组成的C元素在一个块的末尾出现,而在下一个开始时又出现了一些,所以aaand的东西被压碎了,现在丢失了,空气开始闻到我的失败。
我抬起头,了解有关TOP(x)WITH TIES。它的作用是在块的末尾,如果最后一个元素和下一个元素由ORDER BY子句中的列绑定,则会将其添加到块中(递归地)。
“看起来不错,”我想。 “现在如何在偏移量上使用它?”
所以我仔细研究一下,看起来更多东西(31510742),然后想到:
WITH TEMP AS
(SELECT P_CID, P_Cat, P_Order, C_f1, C_f2, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
OFFSET %d ROWS)
SELECT * FROM
(SELECT TOP %d WITH TIES *
FROM TEMP
ORDER BY P_CID)
AS TEMP2
ORDER BY P_CID, P_Cat, P_Order
(我知道SELECT * FROM(SELECT)看起来很糟,但是我需要完整的ORDER BY子句,而没有使TOP WITH TIES过于具体)。
它不起作用。
快速思考,我意识到我仍然将偏移量更新为静态量。
现在我必须在退出互斥对象之前再做COUNT(*)个操作,但是,我有很多线程全速工作,所以仍然是一个胜利,对吧?
对..
它变得如此之慢。
事实证明,具有OFFSET的SELECT仍会选择表中剩余的所有内容。因此,虽然我从没看到过它会临时加载我在此查询结果中不会使用的一排行。
更快速的思考,我有一个新查询:
WITH TEMP AS
(SELECT P_CID, P_Cat, P_Order, C_f1, C_f2, P_f3, P_f4
FROM C JOIN P ON C_CID = P_CID
ORDER BY P_CID, P_Cat, P_Order
OFFSET %d ROWS
FETCH NEXT %d + %d ROWS ONLY)
SELECT * FROM
(SELECT TOP %d WITH TIES *
FROM TEMP
ORDER BY P_CID)
AS TEMP2
ORDER BY P_CID, P_Cat, P_Order
可以执行奇迹。 第一个新的%d的值与TOP的值相同,第二个是附加到同一C元素的P元素的最大数量(在单行查询执行开始时计算)减去一个。如果您不理解为什么,请在纸上画出最坏的情况:最老板的C元素就从一个块的末尾开始。在我的C和P上都是20,我知道它不会再那么大了,所以这样做实际上是有效的。
现在有很多东西可以一起工作,必须工作,对吗?
确实如此。但这很丑。而且有太多事情需要跟踪。当我需要另一个字段(我想要的*,该死的*)时,要适应就很困难了。而且我只知道有一种更简单的方法可以做到这一点。
请告诉我怎么做。
答案 0 :(得分:0)
您知道它很愚蠢,但是再读一遍,我真的可以选择“ SELECT TOP(x)WITH TIES ORDER BY P_CID ASC”,然后围绕ORDER BY进行另一次SELECT(P_CID DESC),得到第一个P_CID值(实际上是最后一个),然后执行下一个“ SELECT TOP(X)WITH TIES ORDER BY P_CID ASC”,并添加“ WHERE P_CID>%d”子句,%d是到那时为止读取的最高CID。>
什么都不会刮墙,我可以在第二个SELECT中添加我的附加ORDER BY列,以便TOP WITH TIES看不到它们,有0个未使用的行被提取,并且周围的代码更易于制作。 / p>
Imma试试。