Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 合并前的子查询vs TENTABLE_Sql_Sql Server_Tsql_Optimization - Fatal编程技术网

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也不太坏。