SSIS中 merge join与lookup 哪个性能更好些

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSIS中 merge join与lookup 哪个性能更好些相关的知识,希望对你有一定的参考价值。

首先Merge Join 要求你的 200W 和 1亿条的查询数据都必须在 JOIN 之前排序,这个排序的过程对性能上也是有很大影响的。一般的情况下,我可能会先考虑使用 Lookup,一是不需要考虑排序的问题,二是可以利用上缓存。但是这个不是绝对的,考虑到你的目标表有1亿条左右,Lookup 缓存是否足够使用也和你本身的服务器配置相关,内存过于紧张,性能可能还不如 Merge Join。所以关于何时选择 Merge Join 还是 Lookup 因环境而异,没有绝对的结论。

给你一个参考,我以前做过一个 1500W目标表,源10W的测试结果,表字段大约100多列,源查询的时候并非直接取表的值,而是需要做一些转换。在本机测试 8G虚机情况下,使用 Lookup 和 Merge Join 的时间都很慢,都是以小时计。但是在 16G的 测试服务器上(和真实产品服务器的配置是一样的) Lookup 的时间要远远优于 Merge Join 的时间。但是就可以明显的看出来,在不同的环境下,结论完全是不一样的。

最好的方式,就是在同一环境下,单用户的访问下,按照实际数据量依次尝试这几种方式:Lookup,Merge Join 和 SQL Server 中的 Merge,并记录比较实际的执行时间,这样的结论往往会比较准确些。但同时也要考虑到并行和串行的环境下,对内存争夺也会影响实际测试结果。

这几个控制本身的配置不会花费很多时间,所以完全可以尝试一下。
参考技术A 三个阶段的主要区别在与所使用的内存、对不匹配记录的处理以及对输入数据的要求不同。

join stage:多个输入链接,一个输出链接。会对输入数据进行按键分区,确保相同键值的记录位于同一分区并用同一节点进行处理,故每次只取较少行,所需内存小。对于不匹配记录按照链接方式的不同而有所差异。

merge stage:多个输入链接,其中一个表示主数据集,其余表示更新数据集,一个输出链接和多个reject链接。可在链接顺序中指定更新链接与reject链接的对应关系。会对输入数据进行按键分区,确保相同键值的记录位于同一分区并用同一节点进行处理,故每次只取较少行,所需内存小。对不匹配记录会放入reject指定的数据输出中。要求主数据集与更新数据集均无重复值。

lookup stage:一个主链接,一个或多个引用链接,一个输出链接,一个reject链接。查找操作基于引用表的查找键列。查找键列在lookup中定义。查找数据与引用数据会全部读入内存,故需内存较大。无需对数据排序,但是应注意查找表的分区方式,与引用表相同或者采用全部分区方式。本回答被提问者和网友采纳

mongodb `$lookup` 或 `join` 与对象数组内的属性

【中文标题】mongodb `$lookup` 或 `join` 与对象数组内的属性【英文标题】:mongodb `$lookup` or `join` with attributes inside array of objects 【发布时间】:2020-08-18 08:19:34 【问题描述】:

我有这个来自 mongodb 的对象

[
    
        "_id": "5eaf2fc88fcee1a21ea0d94d",
        "migration_customer_union_id": 517,
        "__v": 0,
        "account": 1,
        "createdAt": "2020-05-03T20:55:36.335Z",
        "customerUnion": "5eaf2fc7698de8321ccd841d",
        "shaufel_customers": [
            
                "percent": 50,
                "_id": "5eaf2fc8698de8321ccd881f",
                "customer": "5eaf2fb9698de8321ccd68c0"
            ,
            
                "percent": 50,
                "_id": "5eaf2fc9698de8321ccd8a9d",
                "customer": "5eaf2fb9698de8321ccd68c0"
            
        ],
    
]

您可以注意到在 shaufel_customers 数组中有一个名为 customer 的属性,我想用它来加入客户文档,所以这就是我正在做的事情(在 *** 的帮助下编写了这段代码:))

const aggregate = await CustomerUnionCustomer.aggregate(
        [
            
                $match: migration_customer_union_id: 517
            ,
            
                $lookup: 
                    from: 'customers',
                    localField: 'shaufel_customers.customer',
                    foreignField: '_id',
                    as: 'customers',
                
            ,
            
                $project: 
                    shaufel_customer_union_id: 1,
                    customerUnion: '$customerUnions',
                    shaufel_customers: 
                        $map: 
                            input: "$customers",
                            as: "c",
                            in: 
                                $mergeObjects: [
                                    "$$c",
                                    
                                        $arrayElemAt: [
                                            $filter: 
                                                input: "$shaufel_customers",
                                                cond: $eq: ["$$this.customer", "$$c._id"]
                                            
                                        , 0]
                                    ,

                                ]
                            
                        ,

                    
                
            ,
            
                "$project":  // this project just to get some specific values inside shaufel_customers
                    '_id': 0,

                    "shaufel_customers": 
                        "$map": 
                            "input": "$shaufel_customers",
                            "as": "customer",
                            "in": 
                                "customer_id": "$$customer.shaufel_customer_id",
                                "percent": "$$customer.percent"
                            
                        
                    
                
            

        ]
    )

执行此代码时,我收到以下响应

[
    
        "shaufel_customers": [
            
                "customer_id": "869",
                "percent": 50
            
        ]
    
]

你可以注意到我得到了一个对象,虽然上面的原始数组中有两个对象,这是因为上面的客户属性具有相同的 ObjectId 值5eaf2fb9698de8321ccd68c0,这就是我想问的。即使 id 相同,我也想获得相同的两个对象,所以我在这里期待的结果是

[
    
        "shaufel_customers": [
            
                "customer_id": "869",
                "percent": 50
            ,
            
                "customer_id": "869",
                "percent": 50
            ,
        ]
    
]

我该怎么做:(

【问题讨论】:

【参考方案1】:

您需要恢复您的 $map 并迭代 shaufel_customers 而不是 customer - 这将返回两个结果:


    $project: 
        shaufel_customer_union_id: 1,
        customerUnion: '$customerUnions',
        shaufel_customers: 
            $map: 
                input: "$shaufel_customers",
                as: "sc",
                in: 
                    $mergeObjects: [
                        "$$c",
                        
                            $arrayElemAt: [
                                $filter: 
                                    input: "$customers",
                                    cond: $eq: ["$$this._id", "$$sc.customer"]
                                
                            , 0]
                        ,

                    ]
                
            ,

        
    
,

【讨论】:

成功了!谢谢。你又救了我,感谢你的帮助。

以上是关于SSIS中 merge join与lookup 哪个性能更好些的主要内容,如果未能解决你的问题,请参考以下文章

求教DATASTAGE中MERGE,JOIN和LOOKUP三者之间的区别

DataStage中mergelookupjoin的区别与联系

Spark 中 Lookup 和 Join 的区别

mongodb `$lookup` 或 `join` 与对象数组内的属性

Python数据分析pands中的Merge与join

PANDAS 数据合并与重塑(join/merge篇)