2017-08-09 24 views
1

我寫了一個程序,需要幾個外鍵ID,用於進一步的操作沒有選擇從<table>但隨着應用/ JOIN

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有超過30萬行。當我用空表替換FROM md_machines時,此查詢速度大約快10%。
如何避免FROM md_machines?這對我沒有必要。

回答

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 

BTW使用上面的查詢:將是很好的對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 
+0

很好的解決方案/解決。我會記住它,特別是因爲使用'min'和'group'作爲另一個項目。在這裏我使用'name'的唯一索引和'id'的主鍵 – Load

+0

答案已更新 – StanislavL

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並不穩定。

+0

是的,這是我的第一個版本的代碼。但多個查詢正在吃更多的性能。所以我打算加入/應用 – Load