2013-12-16 126 views
4

我有一个名为QuizMatches的表的数据库。该表具有以下结构:性能问题MySQL数据库中的全索引扫描

CREATE TABLE `QuizMatches` (
    `QuizMatchesGuid` binary(16) NOT NULL, 
    `DateStarted` datetime NOT NULL, 
    `LatestChanged` datetime NOT NULL, 
    `HostFBUserToken` varchar(250) NOT NULL, 
    `GuestFBUserToken` varchar(250) NOT NULL, 
    `ArrayOfQuestionIDs` varchar(200) NOT NULL, 
    `ArrayOfQuestionResponseTimesAndAnswersHost` varchar(900) NOT NULL, 
    `ArrayOfQuestionResponseTimesAndAnswersGuest` varchar(900) NOT NULL, 
    `MatchFinished` int(1) NOT NULL DEFAULT '0', 
    `Category` varchar(45) NOT NULL, 
    `JsonQuestions` varchar(4000) NOT NULL DEFAULT '[]', 
    `DateFinished` datetime NOT NULL, 
    `LatestPushSentDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
    PRIMARY KEY (`QuizMatchesGuid`), 
    KEY `HostFBUserTokenIX` (`HostFBUserToken`), 
    KEY `GuestFBUserTokenIX` (`GuestFBUserToken`), 
    KEY `MatchFinishedIX` (`MatchFinished`), 
    KEY `LatestChangedIX` (`LatestChanged`), 
    KEY `LatestPushSentDateIX` (`LatestPushSentDate`), 
    KEY `DateFinishedIX` (`LatestChanged`,`HostFBUserToken`,`GuestFBUserToken`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

有大量在这个表中的行,它是大量使用多个客户端像下面的执行特别查询:

SELECT HEX(QuizMatchesGuid) AS QuizMatchesGuid, DateStarted, 
    LatestChanged, HostFBUserToken, GuestFBUserToken, 
    ArrayOfQuestionIDs, ArrayOfQuestionResponseTimesAndAnswersHost, 
    ArrayOfQuestionResponseTimesAndAnswersGuest, JsonQuestions 
FROM CrystalDBQuiz.QuizMatches 
ORDER BY LatestChanged DESC 
LIMIT 10 

的主要问题似乎是数据库执行完整的索引扫描。我尝试过不同的索引组合,但没有成功。

如果我运行EXPLAIN我收到上述SELECT查询如下:

  id: 1 
    select_type: SIMPLE 
     table: 'QuizMatches' 
     type: index 
possible_keys: NULL 
      key: 'LatestChangedIX' 
     key_len: 8 
      ref: NULL 
     rows: 10 
     Extra: 

有没有一种方法,我可以优化选择如下部分作为对这个数据库表上面的例子?

Neor profiler screenshot

+0

你显示的'SELECT'和它的'EXPLAIN',不会导致全表扫描。 'EXPLAIN'命令的'key'和'rows'输出表明它使用了一个索引。 –

+0

这个解释对我来说看起来很干净,它使用LatestChanged索引来获得排序的行,并在找到其中的10个时立即结束。你为什么认为这很糟糕? – piotrm

+0

据我了解,根据EXPLAIN它做了一个完整的索引扫描?这真的有必要吗?有没有其他方法来改善这个表格和查询? MySQL服务器工作100%,这就是如果我每秒钟做大约10个这样的选择。 –

回答

0

如果使用了分页LIMIT声明,我建议你使用LatestChanged值这是由于订货。所以你的查询将变成

SELECT HEX(QuizMatchesGuid) AS QuizMatchesGuid, DateStarted, LatestChanged, 
HostFBUserToken, GuestFBUserToken, ArrayOfQuestionIDs, 
ArrayOfQuestionResponseTimesAndAnswersHost, 
ArrayOfQuestionResponseTimesAndAnswersGuest, JsonQuestions 
FROM CrystalDBQuiz.QuizMatches 
WHERE LatestChanged<[lastValue] 
ORDER BY LatestChanged DESC 
LIMIT 10 
+0

谢谢,但它不是分页 –