我有一个复杂的查询,我想将其用作合并到表中的源。这将在数百万行上执行。目前,我试图通过在合并之前将其插入临时表来对数据应用约束。
操作是:
这是查询。
-- Get all Orders that aren't in the system
WITH Orders AS
(
SELECT *
FROM [Staging].Orders o
WHERE NOT EXISTS
(
SELECT 1
FROM Maps.VendorBOrders vbo
JOIN OrderFact of
ON of.Id = vbo.OrderFactId
AND InternalOrderId = o.InternalOrderId
AND of.DataSetId = o.DataSetId
AND of.IsDelete = 0
)
)
INSERT INTO #VendorBOrders
(
CustomerId
,OrderId
,OrderTypeId
,TypeCode
,LineNumber
,FromDate
,ThruDate
,LineFromDate
,LineThruDate
,PlaceOfService
,RevenueCode
,BillingProviderId
,Cost
,AdjustmentTypeCode
,PaymentDenialCode
,EffectiveDate
,IDRLoadDate
,RelatedOrderId
,DataSetId
)
SELECT
vc.CustomerId
,OrderId
,OrderTypeId
,TypeCode
,LineNumber
,FromDate
,ThruDate
,LineFromDate
,LineThruDate
,PlaceOfService
,RevenueCode
,bp.Id
,Cost
,AdjustmentTypeCode
,PaymentDenialCode
,EffectiveDate
,IDRLoadDate
,ro.Id
,o.DataSetId
FROM
Orders o
-- Join related orders to match orders sharing same instance
JOIN Maps.VendorBRelatedOrder ro
ON ro.OrderControlNumber = o.OrderControlNumber
AND ro.EquitableCustomerId = o.EquitableCustomerId
AND ro.DataSetId = o.DataSetId
JOIN BillingProvider bp
ON bp.ProviderNPI = o.ProviderNPI
-- Join on customers and fail if the customer doesn't exist
LEFT OUTER JOIN [Maps].VendorBCustomer vc
ON vc.ExtenalCustomerId = o.ExtenalCustomerId
AND vc.VendorId = o.VendorId;
我想知道我能做些什么来优化它的时间。我尝试过使用数据库引擎调优器,但此查询占用的CPU时间比我运行的其他查询多100倍。还有什么我可以研究或者查询不能进一步改进吗?
答案 0 :(得分:1)
通常,当我进行速度测试时,我会对SQL的各个部分执行检查,以查看问题所在。打开“执行计划”,看看很多时间的去向。此外,如果你想快速和肮脏地突出你的CTE并运行它。是这么快,是的,继续前进。
我有时发现一个单独的索引会抛出整个复杂的连接逻辑,只需让数据库执行大的一部分,然后找到那个部分。
另一个想法是,如果您在生产环境中有快速tempdb等,也可以将CTE转储到临时表中。索引,看看是否加快了速度。有时CTE,表变量和临时表在连接时会失去一些性能。我发现在部分对象上创建索引有时会提高性能,但是你也会在tempdb上加载更多的负载来做到这一点,所以请记住这一点。
答案 1 :(得分:1)
CTE只是语法
在该连接上评估(运行)CTE
首先将它作为select语句运行(无插入)
如果选择慢,则:
将CTE移动到#TEMP,以便对其进行一次评估并实现
在三个连接列上放置一个索引(如果适用,PK)
如果select不慢,那么它就是#VendorBOrders上的插入时间 Fist只创建PK并对PK上的插入进行排序,以便不对该聚簇索引进行分段 然后在插入完成之后构建任何其他必要的索引