2017-06-06 71 views
0

这里是我的查询:什么是投票表的最佳索引?

SELECT qa.id, 
     qa.subject, 
     qa.category cat, 
     qa.keywords tags, 
     qa.body_html, 
     qa.amount, 
     qa.visibility, 
     qa.date_time, 
     COALESCE(u.reputation, 'N') reputation, 
     COALESCE(CONCAT(u.user_fname, ' ', u.user_lname), 'unknown') name, 
     COALESCE(u.avatar, 'anonymous.png') avatar, 

    (SELECT COALESCE(sum(vv.value),0) 
    FROM votes vv 
    WHERE qa.id = vv.post_id 
    AND 15 = vv.table_code) AS total_votes, 

    (SELECT COALESCE(sum(vt.total_viewed),0) 
    FROM viewed_total vt 
    WHERE qa.id = vt.post_id 
    AND 15 = vt.table_code 
    LIMIT 1) AS total_viewed 
FROM qanda qa 
LEFT JOIN users u ON qa.author_id = u.id 
AND qa.visibility = 1 
WHERE qa.type = 0 
ORDER BY qa.date_time DESC 
LIMIT 0, 
     11; 

这里是EXPLAIN结果:

enter image description here

看到了吗?最后一行(vv)不会使任何索引受益。而且,这里是在votes表中的当前索引:

enter image description here

总之,什么是你的建议吗?我需要什么指数才能使表现更好?

+0

表的表决是否包含大量的数据或大量的共货币?你为什么不在柱子post_id的VOTE上添加PK,那么你在post_id上有唯一的数据和索引,你可以在post_id和table_code上添加索引,因为你在where条件中选择ti – Moudiz

+0

另外,LIMIT 1似乎是多余 – Strawberry

回答

0

我认为你需要将qa.visibility = 1LEFT JOIN..ON移动到WHERE。一旦你这样做,有这些指标:

qanda: INDEX(visibility, type, date_time) -- date_time must be last 

这将彻底处理WHEREORDER BYLIMIT - 这可能是在性能上的最大提升。

vv and vt: INDEX(post_id, table_code) -- in either order 

您好像有(post_id, table_code, user_id)。如果这是唯一的,那么将其推广为PRIMARY KEY并摆脱id;这将会带来额外的提升。我们假设usersPRIMARY KEY(id)

vt子查询不需要LIMIT 1

如果您需要进一步讨论,请为每个表提供SHOW CREATE TABLE

+0

请看看你的段落:*“你好像有..”* ..!是的,所以你的意思是我可以删除'ID'列?老实说,没有'id'列的表是很奇怪的':-)',不是吗? – stack

+0

没有_primary key_的表很奇怪。通常,“自然PK”在各种方面比人工“ID”更好。 InnoDB在通过二级索引查找时,获取PK('id',在次级BTree的叶节点处),然后通过PK进行第二次查找。通过将索引移动到PK中(如果它是唯一的),让查找只需一步,而不是两步。 –

相关问题