2014-09-04 97 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