实体框架将StartsWith转换为MySQL的Locate,MySQL的Locate不使用索引

时间:2014-01-11 03:03:29

标签: mysql sql linq entity-framework

我正在使用MySQL的实体框架和我的Linq查询:

db.Persons.Where(x => x.Surname.StartsWith("Zyw")).ToList();

..正在生成SQL:

SELECT PersonId, Forename, Surname
FROM Person
WHERE (LOCATE('Zyw', Surname)) = 1

...而且似乎没有在Surname上使用索引。

如果LOCATE替换为等效的LIKE,则查询会快速返回所需的结果。因为它需要整个下午。

为什么Entity Framework及其连接驱动程序选择了这个奇怪的LOCATE函数/如何让它使用LIKE代替/为什么MySQL为LOCATE函数做出糟糕的索引决定/我该如何让它变得更好?

更新

我担心我为这篇文章简化了我的代码,Linq产生错误实际上是:

var target = "Zyw";
db.Persons.Where(x => x.Surname.StartsWith(target)).ToList();

如果目标术语是硬编码的,则生成的SQL确实使用LIKE,但是使用变量术语,SQL将更改为使用LOCATE。

这些都是使用MySQL Installer 5.6.15提供的最新的通用MySQL for Windows。

更新

与赏金相关的更多笔记;我正在使用:

  • Visual Studio 2010
  • EntityFramework 6.0.2
  • MySQL Installer 5.6.15, 反过来给出:
    • MySql.Data 6.7.4
    • MySql.Data.Entities 6.7.4

实体框架代码是生成数据库的第一种样式。

我也尝试过使用Nuget的最新连接器(MySql.Data 6.8.3),问题仍然存在。

2 个答案:

答案 0 :(得分:1)

您的问题很可能是由以下原因造成的:

  1. 您使用的是the bug的旧连接器。

  2. 您有一个特殊情况(使用变量来保存.Contains搜索),描述为错误here

  3. 您的案件是否属于这些案件?

答案 1 :(得分:1)

这看起来像MySQL bug #64935对我的回归。

我可以确认,使用相同版本的EF6和MySQL Connector,我也得到了相同的SQL:

context.stoppoints.Where(sp => sp.derivedName.StartsWith(stopName));

...记录为:

SELECT
`Extent1`.`primaryCode`, 
...
`Extent1`.`stop_timezone`
FROM `stoppoints` AS `Extent1`
 WHERE (LOCATE(@p__linq__0, `Extent1`.`derivedName`)) = 1

实体框架:6.0.2 MySQL Connector.Net:6.8.3

我有reported this作为MySQL错误回归。