当前位置: 首页 > 面试题库 >

linq to sql startwith性能索引列

经博延
2023-03-14
问题内容

我首先使用实体​​代码。索引列:

  • SourceCatalogId
  • Disabled
  • CategoryPath

表中的4万行

我的问题是查询需要40秒钟!

var result = DBContext.Set<SourceProduct>()
            .Include(x => x.SalesHistories, x => x.SourceCatalog)
            .Where(p => p.SourceCatalogId == 2)
            .where(p => p.Disabled == false)
            .where(x => x.CategoryPath.StartsWith("MyPath"))
            .orderby(x => x.ShortDesignation)
            .Skip(1)
            .Take(10)
            .toList();

通过sql profiler进行的SQL:

exec sp_executesql N'SELECT TOP (10) 
[Project1].[SourceProductId] AS [SourceProductId], 
[Project1].[SourceSKU] AS [SourceSKU], 
[Project1].[SourceCatalogId] AS [SourceCatalogId], 
[Project1].[ManufacturerReference] AS [ManufacturerReference], 
[Project1].[Disabled] AS [Disabled], 
[Project1].[EAN] AS [EAN], 
[Project1].[ShortDesignation] AS [ShortDesignation], 
[Project1].[FullDesignation] AS [FullDesignation], 
[Project1].[Description] AS [Description], 
[Project1].[Url] AS [Url], 
[Project1].[CategoryPath] AS [CategoryPath], 
[Project1].[Condition] AS [Condition], 
[Project1].[BuyingPriceHT] AS [BuyingPriceHT], 
[Project1].[ShippingPriceHT] AS [ShippingPriceHT], 
[Project1].[PublicSellingPriceHT] AS [PublicSellingPriceHT], 
[Project1].[PictureUrl1] AS [PictureUrl1], 
[Project1].[PictureUrl2] AS [PictureUrl2], 
[Project1].[PictureUrl3] AS [PictureUrl3], 
[Project1].[PictureUrl4] AS [PictureUrl4], 
[Project1].[Quantity] AS [Quantity], 
[Project1].[AddDate] AS [AddDate], 
[Project1].[UpdateDate] AS [UpdateDate], 
[Project1].[Followers] AS [Followers]
FROM ( SELECT [Project1].[SourceProductId] AS [SourceProductId], [Project1].[SourceSKU] AS [SourceSKU], [Project1].[SourceCatalogId] AS [SourceCatalogId], [Project1].[ManufacturerReference] AS [ManufacturerReference], [Project1].[Disabled] AS [Disabled], [Project1].[EAN] AS [EAN], [Project1].[ShortDesignation] AS [ShortDesignation], [Project1].[FullDesignation] AS [FullDesignation], [Project1].[Description] AS [Description], [Project1].[Url] AS [Url], [Project1].[CategoryPath] AS [CategoryPath], [Project1].[Condition] AS [Condition], [Project1].[BuyingPriceHT] AS [BuyingPriceHT], [Project1].[ShippingPriceHT] AS [ShippingPriceHT], [Project1].[PublicSellingPriceHT] AS [PublicSellingPriceHT], [Project1].[PictureUrl1] AS [PictureUrl1], [Project1].[PictureUrl2] AS [PictureUrl2], [Project1].[PictureUrl3] AS [PictureUrl3], [Project1].[PictureUrl4] AS [PictureUrl4], [Project1].[Quantity] AS [Quantity], [Project1].[AddDate] AS [AddDate], [Project1].[UpdateDate] AS [UpdateDate], [Project1].[Followers] AS [Followers], row_number() OVER (ORDER BY [Project1].[ShortDesignation] ASC) AS [row_number]
    FROM ( SELECT 
        [Extent1].[SourceProductId] AS [SourceProductId], 
        [Extent1].[SourceSKU] AS [SourceSKU], 
        [Extent1].[SourceCatalogId] AS [SourceCatalogId], 
        [Extent1].[ManufacturerReference] AS [ManufacturerReference], 
        [Extent1].[Disabled] AS [Disabled], 
        [Extent1].[EAN] AS [EAN], 
        [Extent1].[ShortDesignation] AS [ShortDesignation], 
        [Extent1].[FullDesignation] AS [FullDesignation], 
        [Extent1].[Description] AS [Description], 
        [Extent1].[Url] AS [Url], 
        [Extent1].[CategoryPath] AS [CategoryPath], 
        [Extent1].[Condition] AS [Condition], 
        [Extent1].[BuyingPriceHT] AS [BuyingPriceHT], 
        [Extent1].[ShippingPriceHT] AS [ShippingPriceHT], 
        [Extent1].[PublicSellingPriceHT] AS [PublicSellingPriceHT], 
        [Extent1].[PictureUrl1] AS [PictureUrl1], 
        [Extent1].[PictureUrl2] AS [PictureUrl2], 
        [Extent1].[PictureUrl3] AS [PictureUrl3], 
        [Extent1].[PictureUrl4] AS [PictureUrl4], 
        [Extent1].[Quantity] AS [Quantity], 
        [Extent1].[AddDate] AS [AddDate], 
        [Extent1].[UpdateDate] AS [UpdateDate], 
        [Extent1].[Followers] AS [Followers]
        FROM [dbo].[SourceProducts] AS [Extent1]
        WHERE ([Extent1].[SourceCatalogId] = @p__linq__0) AND (0 = [Extent1].[Disabled]) AND ([Extent1].[CategoryPath] LIKE @p__linq__1 ESCAPE N''~'')
    )  AS [Project1]
)  AS [Project1]
WHERE [Project1].[row_number] > 0
ORDER BY [Project1].[ShortDesignation] ASC',N'@p__linq__0 bigint,@p__linq__1 nvarchar(4000)',@p__linq__0=2,@p__linq__1=N'MyPath%'

