【发布时间】:2013-11-26 04:55:16
【问题描述】:
我需要使用 LINQ 从 DB2 数据库中查询记录。我有从 DB 模式生成的实体,并且正在尝试使用 Skip 和 Take 执行 LINQ 查询。基础表有 25 列,可能有一百万条记录。当我在没有“Skip()”的情况下执行查询时,大约需要 0.508 毫秒才能完成。当我包含 Skip() 时,它需要将近 30 秒。大不同。
谁能告诉我为什么会这样?
更新:这是我正在使用的 LINQ 查询。
var x = 30;
var results = context.ASSET_T
.OrderBy(c => c.ASSET_ID)
.Skip(x)
.Take(x)
.ToList();
更新:所以我只是尝试更新查询,以便我只返回一个列,ASSET_ID。当我只返回那一列时,带有 Skip() 的查询只需要 0.256 毫秒。
var x = 30;
var results = context.ASSET_T
.OrderBy(c => c.ASSET_ID)
.Skip(x)
.Take(x)
.Select(c => c.ASSET_ID)
.ToList();
如果我包含任何其他列,则查询执行时间会增加戏剧性地。
例如下面的查询需要 10 秒来执行。
var x = 30;
var results = context.ASSET_T
.OrderBy(c => c.ASSET_ID)
.Skip(x)
.Take(x)
.Select(c => new {
ASSET_ID = c.ASSET_ID,
ASSET_TYP = c.ASSET_TYP
ASSET_DESC = c.ASSET_DESC
})
.ToList();
更新:我现在发现我尝试查询的表中的列存在问题(可能与索引相关)。正如我上面提到的,当我执行一个只返回 ASSET_ID 列的查询时,它只需要 0.256 毫秒。如果我尝试执行 ONLY 返回 ASSET_DESC 的查询或 ONLY 返回 ASSET_TYP 的查询,则查询执行时间跳到 9 秒左右。
这是否表明其他列当前没有被索引?
更新:我已经添加了上述 LINQ 查询的 SQL 输出。
SELECT
Project1.C1 AS C1,
Project1.ASSET_ID AS ASSET_ID,
Project1.ASSET_TYP AS ASSET_TYP,
Project1.ASSET_DESC AS ASSET_DESC
FROM ( SELECT Project1.ASSET_ID AS ASSET_ID, Project1.ASSET_TYP AS ASSET_TYP, Project1.ASSET_DESC AS ASSET_DESC, Project1.C1 AS C1, row_number() OVER (ORDER BY Project1.ASSET_ID ASC, Project1.ASSET_TYP ASC, Project1.ASSET_DESC ASC) AS row_number
FROM ( SELECT
Extent1.ASSET_ID AS ASSET_ID,
Extent1.ASSET_TYP AS ASSET_TYP,
Extent1.ASSET_DESC AS ASSET_DESC,
CAST(1 AS int) AS C1
FROM MYDB.ASSET_T AS Extent1
) AS Project1
) AS Project1
WHERE Project1.row_number > 1
ORDER BY Project1.ASSET_ID ASC, Project1.ASSET_TYP ASC, Project1.ASSET_DESC ASC FETCH FIRST 31 ROWS ONLY
【问题讨论】:
-
生成的SQL是什么?
-
显示您编写的 LINQ 查询。
-
查询是否曾经被视为
IEnumerable<T>?还是一直是IQueryable<T>? -
虽然我没有看到任何突然出现的东西,但您可能需要阅读 msdn.microsoft.com/en-us/data/hh949853 的性能注意事项。有一节介绍如何解决性能问题。
-
使用
Skip会完全改变sql查询是可以理解的,而只使用Take可能会导致使用Top的sql查询。
标签: c# linq linq-to-entities paging query-performance