选择没有FROM但使用APPLY / JOIN

时间:2017-08-09 13:27:13

标签: sql sql-server performance optimization

我编写了一个程序,需要很少的外键ID才能进行进一步的操作

md_machines

+----+-------+
| id | name  |
+----+-------+
| 1  | c432  |
| 2  | c431  |
| n  | ...   |
+----+-------+

我的程序中的查询:

SELECT TOP 1  
@m1 = m1.id,  
@m2 = m2.id,  
@m3 = m3.id,  
@m4 = m4.id  
FROM md_machines  
OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p1) m1  
OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p2) m2  
OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p3) m3  
OUTER APPLY(SELECT TOP 1 id FROM md_machines WHERE name = @p4) m4  

一切正常,但md_machines行数超过300k。当我用空表替换FROM md_machines时,此查询大约快10% 我该如何避免FROM md_machines?对我来说没有必要。

2 个答案:

答案 0 :(得分:2)

使用简单的变量赋值:

SET @m1 = (SELECT TOP 1 id FROM md_machines WHERE name = @p1);
SET @m2 = (SELECT TOP 1 id FROM md_machines WHERE name = @p2);
SET @m3 = (SELECT TOP 1 id FROM md_machines WHERE name = @p3);
SET @m4 = (SELECT TOP 1 id FROM md_machines WHERE name = @p4);
没有明确TOP 1

ORDER BY不稳定。

答案 1 :(得分:1)

选择一次

SELECT name, min(id) 
FROM md_machines 
WHERE (name = @p1 or name = @p2 or name = @p3 or name = @p4)
group by name

然后按WITH

使用上面的查询
WITH sub (name, id)  
AS  
(  
    the suquery  
)

SELECT TOP 1
@m1 = m1.id,
@m2 = m2.id,
@m3 = m3.id,
@m4 = m4.id
FROM (SELECT TOP 1 id FROM sub WHERE name = @p1) m1,
     (SELECT TOP 1 id FROM sub WHERE name = @p2) m2,
     (SELECT TOP 1 id FROM sub WHERE name = @p3) m3,
     (SELECT TOP 1 id FROM sub WHERE name = @p4) m4

顺便说一句:在name

上有索引会很高兴

更新:我认为这个也可以使用

SELECT TOP 1
@m1 = m1.id,
@m2 = m2.id,
@m3 = m3.id,
@m4 = m4.id
FROM (SELECT TOP 1 id FROM md_machines WHERE name = @p1) m1,
     (SELECT TOP 1 id FROM md_machines WHERE name = @p2) m2,
     (SELECT TOP 1 id FROM md_machines WHERE name = @p3) m3,
     (SELECT TOP 1 id FROM md_machines WHERE name = @p4) m4