在where子句中的最后一个子句中,如果我在以下位置删除“ scape N”〜“ ”:

WHERE ([Extent1].[SourceCatalogId] = @p__linq__0) AND (0 = [Extent1].[Disabled]) AND ([Extent1].[CategoryPath] LIKE @p__linq__1 ESCAPE N''~'')

查询需要4秒。

正常吗?索引用途?我如何用startWith解决呢?

编辑

categoryPath的索引属性:

[Index("IX_SourceProduct_SourceCatalogId_Disabled_CategoryPath", 3), StringLength(400)]
    public string CategoryPath { get; set; }

编辑2

好的,我非常接近,我认为问题是存储过程。

string search = "julien";
            var list = db.Users.Where(x => x.Name.StartsWith(search));
            string query = list.ToString();

=> SELECT [Extent1].[UserId] AS [UserId], [Extent1].[Name] AS [Name] FROM [dbo].[Users] AS [Extent1] WHERE [Extent1].[Name] LIKE @p__linq__0 ESCAPE N’~’

var list2 = db.Users.Where(x => x.Name.StartsWith("julien"));
            string query2 = list2.ToString();

=> SELECT [Extent1].[UserId] AS [UserId], [Extent1].[Name] AS [Name] FROM [dbo].[Users] AS [Extent1] WHERE [Extent1].[Name] LIKE N’julien%’

因此,如果我在查询中使用变量获取存储过程,则如果我使用const则获取选择。

在存储过程中(由实体生成)使 @ p__linq__0 出现,因此 在变量中添加 ESCAPE N’〜
以避免wildCaractere。

因此,现在的问题更为简单。如何避免使用变量查询?这是可能的 ?谢谢


问题答案:

因此,这里您需要做的是获取变量的值,并将其用作Expression要生成的变量中的常量。实际上这是完全有可能的。我们需要的是一个表达式,该表达式接受您想要的参数作为实选择器的参数,作为第二个参数,该第二个参数是常量值的占位符,然后是您想要成为常量的值。然后,我们可以用常量的值替换参数的所有实例,只剩下一个将真实参数映射到结果的函数

