【问题标题】:Simple Query Running slowly in SQL Server?简单查询在 SQL Server 中运行缓慢?
【发布时间】:2014-04-15 08:14:23
【问题描述】:

我只有 2 个表格,产品和图像。在产品中我只有 50,000 行,而在图像中我有 10 行。我写了一个非常简单的查询,它将为我提供前 10 种产品。实际上,这个查询是由 EF 生成的。

SELECT TOP (10) 
    [Join1].[Id1] AS [Id], 
    [Join1].[Name] AS [Name], 
    [Join1].[Price] AS [Price], 
    [Join1].[NewPrice] AS [NewPrice], 
    [Join1].[ShortDescription] AS [ShortDescription], 
    [Join1].[SKU] AS [SKU], 
    [Join1].[ProductTypeID] AS [ProductTypeID], 
    [Join1].[ImageID] AS [ImageID], 
    [Join1].[Promotion] AS [Promotion], 
    [Join1].[ParentID] AS [ParentID], 
    [Join1].[Attributes] AS [Attributes], 
    [Join1].[Id2] AS [Id1], 
    [Join1].[Path] AS [Path]
FROM (
   SELECT [Extent1].[Id] AS [Id1]
        , [Extent1].[Name] AS [Name]
        , [Extent1].[Price] AS [Price]
        , [Extent1].[NewPrice] AS [NewPrice]
        , [Extent1].[ShortDescription] AS [ShortDescription]
        , [Extent1].[SKU] AS [SKU]
        , [Extent1].[ProductTypeID] AS [ProductTypeID]
        , [Extent1].[ImageID] AS [ImageID]
        , [Extent1].[Promotion] AS [Promotion]
        , [Extent1].[ParentID] AS [ParentID]
        , [Extent1].[Attributes] AS [Attributes]
        , [Extent2].[Id] AS [Id2]
        , [Extent2].[Path] AS [Path]
        , row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
   FROM  [dbo].[Products] AS [Extent1]
   INNER JOIN [dbo].[Images] AS [Extent2] ON [Extent1].[ImageID] = [Extent2].[Id]
)  AS [Join1]
WHERE [Join1].[row_number] > 0
ORDER BY [Join1].[Id1] ASC

但是这个查询需要 3 秒。如何提高此查询性能。 id 是主键和标识列。

【问题讨论】:

  • 您正在编写的输出此查询的代码是什么?
  • @BiffBaffBoff:从标签来看,生成这个野兽的一定是Entity Framework 6。
  • 是的,但是显示您正在编写的生成此查询的代码。即您的方法中的 LINQ 代码
  • @BiffBaffBoff,代码很简单 EF products.include(p => p.Image)
  • 所以您一次退回 50000 件产品?而您正在从ProductImage 中选择每一列?为什么?

标签: sql sql-server entity-framework sql-server-2012 entity-framework-6


【解决方案1】:

好的,我稍后添加了 JOIN,然后它开始快速工作。

SELECT TOP (10)
    [Join1].[Id1] AS [Id],
    [Join1].[Name] AS [Name],
    [Join1].[Price] AS [Price],
    [Join1].[NewPrice] AS [NewPrice],
    [Join1].[ShortDescription] AS [ShortDescription],
    [Join1].[SKU] AS [SKU],
    [Join1].[ProductTypeID] AS [ProductTypeID],
    [Join1].[ImageID] AS [ImageID],
    [Join1].[Promotion] AS [Promotion],
    [Join1].[ParentID] AS [ParentID],
    [Join1].[Attributes] AS [Attributes],
    [Join2].[Id] AS [Id2],
    [Join2].[Path] AS [Path]
FROM (SELECT
    [Extent1].[Id] AS [Id1],
    [Extent1].[Name] AS [Name],
    [Extent1].[Price] AS [Price],
    [Extent1].[NewPrice] AS [NewPrice],
    [Extent1].[ShortDescription] AS [ShortDescription],
    [Extent1].[SKU] AS [SKU],
    [Extent1].[ProductTypeID] AS [ProductTypeID],
    [Extent1].[ImageID] AS [ImageID],
    [Extent1].[Promotion] AS [Promotion],
    [Extent1].[ParentID] AS [ParentID],
    [Extent1].[Attributes] AS [Attributes],
    ROW_NUMBER() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[Products] AS [Extent1]) AS [Join1]
INNER JOIN [dbo].[Images] AS [Join2] ON [Join1].[ImageID] = [Join2].[Id]
WHERE [Join1].[row_number] > 0
ORDER BY [Join1].[Id1] ASC

但我不明白为什么 EF 做这些事情。

【讨论】:

  • @ElectricLlama,你确定吗?我的 sql 管理工作室中正在运行相同的查询
  • 由于行号以及应用于它的排序和过滤,它可能需要相当多的时间。行号是一个没有任何索引的动态列。因此,数据库必须进行大量处理(可能访问每一行)才能确定您想要哪些行。您可以通过查看访问的行数来检查执行计划(如果这等于表上的行数,则它会完成所有艰苦的工作)。让它更快的方法是找到另一种没有row_number的排序和过滤方式。
  • 抱歉我的错误,我错过了右括号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多