Arb*_*bid 5 linq sql-server random entity-framework guid
我试图用一个快速的方法从一个大表(超过100万行)中获取5个随机行数.
到目前为止,我已经使用这些SQL查询进行了测试:
方法1
Select top 5 customer_id, customer_name
from Customer TABLESAMPLE(1000 rows)
order by newid()
Run Code Online (Sandbox Code Playgroud)
这种方法估计I/O成本是0.0127546如此之快(索引扫描非聚集)
方法2
select top 5 customer_id, customer_name
from Customer
order by newid()
Run Code Online (Sandbox Code Playgroud)
此方法的排序估计I/O成本是117.21189和索引扫描非聚集估计的I/O成本2.8735,因此这会影响性能
方法3
select top 5 customer_id, customer_name
from Customer
order by rand(checksum(*))
Run Code Online (Sandbox Code Playgroud)
这种方法的排序估计I/O成本是117.212和索引扫描非聚集估计的I/O成本213.149,这个查询比所有都慢,因为估计的子树成本是213.228非常慢的.
更新:
方法4
select top 5 customer_id, customer_name, product_id
from Customer
Join Product on product_id = product_id
where (customer_active = 'TRUE')
order by checksum(newid())
Run Code Online (Sandbox Code Playgroud)
这种方法更好,速度更快.所有基准测试都没问题.
题
如何将方法4转换为LINQ-to-SQL?谢谢
如果您想将方法 2jitender转换为 Linq To Entities,只需使用如下所示的解决方案:
var randomCoustmers = context.Customers.OrderBy(x => Guid.NewGuid()).Take(5);
Run Code Online (Sandbox Code Playgroud)
但对于方法 1(它在基准测试后速度非常快),您需要执行以下 C# 代码,因为 Linq To Entities 没有此 SQL 语句的 LINQ 等效项TABLESAMPLE(1000 rows)。
var randomCoustmers = context.Customers.SqlQuery("Select TOP 5 customer_id, customer_name from Customer TABLESAMPLE(1000 rows) order by newid()").ToList();
Run Code Online (Sandbox Code Playgroud)
您可以将 SQL 语句移至 SQL 视图或存储过程中,该视图或存储过程将接收要获取的客户数量。
更新
对于似乎非常快的方法 4 (始终遵循您的基准),您可以执行以下 Linq To Entities 操作:
var randomCoustmers = context.Customers.OrderBy(c => SqlFunctions.Checksum(Guid.NewGuid()).Take(5);
Run Code Online (Sandbox Code Playgroud)
实体框架可以将定义在SqlFunctions类中的所有函数转换为 SQL。在这些函数中,我们有Checksum可以做你想做的事情的函数。
如果您想加入其他表,您可以使用 Linq To Entites 轻松完成,因此我只是通过仅查询Customers DbSets.