sql – LINQ联接 – 性能

我很好奇LINQ(而不是LINQ to sql)的表现是如何在sql Server执行连接的情况下加入幕后的.

sql Server在执行查询之前,生成执行计划.执行计划基本上是一个表达式树,它认为它是执行查询的最佳方式.每个节点都提供有关是否执行排序,扫描,选择,加入等信息.

在我们的执行计划中的“加入”节点上,我们可以看到三种可能的算法;散列连接,合并连接和嵌套循环连接. sql Server将根据Inner表和外表中的预期行数,我们正在做什么类型的连接(某些算法不支持所有类型的连接),是否需要数据排序,以及可能是很多其他因素.

加入算法:

嵌套循环连接:
最适合小型输入,可通过有序内表进行优化.

合并加入:
最适合中到大输入分类输入,或需要订购的输出.

哈希加入:
最适合中到大输入,可以并行化以线性扩展.

LINQ查询

DataTable  firstTable,secondTable;

...

var rows = from firstRow in firstTable.AsEnumerable ()
                join secondRow in secondTable.AsEnumerable ()
                    on firstRow.Field<object> (randomObject.Property)
                    equals secondRow.Field<object> (randomObject.Property)
           select new {firstRow,secondRow};

SQL查询

SELECT *
FROM firstTable fT
    INNER JOIN secondTable sT ON fT.Property = sT.Property

如果sql Server知道每个表中有少量行,则可以使用嵌套循环连接,如果知道其中一个表有索引,则使用合并连接,如果知道任何一个表上有很多行,则使用散列连接表,既没有索引.

Linq是否选择其连接算法?还是总是使用一个?

解决方法

Linq to sql不会向服务器发送连接提示.因此,使用Linq to sql的连接的性能将与“直接”发送到服务器(即使用纯ADO或sql Server Management Studio)的相同连接的性能相同,而不指定任何提示.

Linq to sql也不允许你使用连接提示(据我所知).因此,如果要强制使用特定类型的连接,则必须使用存储过程或Execute [Command | Query]方法执行此操作.但是,除非您通过编写INNER [HASH | LOOP | MERGE] JOIN来指定连接类型,否则sql Server总是选择它认为最有效的连接类型 – 查询的来源无关紧要.

其他Linq查询提供程序(如Entity Framework和NHibernate Linq)将完成与Linq to sql完全相同的操作.这些都没有直接了解您如何索引数据库,因此他们都没有发送连接提示.

Linq to Objects有点不同 – 它(几乎?)总是在sql Server用语中执行“散列连接”.这是因为它缺少进行合并连接所需的索引,并且散列连接通常比嵌套循环更有效,除非元素的数量非常小.但是确定IEnumerable< T>中的元素数量.可能首先需要完整的迭代,因此在大多数情况下,假设最差并使用散列算法会更快.

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03