2014-09-04 79 views
0

我有一个用户投票的大表。我尝试了几乎所有关于INDEX用法的教程和文章,并且在失败之后...每个可能的字段组合都作为键,但是查询保持缓慢。缓慢的MySQL查询索引

有没有我可以用来加快速度的指标?

(我会饶你我hidious企图indizes到目前为止...)

CREATE TABLE IF NOT EXISTS `votes` (
    `uid` varchar(100) COLLATE utf8_unicode_ci NOT NULL, 
    `objectId` bigint(15) NOT NULL, 
    `vote` tinyint(1) NOT NULL, 
    `created` datetime NOT NULL, 
    UNIQUE KEY `unique input` (`uid`,`objectId`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

表有130万左右行,并会继续增长。这是我正在尝试的查询:

EXPLAIN SELECT objectId, COUNT(uid) AS voteCount, AVG(vote) AS rating 
FROM votes 
GROUP BY objectId 

任何指针?

回答

2

我可以建议的唯一方法是以下,但我不知道它是否会提高性能。它假定你有一个Objects表,每ObjectId一行:

SELECT ObjectId, 
     (select count(*) from votes v where v.objectid = o.objectid) as votecount, 
     (select avg(vote) from votes v where v.objectid = o.objectid) as rating 
FROM objects o; 

那么你一定要以下指标:votes(objectid, vote)

这将用索引扫描替换外部group by,这可能会加快查询速度。

+0

你的权利,我忘记了我的示例SQL中的objectId ...固定 – ToBe 2014-09-04 11:16:23

+0

你确定Optimizer实际上会更快与这两个子查询,而不是一个组? – ToBe 2014-09-04 11:17:23

+0

@ToBe。 。 。不,我说这是值得一试的。这在某些情况下可能会有所帮助,但我不知道在您的情况下它是否会更好。我更喜欢明确的“按组”方式,但有时你必须尝试欺骗引擎。 – 2014-09-04 11:26:27

1

我不明白索引如何加快速度,因为平均函数将要求您与每一行进行交互。没有WHERE子句。

也许你可以创建一个VIEW来分摊你的成本。

+0

我会尝试查看想法。 – ToBe 2014-09-04 11:01:09

1

我认为duffymo是正确的。但是,您可以尝试交换周围唯一密钥中的两列(或仅添加objectid的索引),因为它可能帮助GROUP BY 可能

+0

我注意到它使用'objectId'上的索引,但是只有当我抛弃了'vote'的任何聚合时,无论我使用什么聚合。 – ToBe 2014-09-04 10:59:19

+0

太糟糕了,duffymo是正确的,它总是要做一个全表扫描来完成聚合(我怀疑计数正在完成索引)。 – Giles 2014-09-04 11:21:27