EF SQL 查询逗号分隔字符串 ID 的性能

EF SQL query Performance on comma-separated string Ids

关联ID的存储和查询,哪种方式查询速度和性能最好?特别是在主table中有大量记录,比如100,000条记录。

1- 使用逗号分隔的字符串字段作为 ID :

query.Where(x => (',' + x.Ids + ',').Contains(',' + value + ','));

2- 使用单独的 table 和连接操作:

query.Where(x => x.SecondaryTable.Any(s => s.Id == value));

第一个选项对 dynamically-generated 字符串执行字符串比较,因此索引不可能提高查询性能。会特别慢。

第二个选项是对索引主键执行数字比较(假设 Id 是某种数字类型并且它是主键)。这是一个让您的处理器进行评估的比较速度要快得多,而且它是一个简单的比较,不会为所述比较生成动态数据。

如果您将 ID 存储为逗号分隔的字符串 - 您总是会进行 TABLE/INDEX 扫描。如果你的 table 很小,它就足够了。

使用 SecondaryTable table 存储与主要关联的 ID table 还有很多其他计划:

  1. 您可以保持原样并信任或不信任数据库引擎优化器
query = query.Where(x => x.SecondaryTable.Any(s => s.Id == value));
  1. 如果 (MainId, Id) 对是唯一的。以下查询肯定会命中 index
var query = 
   from m in query
   from s in m.SecondaryTable.Where(s => s.Id == value)
   select s;
  1. 如果 (MainId, Id) 对不是唯一的。
var secondary = db.SecondaryTable.Where(s => s.Id == value);
var mainIds = secondary.Select(s => new { s.MainId }).Distinct();

query = 
   from m in query
   from s in mainIds.Where(s => s.MainId == m.Id)
   select m;

无论如何,最好测试和检查执行计划。