2016-11-25 33 views
1

使用MySQL 5.6和下面的表结构:LINQ查询与FirstOrDefault VS ToArray的

CREATE TABLE `dataitem` (
    `AI` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `ID` binary(16) NOT NULL, 
    `OwnerID` binary(16) NOT NULL, 
    `DataItemTimeUtc` datetime NOT NULL, 
    `DataItemTimeLocal` datetime NOT NULL, 
    `DataItemTimeMicroSeconds` int(11) NOT NULL, 
    `DataItemArrivalTimeUtc` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', 
    `DataItemTimeTimeZoneID` binary(16) NOT NULL, 
    `QuestionID` binary(16) NOT NULL, 
    `QuestionHistoryID` binary(16) DEFAULT NULL, 
    `QuestionAbsolutePositionID` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `GroupSessionIDString` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `DataItemType` int(11) NOT NULL, 
    `DataEntryDevice` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `DataEntryDeviceCradle` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `DataItemXml` longtext COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`AI`), 
    UNIQUE KEY `dataitem_ID_UQ_Idx` (`ID`), 
    KEY `dataitem_OwnerID_Idx` (`OwnerID`), 
    KEY `dataitem_DataItemTimeUtc_Idx` (`DataItemTimeUtc`), 
    KEY `dataitem_QuestionID_Idx` (`QuestionID`), 
    KEY `dataitem_QuestionHistoryID_Idx` (`QuestionHistoryID`), 
    KEY `dataitem_QuestionAbsolutePositionID_Idx` (`QuestionAbsolutePositionID`(255)), 
    KEY `dataitem_DataItemType_Idx` (`DataItemType`) 
) ENGINE=InnoDB AUTO_INCREMENT=23467 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

我遇到事情,我努力理解。下面的查询会导致致命的错误,因为它正在采取永远执行:

 Guid patientid = new Guid("cfed2acf-acbd-4ab2-8c23-7ab0b3a8cfa3"); 
     var latestRecord = (from f in QueryHelper.GetEntityTable<DataItem>() 
           where 
           f.OwnerID == patientid 
           && f.QuestionAbsolutePositionID == "5867FF5EC08B9C0422EFD1359B2802B29A8E167952D381EC70AE53CE6D4C9318" 
           orderby f.DataItemTimeUtc descending 
           select f.ID).FirstOrDefault(); 

但是,如果我改变.FirstOrDefault()来.ToArray()查询运行如Flash和returs 2分的结果。有人可以解释这个吗?

SQL查询从.ToArray()生成的:)从.FirstOrDefault(产生

SELECT t0.`ID` 
FROM `DataItem` AS t0 
WHERE ((t0.`OwnerID` = @p0) AND (t0.`QuestionAbsolutePositionID` = @p1)) 
ORDER BY t0.`DataItemTimeUtc` DESC 
-- p0 = [cfed2acf-acbd-4ab2-8c23-7ab0b3a8cfa3] 
-- p1 = [5867FF5EC08B9C0422EFD1359B2802B29A8E167952D381EC70AE53CE6D4C9318] 

SQL查询:

SELECT t0.`ID` 
FROM `DataItem` AS t0 
WHERE ((t0.`OwnerID` = @p0) AND (t0.`QuestionAbsolutePositionID` = @p1)) 
ORDER BY t0.`DataItemTimeUtc` DESC 
LIMIT 0, 1 
-- p0 = [cfed2acf-acbd-4ab2-8c23-7ab0b3a8cfa3] 
-- p1 = [5867FF5EC08B9C0422EFD1359B2802B29A8E167952D381EC70AE53CE6D4C9318] 
+0

请向我们展示生成的SQL。 –

+0

我已将查询添加到帖子。该表共有5513788行。谢谢 – user1984695

回答

0

首先,弄清楚为什么QuestionAbsolutePositionID需求为1000个字符。它可以小于256,这样做。如果不是,那么问自己是否可以更改为CHARACTER SET ascii。它看起来像十六进制,它适用于ascii。 (很少做“ids”包括重音字母,西里尔文,日文等)。如果这些'修复'都不可能,你可以升级到MySQL 5.7吗?一旦你已经解决了索引大小问题(上面),添加这个'合成'(和'覆盖')索引;应该加快查询:

INDEX(OwnerID, QuestionAbsolutePositionID, DataItemTimeUtc, ID) 

(前两列可以以任何顺序)

如果没有帮助,那么我们需要讨论的@variables。

+0

谢谢瑞克。 QuestionAbsolutePositionID的大小减小到100,现在查询运行速度相当快。 – user1984695