【发布时间】:2021-07-16 09:33:43
【问题描述】:
我有一个表,其中包含一个类似于布尔值的字段“阻塞”(作为不可为空的 tinyint),我有一个索引。
跑步
SELECT `p`.`Id`
FROM `ProjectTasks` AS `p`
WHERE `p`.`Blocked` > 0
ORDER BY `p`.`Id`
或
SELECT `p`.`Id`
FROM `ProjectTasks` AS `p`
WHERE `p`.`Blocked`
都很快(MySql Workbench 显示 0.000 秒)。
但正在运行
SELECT `p`.`Id`
FROM `ProjectTasks` AS `p`
WHERE `p`.`Blocked`
ORDER BY `p`.`Id`
非常慢(返回 50.000 个条目中的约 50 个时需要 0.5 秒)。
使用 EXPLAIN 表示后面的查询没有用到 Index。
不幸的是,我不能只添加> 0,因为查询是由 EF Core 生成的。我可以对索引进行任何更改,以便将其与最新版本的查询一起使用吗?
【问题讨论】:
-
您实际上可以告诉 EF Core 为您定义选定列的索引,这将确保您的查询在查询某些列时使用索引。看看文档。 docs.microsoft.com/en-us/ef/core/modeling/…
-
通过
(Blocked, Id)创建一个索引并使用WHERE `p`.`Blocked` = 1 ORDER BY `p`.`Id`(如果它是“boolean-like NOT NULL”那么它的值只有0和1)。 -
@MaulikParmar 我已经有
modelBuilder.Entity<ProjectTask>().HasIndex(pt => new { pt.Blocked });(并且刚刚添加了另一个带有 Blocked,Id 的索引),但它没有被使用。 @Akina 我已经添加了索引,但是WHERE p.Blocked没有使用它。我无法添加= 1,因为查询是由 EF Core 生成的。 -
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ProjectTask>() .HasIndex(pt => new { pt.id, pt.Blocked }); }你能确认你的数据库已经定义了索引吗?如果不只是迁移模型,请重新创建以便它实际创建索引。索引在创建表或迁移的同时创建。确保它在那里,mysql也支持布尔类型,为什么不使用它应该没有问题。 -
查询速度慢可能有多种原因,可能是 io 或内存不足、页面大小过小等。如果您可以确认索引存在并使用,那么我们可以缩小导致问题的范围。跨度>
标签: mysql performance entity-framework-core