public static Expression<Func<TSource, TResult>> EmbedConstant
    <TSource, TResult, TConstant>(
    this Expression<Func<TSource, TConstant, TResult>> expression,
    TConstant constant)
{
    var body = expression.Body.Replace(
        expression.Parameters[1],
        Expression.Constant(constant));
    return Expression.Lambda<Func<TSource, TResult>>(
        body, expression.Parameters[0]);
}

这依靠以下方法将一个表达式的所有实例替换为另一个表达式:

public static Expression Replace(this Expression expression,
    Expression searchEx, Expression replaceEx)
{
    return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public ReplaceVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

这使您可以对此进行映射:

string search = "julien";
var list = db.Users.Where(x => x.Name.StartsWith(search));
string query = list.ToString();

变成这个:

string search = "julien";
Expression<Func<User, string, bool>> predicate = 
    (item, searchTerm) => item.Name.StartsWith(searchTerm);
var list = db.Users.Where(predicate.EmbedConstant(search));
string query = list.ToString();


 类似资料:
  • 主要内容:1 独立的列,2 前缀索引和索引选择性,3 多列(组合、联合)索引,3.1 多个单列索引的问题,3.2 使用多列索引,4 选择适合的索引列顺序,5 聚簇(聚集)索引,6 覆盖索引详细介绍了各种高性能的索引使用策略,比如联合索引、索引顺序、聚簇索引、覆盖索引等等,以及常见索引失效的情况。 前面我们已经介绍了各种类型的索引结构及其对应的优缺点: BTREE索引的数据结构以及具体实现原理深入解析 哈希索引的数据结构以及索引的优缺点 正确的创建和使用索引是实现高性能查询的基础。我们通常会看到一

  • 问题内容: 如果我的ID,然后用这些ID,那么查询是比我快会使用的条件。 为了显示: 在相同条件下,上述速度比大约快100倍: 为什么? 注意:该列 已建立 索引。 问题答案: 第二条语句很可能会锁定更多行,而第一条语句使用唯一键并仅锁定要更新的行。

  • 我们将数据导入到elasticsearch集群中的索引很少,每个索引约为10GB。 同时,我们关心对现有索引的搜索,很少是小的-100MB,也很少是大的-10GB。 根据这些文章和拉请求,我们不应该接触合并设置在所有。 在这里非常困惑,任何帮助都非常感谢。

  • 问题内容: varchar列上的索引是否会使查询运行缓慢?我可以将其设为int。而且我不需要做LIKE%比较。 问题答案: varchar列上的索引是否会使查询运行缓慢? 不,不是的。 如果优化器决定使用索引,则查询将运行得更快。 该表上的s / s / s会变慢,但不太可能引起注意。 我不需要做LIKE%比较 请注意,使用: …将 不 使用索引,但以下内容将: 关键是在字符串的左侧使用通配符,这

  • 本文向大家介绍mysql性能优化之索引优化,包括了mysql性能优化之索引优化的使用技巧和注意事项,需要的朋友参考一下   作为免费又高效的数据库,mysql基本是首选。良好的安全连接,自带查询解析、sql语句优化,使用读写锁(细化到行)、事物隔离和多版本并发控制提高并发,完备的事务日志记录,强大的存储引擎提供高效查询(表记录可达百万级),如果是InnoDB,还可在崩溃后进行完整的恢复,优点非常多

  • 主要内容:1 索引扫描排序,2 索引下推,3 压缩(前缀压缩)索引,4 重复、冗余索引和未使用的索引,5 常见索引失效情况,6 三星索引详细介绍了各种高性能的索引使用策略,比如索引排序、索引下推、压缩索引等等,以及常见索引失效的情况。 前面我们已经介绍了各种类型的索引结构及其对应的优缺点: BTREE索引的数据结构以及具体实现原理深入解析 哈希索引的数据结构以及索引的优缺点 正确的创建和使用索引是实现高性能查询的基础。我们通常会看到一些查询不当的使用索引,或者使用MySQL无法使用已有的索引,下