【发布时间】:2013-10-08 20:51:02
【问题描述】:
如何让这个 SQL 查询更高效?下面显示的 CteFinal 代码是我的查询的一部分,我的查询最多需要 6 分钟。 cteMonth 如下所示。 cteDetail 是另一个直接从数据库中提取信息的 cte,运行时间不到一秒。
CteFinal 所做的是创建缺少的会计期间行,同时包含 f.FiscalPeriod=0 行中的一些列数据。
我不能添加、删除或更改表上的任何索引,因为这是一个 ERP 数据库,我不能进行此类更改。
CteFinal:
SELECT Account,Month, CONVERT(DATETIME, CAST(@Year as varchar(4)) + '-' + CAST(Month as VARCHAR(2)) + '-' + '01', 102) JEDate
,accountdesc,'' Description,'' JournalCode,NULL JournalNum,NULL JournalLine
,'' LegalNumber,'' CurrencyCode,0.00 DebitAmount,0.00 CreditAmount,fiscalcalendarid,company,bookid,SegValue2,SegValue1,SegValue3,SegValue4
FROM cteDetail f
CROSS JOIN cteMonths m
WHERE f.FiscalPeriod=0 and not exists(select * from cteDetailADDCreatedZero x where x.Account=f.Account and x.FiscalPeriod=Month)
CteMonth:
cteMonths (Month) AS(
select 0 as Month
UNION select 1 as Month
UNION select 2 as Month
UNION select 3 as Month
UNION select 4 as Month
UNION select 5 as Month
UNION select 6 as Month
UNION select 7 as Month
UNION select 8 as Month
UNION select 9 as Month
UNION select 10 as Month
UNION select 11 as Month
UNION select 12 as Month)
谢谢!
【问题讨论】:
-
右加入 cteMonth 怎么样?
-
您可以使用
SET NOCOUNT ON来减少一些网络开销,在表名前加上dbo.以节省一点安全开销,如果可能的话,将WITH (NOLOCK)提示添加到表中。在您的AND NOT EXISTS中,您可以只从您的cteDetailADDCreatedZero表中选择主键。 -
@Darth
WITH (NOLOCK)将有助于防止阻塞,但以潜在的脏数据为代价 - 并且不会自行加速此查询(仅在更新阻塞读取的情况下)。您对NOT EXISTS提出的更改将对任何事情产生绝对零影响。 -
为什么会有第 0 个月和第 12 个月?你真的要代表 13 个月吗?为什么要使用交叉连接?您真的想要源中的每一行都有 13 行吗?否则你能告诉我们如何找出
cteDetail中的什么可以告诉我们该数据属于哪个月份吗? -
@Aaron 第 0 个月 = 本年度的期初余额,该行将始终存在。它用于填充其他创建的行中的一些列。匹配很简单,对这个查询没有影响,但是很好的问题。
标签: sql sql-server-2008 query-optimization