我使用 Linq2Sql 作为 ORM 并遇到以下问题:我有 2 个表,让我们称它们为客户端(id、名称)和 client_action(id、clientid、日期)。'client' 表包含客户端,client_action 包含用户操作的日志,我只需要其中的第一个。
有一个 linq2sql 查询(带有分页和排序),导致以下 sql:
SELECT TOP (10) /* columns here */
FROM (
SELECT /* columns here */
FROM [dbo].[client] AS [t0]
CROSS APPLY ((
SELECT NULL AS [EMPTY]
) AS [t8]
OUTER APPLY (
SELECT [t9].[source]
FROM [action] AS [t9]
INNER JOIN (
SELECT MIN([t10].[actionID]) AS [value], [t10].[ClientID]
FROM [client_action] AS [t10]
GROUP BY [t10].[clientID]
) AS [t11] ON [t9].[ID] = [t11].[value]
WHERE [t0].[ID] = [t11].[ClientID]
) AS [t12])
) AS [t17]
WHERE /* filter for fields from the client table */
ORDER BY [t17].[date_created] DESC
该查询中有一个逻辑错误,我更改了它。现在生成的sql如下所示:
SELECT TOP (10) /* columns here */
FROM (
SELECT /* columns here */
FROM (
SELECT /* columns here */
FROM [dbo].[client] AS [t0]
CROSS APPLY ((
SELECT NULL AS [EMPTY]
) AS [t3]
OUTER APPLY (
SELECT [t7].[value]
FROM (
SELECT [t5].[ClientID], (
SELECT TOP (1) [t6].[ID]
FROM [client_action] AS [t6]
WHERE [t5].[clientID] = [t6].[clientID]
ORDER BY [t6].[date_created]
) AS [value]
FROM (
SELECT [t4].[clientID]
FROM [client_action] AS [t4]
GROUP BY [t4].[clientID]
) AS [t5]
) AS [t7]
WHERE [t0].[ID] = [t7].[clientID]
) AS [t8])
LEFT OUTER JOIN [client_action] AS [t9] ON [t8].[value] = [t9].[ID]
) AS [t26]
) AS [t27]
WHERE /* filter for fields from client table */
ORDER BY [t27].[date_created] DESC
并且出现了性能问题。我使用“SET STATISTICS IO ON”执行了这两个查询并得到了有趣的结果:
- 对于第一个查询:
- 客户表被过滤
- 申请了“前 10 名”
- 'cross apply' 应用于结果 10 条记录
- 对于第二个查询:
- 客户表被过滤(找到大约 10K 条记录)
- 'cross apply' 申请了那 10K 条记录
- 申请了“前 10 名”
所以它使第二个查询工作得慢得多。有没有办法“调整”查询,以便尽可能在过滤后应用“交叉应用”?
问题是那里有 2 个“交叉应用”和更多的连接,这一切都使它工作得非常慢。我创建了可以提高查询速度的索引,但它仍然慢到令人讨厌。
帮帮帮帮 。_