如何编写更优化和简单的查询 - 父子关系?

时间:2017-07-12 20:57:08

标签: sql sql-server sqlperformance

我有一张医疗数据表,它有关系(类似于父母和孩子)。 为简单起见,我考虑了一个具有实际父子关系的表。 以下是表格:

表名:关系

Parent | Child
------ | ------
Mike   |John
Aliss  |John
John   |Chris
Brad   |David
Kate   |Brad
Alexa  |Shawn
Matt   |Thoa 

我已经编写了查询,让我获得了GrandParent,Parent和Grandchild的关系。

SELECT t1.grandchild, 
       t2.grandparent,
       t1.parent,
       t2.child
FROM   (SELECT child AS Grandchild, 
               parent 
        FROM   relations 
        WHERE  parent IN (SELECT DISTINCT( r.parent ) 
                          FROM   relations r 
                                 JOIN relations t 
                                   ON r.parent = t.child)) AS t1 
       INNER JOIN (SELECT parent AS Grandparent, 
                          child 
                   FROM   relations 
                   WHERE  child IN (SELECT DISTINCT( r.parent ) 
                                     FROM   relations r 
                                            JOIN relations t 
                                              ON r.parent = t.child)) AS t2 
               ON t1.parent = t2.child 
ORDER  BY t1.grandchild; 

这是捕获,现在实际数据有30015924行,当我使用上面的查询运行报告时,需要永远获取数据。

我看到了执行计划,并且有许多"嵌套循环"和懒惰的线轴。 我正在尝试编写一个更有效的查询,它可以更快地在大型数据集上执行。

联盟对于单独的关系是否有效。 这是我写的最有效的查询还是有更好的版本?

谢谢。

2 个答案:

答案 0 :(得分:0)

我经常发现,使用联合会比使用嵌套的派生查询大大加快查询时间。

答案 1 :(得分:0)

这是一个更简单(可能更好的性能)查询,以获得完全相同的结果:

首先,创建并填充样本数据(在将来的问题中保存此步骤):

CREATE TABLE relations
(
    Parent varchar(10),
    Child varchar(10)
)

INSERT INTO relations VALUES

('Mike', 'John'),
('Aliss', 'John'),
('John', 'Chris'),
('Brad', 'David'),
('Kate', 'Brad'),
('Alexa', 'Shawn'),
('Matt', 'Thoa')

查询:

SELECT  sg.child as grandchild,
        fg.Parent as grandparent,
        fg.child as parent,
        sg.Parent as parent
FROM relations as fg -- stands for first generation
INNER JOIN
(
    SELECT parent, child
    FROM relations
) as sg ON fg.child = sg.parent -- second generation

结果:

grandchild  grandparent parent  parent
Chris       Mike        John    John
Chris       Aliss       John    John
David       Kate        Brad    Brad

See a live demo on rextester(我也在那里粘贴您的查询以比较结果。)