Sql 合并前的子查询vs TENTABLE
我有一个复杂的查询,我想用它作为合并到表中的源。这将在数百万行上执行。目前,我正在尝试通过在合并之前将数据插入临时表来对数据应用约束 行动包括: 过滤掉重复的数据。 连接一些表以拉入其他数据 插入临时表。 这是问题所在Sql 合并前的子查询vs TENTABLE,sql,sql-server,tsql,optimization,Sql,Sql Server,Tsql,Optimization,我有一个复杂的查询,我想用它作为合并到表中的源。这将在数百万行上执行。目前,我正在尝试通过在合并之前将数据插入临时表来对数据应用约束 行动包括: 过滤掉重复的数据。 连接一些表以拉入其他数据 插入临时表。 这是问题所在 -- Get all Orders that aren't in the system WITH Orders AS ( SELECT * FROM [Staging].Orders o WHERE NOT EXISTS ( SEL
-- 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;
我想知道是否有什么我可以做的优化它的时间。我尝试过使用DB引擎调谐器,但是这个查询比我正在运行的其他查询占用的CPU时间多100倍。还有什么我可以研究或者查询不能进一步改进的吗?通常,当我进行速度测试时,我会对SQL的各个部分进行检查,以查看问题所在。打开“执行计划”,看看大部分时间都花在哪里。此外,如果你只想做快速和肮脏突出显示你的CTE和运行就是这样。那么快,是的,继续 我有时会发现,一个单独的索引被删除,只需让数据库做一些大的事情的一部分,然后找到那部分,就可以抛出一个复杂的连接逻辑 另一个想法是,如果在生产环境或类似环境中有一个快速tempdb,那么也可以将CTE转储到temp表中。在上面建立索引,看看这是否加快了速度。有时CTE、表变量和临时表在连接时会失去一些性能。我发现在部分对象上创建索引有时会提高性能,但要做到这一点,tempdb的负载也会增加,所以请记住这一点 CTE只是语法 在该联接上运行该CTE 首先,只需将其作为select语句运行,无需插入 如果选择速度较慢,则: 将该CTE移动到临时状态,以便对其进行一次评估并具体化 在三个联接列上放置索引PK(如果适用) 如果选择不慢,则是在订单上插入时间 首先只创建PK并对PK上的insert进行排序,这样就不会对聚集索引进行分段
然后在插入完成后构建任何其他必要的索引尝试使用嵌套CTE计算需要插入的最终数据,并最终保留一个简单的插入有关于创建最佳索引的文章吗?我一直在使用调优引擎来建议索引,但我开始认为从长远来看,这可能弊大于利。老实说,我对索引的TSQL知识最弱。我相信索引会降低插入的性能,所以您希望节约使用它们。然而,有时使用临时表时,我已经成功地做到了这一点:将Select*插入Object from thing或Select*插入Object from thing,然后创建索引。因此,您不必添加索引就可以获得插入的速度,然后在单个int字段上创建所有内容的完整索引。我知道很多时候,当你有多个部门加入时,往往会有一个单一的断点,这就是瓶颈。我不确定这是否在野外使用,但我能在插入之前删除索引,然后再添加它们吗?同样,如果这件事发展成TB的数据,可能无法工作。取决于所需的时间,在QA/UAT/BETA中测试,然后运行生产是不同的。取决于你的尺寸和你想要的时间表。你可以,但它经常成为一个问题“我应该吗?”。如果速度更快,收益就更大。您可以尝试禁用它们,然后再重新启用它们。然后可能会在之后对指数进行增量调整。在生产环境中从头开始重新创建索引有时需要一段时间。对于temp表,我建议它通常高达几百dk或几mil(如果只是int),如果tempdb上有良好的硬件,那么ints也不太坏。