我想从点生成三角形并在它们之间生成可选关系。并非所有的点都形成三角形,但很多都是三角形。
在初始结构中,我有一个包含以下表格的数据库:
节点(id,value)
关系(id,nodeA,nodeB,value)
三角形(id,relation1_id,relation2_id,relation3_id)
为了从节点和关系表生成三角形,我使用了以下查询:
INSERT INTO Triangles
SELECT t1.id, t2.id , t3.id,
FROM Relations t1, Relations t2, Relations t3
WHERE t1.id < t2.id AND t3.id > t1.id AND
(
t1.nodeA = t2.nodeA
AND (t3.nodeA = t1.nodeB AND t3.nodeB = t2.nodeB
OR t3.nodeA = t2.nodeB AND t3.nodeB = t1.nodeB)
OR
t1.nodeA = t2.nodeB
AND (t3.nodeA = t1.nodeB AND t3.nodeB = t2.nodeA
OR t3.nodeA = t2.nodeA AND t3.nodeB = t1.nodeB)
)
它完美适用于小型数据。 (〜&lt; 50分) 然而,在某些情况下,我有大约100分,彼此相关,导致成千上万的关系。因此,当预期的三角形数量达到数十万甚至数百万时,查询可能需要几个小时。
我的主要问题不在于选择查询,而我看到它在Management Studio中执行,返回的结果很慢。我每分钟收到大约2000行,这对我来说是不可接受的。
事实上,操作的大小正在加强指数,这对性能造成了极大的影响。
我已经尝试过将其作为LINQ从我的代码中反对,但性能更差。
我也尝试在C#的读卡器上使用SqlBulkCopy来获得结果,也没有运气。
所以问题是......任何想法或解决方法?
答案 0 :(得分:2)
我想你只需要这个:
INSERT
INTO triangles (relation1_id, relation2_id, relation3_id)
SELECT r12.id, r23.id, r13.id
FROM relations r12
JOIN relations r23
ON r23.nodeA = r12.nodeB
JOIN relations r13
ON r13.nodeA = r12.nodeA
AND r13.nodeB = r23.nodeB
ON r12.nodeA = n1.id
WHERE NOT EXISTS
(
SELECT relation1_id, relation2_id, relation3_id
FROM triangles
INTERSECT
SELECT r12.id, r23.id, r13.id
)
进行以下检查约束:
ALTER TABLE relations ADD CONSTRAINT CHECK (nodeA < nodeB)
这一点是因为relations
是对称的,你只需要每对存储一次关系,每个排列存储一次三角形。
检查约束确保按固定顺序每对存储一次关系。
设计查询使得三角形也以固定顺序存储:1 - 3首先,2 - 3秒,1 - 3,第三,其中1,2和3由关系链接的节点的顺序确定。
另请注意,三角形的数量增长为O(n^3)
,而非指数式增长(O(exp(N))
)。
对于100
个节点,最多可以有100 * 99 * 98 / 6 = 161700
个三角形。
答案 1 :(得分:1)
您使用的查询存在一些问题:
Quassnoi的解决方案看起来很有希望。它也有问题。首先,它是将节点ID而不是关系ID选择为三角形。其次,不检查n1和n3之间的关系是否存在。我将声明重写为:
INSERT
INTO triangles (relation1_id, relation2_id, relation3_id)
SELECT r12.id, r23.id, r13.id
FROM relations r12
JOIN relations r23
ON r12.nodeB = r23.nodeA
JOIN relations r13
ON r12.nodeA = r13.nodeA AND r23.nodeB = r13.nodeB
WHERE NOT EXISTS
(
SELECT relation1_id, relation2_id, relation3_id
FROM triangles
WHERE relation1_id = r12.id AND relation2_id = r23.id AND relation3_id = r13.id
)
此解决方案不依赖于关系表中ID排序的任何约束,也不保证三角形表中任何ID顺序。