我在SQL Server 2000 Server上使用Quest的TOAD for SQL Server。
下面是我的问题:
SELECT CASE SLCE.GroupName WHEN 'Other' THEN ARM.FBCOMPANY
WHEN 'Inter Co.' THEN ARM.FBCOMPANY
ELSE SLCE.GroupName END AS [Company Name],
ARM.fcustno AS [Cust No],
ARM.fbcompany AS [Cust Name],
ARM.fcinvoice AS [Invoice No],
ARM.fdgldate AS [Post Date],
year(arm.fdgldate) AS [Year Posted],
CASE ARM.fcsource WHEN 'S' THEN 'Shipper'
WHEN 'O' THEN 'Sales Order'
WHEN 'R' THEN 'Receiver'
WHEN 'C' THEN 'Customer'
ELSE ARM.fcsource END AS [Source Doc Type],
CASE ARM.fcstatus WHEN 'N' THEN 'New'
WHEN 'U' THEN 'Unpaid'
WHEN 'P' THEN 'Partially Paid'
WHEN 'F' THEN 'Paid in Full'
WHEN 'H' THEN 'Held'
WHEN 'V' THEN 'Voided'
ELSE ARM.fcstatus END AS [Invoice Status],
ARM.fpono AS [Cust PO No],
ARM.fsalespn AS [Sales Person],
ARI.fitem AS [Item No],
ARI.fprodcl AS [Prod Class],
ARI.fshipkey AS [Qty Invoiced],
ARI.ftotprice AS [Net Invoiced],
ARI.fpartno AS [Part No],
ARI.frev AS [Part Rev],
cast(ARI.fmdescript AS VARCHAR(20)) AS [Part Description],
ARM.fsono AS [Sales No],
ARI.fsokey AS [SO Rels Key],
ARI.fordqty AS [Qty Ordered],
RED.[YEAR] AS [Year],
RED.PERIOD AS [RF Period]
FROM dbo.armast ARM
INNER JOIN dbo.aritem ARI
ON ARM.FCINVOICE = ARI.FCINVOICE
INNER JOIN slcdpm SLC
ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE
ON SLC.identity_column = SLCE.fkey_id
INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED
ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME)
WHERE ARM.fcstatus <> 'V'
AND RED.[YEAR] = year(getdate())
AND ari.frev = 'REP'
AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000')这是TOAD的选项(突出显示差异)是:
INNER JOIN dbo.aritem ARI
ON ARM.FCINVOICE = ***COALESCE (ARI.FCINVOICE , ARI.FCINVOICE)***
INNER JOIN slcdpm SLC
ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE
ON SLC.identity_column = SLCE.fkey_id
INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED
ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME)
WHERE ARM.fcstatus <> 'V'
AND RED.[YEAR] = year(getdate())
AND ari.frev = 'REP'
AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000')
***AND ARI.[fpartno] >= CHAR(0)***有人能告诉我为什么联合和附加and语句将查询速度提高了50%以上吗?
发布于 2009-08-28 15:46:42
你看过实际的执行计划了吗?它们应该向您显示SQL Server在执行这些查询时所采用的不同方法。
发布于 2009-08-28 15:54:39
这绝对是一个奇怪的问题。执行计划应该可以肯定地告诉您,但是在数据库中像这样的性能变化几乎总是归结为索引。因此,我最好的猜测是,不知何故,sql server缺少了一个可以使用的索引,添加这些奇怪的更改使其脱颖而出。
但是,如果你想了解其中的“为什么”,这样下次你就可以在第一时间写出更快的查询,那就什么都没有了。
发布于 2009-08-28 16:05:07
一个完整的WAG:
我将猜测>=CHAR有一个“非空”条件(所以添加的过滤器总是通过),Toad碰巧知道fpartno不够聪明,无法检测到fpartno(0)始终为真。因此,这表明Toad试图以一种非常间接的方式,引导优化器使用其中包含fpartno的内容。可以是(fcinvoice,fpartno)上的综合索引。你有这样的吗?
就像其他人所说的,解释计划应该有助于解释这个谜团。
https://stackoverflow.com/questions/1347837
复制相似问题