2016-11-25 81 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