用于4表联接的MySQL表索引

用于4表联接的MySQL表索引,mysql,optimization,indexing,Mysql,Optimization,Indexing,我有四张桌子: activity (activity_id (PRIMARY), item_id, geolat, geolng, user_id, created_at) users (user_id (PRIMARY), user_name, first_name, last_name, user_banned) items (item_id (PRIMARY), item_name) ratings (item_id (PRIMARY), avg_rating_score) 我想运行以下

我有四张桌子:

activity (activity_id (PRIMARY), item_id, geolat, geolng, user_id, created_at)
users (user_id (PRIMARY), user_name, first_name, last_name, user_banned)
items (item_id (PRIMARY), item_name)
ratings (item_id (PRIMARY), avg_rating_score)
我想运行以下查询:

SELECT item_name, count(distinct activity.user_id) as distinct_user_count, ratings.avg_rating_score
FROM activity
INNER JOIN users on activity.user_id = users.user_id
INNER JOIN items on activity.item_id = items.item_id
INNER JOIN ratings on activity.item_id = ratings.item_id
WHERE activity.user_id != 1
AND (activity.geolat BETWEEN 'XXXXX' and 'XXXX' and activity.geolng BETWEEN 'XXXX' and 'XXXX') 
AND (users.user_banned = 0)
GROUP by activity.item_id
HAVING distinct_user_count >= 5
ORDER by avg_rating_score DESC
LIMIT 0,5
我正在努力为这个连接使用正确的索引。现在我有:

ALTER TABLE activity ADD INDEX (user_id)
ALTER TABLE activity ADD INDEX (item_id)
ALTER TABLE activity ADD INDEX (geolat)
ALTER TABLE activity ADD INDEX (geolng)
ALTER TABLE users ADD INDEX (user_banned)
查询的目标是获得用户1从未添加的项目列表(在lat/lng半径范围内),这些项目在用户1的本地区至少发生了5次,按照该项目的评级按降序排列,最后不包括任何被禁止的用户


这是最好的方法吗?有没有更好的方法来解决这个问题?它的运行速度非常慢,上面列出的索引。

您忘记了<代码>评级(ITEMIDID)(您有多少个等级)的索引,并考虑创建活动的两个索引:<代码>活动(ITEMID、USEL ID、GEOLAT、GEOLNG)<代码>和<代码>活动(USELID、ITEMITID、GEOLAT、GEOLNG)< /代码>。什么是更严格的地理应用或用户id和项目id?评级有大约70k行。ITEM_ID是该表中的主键。这样做是否会使活动(项目id、用户id、geolat、Geoling)和活动(用户id、项目id、geolat、Geoling)有所不同?我更新了索引,因为它们都是单个的。记住MySQL会自动为主键和外键生成索引。只有当优化器查找所有索引字段(至少是第一个字段)时,复合索引才有意义。