我有一个查询需要40秒才能执行:
HttpListener Listener = new HttpListener("http", 80);
Listener.Start();
HttpListenerContext ctx;
string s;
byte[] b;
int i;
while (true)
{
ctx = Listener.GetContext();
Debug.Print("Serving a page...");
s = "";
for (i = 0; i < 500; i++) s += "Hello!"; // a 5KB dumb page
s += "";
b = Encoding.UTF8.GetBytes(s);
ctx.Response.ContentLength64 = b.Length;
ctx.Response.ContentType = "text/html";
ctx.Response.OutputStream.Write(b, 0, b.Length);
ctx.Response.OutputStream.Close();
s = null;
b = null;
Debug.GC(true);
Debug.Print("Done with the page.");
}
在上述查询条件下,tblb.col1 = oc.col1花费了很多时间,然后达到了预期。
因此,我对查询进行了如下优化,只需4秒钟即可执行并给出准确的结果:
select ID , OPERATOR_NAME,
JOBS_BULK = ISNULL((select COUNT(distinct REPL_RUN) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_BULK = o.OPERATOR_NAME and isnull(r.ASSIGNED_BULK_COMPLETE,'N') = 'N'),0) ,
ITEMS_BULK = ISNULL((select COUNT(*) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_BULK = o.OPERATOR_NAME and isnull(r.ASSIGNED_BULK_COMPLETE,'N') = 'N'),0) ,
JOBS_PICK = ISNULL((select COUNT(distinct REPL_RUN) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_PICK = o.OPERATOR_NAME and isnull(r.ASSIGNED_PICK_COMPLETE,'N') = 'N') ,0) ,
ITEMS_PICK = ISNULL((select COUNT(*) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_PICK = o.OPERATOR_NAME and isnull(r.ASSIGNED_PICK_COMPLETE,'N') = 'N') ,0)
from Operatorr o
where
(ISNULL((select COUNT(*) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where ISNULL(ASSIGNED_BULK,' ') <> ' ' and r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_BULK = o.OPERATOR_NAME and isnull(r.ASSIGNED_BULK_COMPLETE,'N') = 'N'),0)
+ ISNULL((select COUNT(*) from Locationn r (NOLOCK) , Batch b (NOLOCK)
where ISNULL(ASSIGNED_PICK,' ') <> ' ' and r.FROM_PRO_CODE = b.PRO_CODE and r.FROM_BAT_NUMBER = b.BAT_NUMBER and b.BAT_QUANTITY > 0 and r.ASSIGNED_PICK = o.OPERATOR_NAME and isnull(r.ASSIGNED_PICK_COMPLETE,'N') = 'N') ,0) ) <> 0
我只是在where子句的select语句中使用了表tblA的联接。 您能告诉我什么是技术原因,为什么第二个查询需要更少的时间来执行?
答案 0 :(得分:1)
这在黑暗中非常刺眼。开始更改后,我发现您的查询存在更多问题。我已经发表了几条评论,因此请注意,并注意大括号({}
)中的项目。最后,我看不到为什么需要2个子查询。因为您似乎在第二个查询中检查的是同一件事,而在第一个查询中,tblb.{Some Column}
('xyz'
和'abc'
)的值却不同。
考虑到您只想检查是否有行,也不需要COUNT
,可以使用EXISTS
。最后,我摆脱了1980年的隐式JOIN
语法。
如果这不能为您提供所需的结果,则样本数据和预期结果将是关键,并且您所使用的实际SQL(由于语法错误,您提供的SQL无法使用)。 / p>
SELECT *
FROM tblA A
WHERE EXISTS (SELECT 1
FROM tblb B
JOIN tblc C ON B.Col1 = C.Col1
WHERE B.{Some Column} IN ('xyz','abc')--The column name is missing in your original query
--Also in first query you had 'xyz' and 'abc' but 'xyz' both times in your second, which is it?
AND B.col1 = A.col1);
答案 1 :(得分:1)
您应使用exists
编写此类查询。我将从以下内容开始:
select a.*
from tblA a
where exists (select 1
from tblb b join
tblc c
on b.col1 = c.col1
where b.? = 'xyz' and -- unclear what column this is
b.col1 = a.col1
) and
exists (select count (*)
from tblb b join
tblc c
on b.col1 = c.col1
where b.? = 'ABC' and
b.col1 = a.col1
);
影响性能的差异是使用exists
。以下是最佳做法:
FROM
子句中使用逗号。 始终使用正确的,明确的JOIN
语法。关于为什么您的版本具有不同的性能。一种可能是缓存。另一个是研究执行计划。通常,第一个会更好,但“通常”不会总是“变”。