使用 EF4 和 MySql

发布于 2024-10-30 21:15:11 字数 1865 浏览 1 评论 0原文

需要一些使用 EF4 和 MySql 的建议。

我有一个包含大量数据项的表。每个项目都属于一个模块和一个区域。数据项还具有时间戳(刻度)。最常见的用法是应用程序在指定时间后查询模块和区域的数据。数据应该排序。

问题是查询选择了很多行,并且数据库服务器内存不足,导致查询速度非常慢。我尝试将查询限制为 100 个项目,但生成的 sql 仅在选择并排序所有项目后才会应用该限制。

dataRepository.GetData().WithModuleId(ModuleId).InZone(ZoneId).After(ztime).OrderBy(p

=> p.Timestamp).Take(100).ToList();

由 MySql .Net Connector 6.3.6

 SELECT  
`Project1`.`Id`,  
`Project1`.`Data`,  
`Project1`.`Timestamp`,  
`Project1`.`ModuleId`,  
`Project1`.`ZoneId`,  
`Project1`.`Version`,  
`Project1`.`Type`  
FROM (SELECT  
`Extent1`.`Id`,  
`Extent1`.`Data`,  
`Extent1`.`Timestamp`,  
`Extent1`.`ModuleId`,  
`Extent1`.`ZoneId`,  
`Extent1`.`Version`,  
`Extent1`.`Type`  
FROM `DataItems` AS `Extent1`  
 WHERE ((`Extent1`.`ModuleId` = 1) AND (`Extent1`.`ZoneId` = 1)) AND  
(`Extent1`.`Timestamp` > 634376753657189002)) AS `Project1`  
 ORDER BY  
`Timestamp` ASC LIMIT 100  

表定义

CREATE TABLE  `mydb`.`DataItems` (

  `Id` bigint(20) NOT NULL AUTO_INCREMENT,  
  `Data` mediumblob NOT NULL,  
  `Timestamp` bigint(20) NOT NULL,  
  `ModuleId` bigint(20) NOT NULL,  
  `ZoneId` bigint(20) NOT NULL,  
  `Version` int(11) NOT NULL,  
  `Type` varchar(1000) NOT NULL,  
  PRIMARY KEY (`Id`),  
  KEY `IX_FK_ModuleDataItem` (`ModuleId`),  
  KEY `IX_FK_ZoneDataItem` (`ZoneId`),  
  KEY `Index_4` (`Timestamp`),  
  KEY `Index_5` (`ModuleId`,`ZoneId`),  
  CONSTRAINT `FK_ModuleDataItem` FOREIGN KEY (`ModuleId`) REFERENCES  
`Modules` (`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION,  
  CONSTRAINT `FK_ZoneDataItem` FOREIGN KEY (`ZoneId`) REFERENCES `Zones`  
(`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION  
) ENGINE=InnoDB AUTO_INCREMENT=22904 DEFAULT CHARSET=utf8;  

生成 SQL欢迎提出有关如何解决此问题的所有建议。

Need some advice working with EF4 and MySql.

I have a table with lots of data items. Each item belongs to a module and a zone. The data item also has a timestamp (ticks). The most common usage is for the app to query for data after a specified time for a module and a zone. The data should be sorted.

Problem is that the query selects to many rows and the database server will be low on memory resulting in a very slow query. I tried to limit the query to 100 items but the generated sql will only apply the limit after all the items has been selected and sorted.

dataRepository.GetData().WithModuleId(ModuleId).InZone(ZoneId).After(ztime).OrderBy(p

=> p.Timestamp).Take(100).ToList();

Generated SQL by the MySql .Net Connector 6.3.6

 SELECT  
`Project1`.`Id`,  
`Project1`.`Data`,  
`Project1`.`Timestamp`,  
`Project1`.`ModuleId`,  
`Project1`.`ZoneId`,  
`Project1`.`Version`,  
`Project1`.`Type`  
FROM (SELECT  
`Extent1`.`Id`,  
`Extent1`.`Data`,  
`Extent1`.`Timestamp`,  
`Extent1`.`ModuleId`,  
`Extent1`.`ZoneId`,  
`Extent1`.`Version`,  
`Extent1`.`Type`  
FROM `DataItems` AS `Extent1`  
 WHERE ((`Extent1`.`ModuleId` = 1) AND (`Extent1`.`ZoneId` = 1)) AND  
(`Extent1`.`Timestamp` > 634376753657189002)) AS `Project1`  
 ORDER BY  
`Timestamp` ASC LIMIT 100  

Table definition

CREATE TABLE  `mydb`.`DataItems` (

  `Id` bigint(20) NOT NULL AUTO_INCREMENT,  
  `Data` mediumblob NOT NULL,  
  `Timestamp` bigint(20) NOT NULL,  
  `ModuleId` bigint(20) NOT NULL,  
  `ZoneId` bigint(20) NOT NULL,  
  `Version` int(11) NOT NULL,  
  `Type` varchar(1000) NOT NULL,  
  PRIMARY KEY (`Id`),  
  KEY `IX_FK_ModuleDataItem` (`ModuleId`),  
  KEY `IX_FK_ZoneDataItem` (`ZoneId`),  
  KEY `Index_4` (`Timestamp`),  
  KEY `Index_5` (`ModuleId`,`ZoneId`),  
  CONSTRAINT `FK_ModuleDataItem` FOREIGN KEY (`ModuleId`) REFERENCES  
`Modules` (`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION,  
  CONSTRAINT `FK_ZoneDataItem` FOREIGN KEY (`ZoneId`) REFERENCES `Zones`  
(`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION  
) ENGINE=InnoDB AUTO_INCREMENT=22904 DEFAULT CHARSET=utf8;  

All suggestions on how to solve this are welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自找没趣 2024-11-06 21:15:11

你的 GetData() 方法在做什么?我敢打赌它正在对整个表执行查询。这就是为什么你的 Take(100) 最后没有做任何事情。

What's your GetData() method doing? I'd bet it's executing a query on the entire table. And that's why your Take(100) at the end isn't doing anything.

策马西风 2024-11-06 21:15:11

我通过使用此处描述的表拆分方法解决了这个问题:
表拆分在实体框架中

I solved this by using the Table Splitting method described here:
Table splitting in entity framework

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文