0

我有以下查询:

SELECT venues.venue_name, count( distinct checkin.user_id ) AS total_count, category_id
    FROM checkin
    INNER JOIN venues ON checkin.internal_venue_id = venues.venue_primary_id
    WHERE checkin.item_id = '3783'
    and is_category_valid = 1 and created_at >= DATE_SUB('2013-07-07 12:35:06', INTERVAL 5 DAY)
    GROUP BY checkin.internal_venue_id
    ORDER BY total_count DESC
    LIMIT 10;

我正在努力处理此查询所需的索引。是正确的索引:

checkin: (internal_venue_id, item_id, is_category_valid, created_at, user_id)

还是有其他更理想的查询路径?

4

2 回答 2

0

RandomSeed 有很好的优点。不过,对于您遇到的问题,我会尝试在您所要求的最小粒度上优化索引。在这种情况下,您正在专门寻找给定的“item_ID”.. 将其移动到索引的前面位置。然后,我将根据结果预期的粒度将其他标准或分组作为下一个考虑因素……再次。你有 Is_Category_Valid 和 Created_At.. 我希望因为大多数类别都是有效的,所以我会在第二个位置创建 created_at。这基本上说明索引可以跳转到项目 ID 3783,并在其中转到创建日期 2013-07-07(通过 Date_sub 减少 5 天)。在这一点上,我将通过索引的标准分组,最后是有效的

index (item_id, created_at, interval_venue_id, is_category_valid )

但是,每个查询都是不同的,您确实需要查看获取数据粒度级别的最快方法......并且拥有一个覆盖索引(如果可能)可以防止进入原始页面数据级别的需要有助于实现它也更快。

于 2013-07-07T14:54:22.673 回答
0

您建议的索引是相关的。

但是本身并没有“正确”或“最佳”索引这样的东西,您需要考虑表的完整结构以及基数。例如,有多少条记录(按比例)is_category_valid = 1?如果大多数记录都满足这个条件,那么这个字段上的索引就没什么用了。

基本思想是按“重要性”的顺序包含列,也就是说,首先在最具辨别力的列上。例如,is_category_valid如果大多数类别是“有效的”,我会将列推到索引的末尾。

(出现在GROUP BYORDER BY子句中的列有一个例外,但你已经知道了,所以看起来)

您应该查看查询执行计划 ( EXPLAIN SELECT [your query here]) 并了解如何处理查询。尝试各种组合,看看哪一种表现更好。请记住,随着数据集的发展,今天的“最佳”索引可能会变得不太理想。

于 2013-07-07T14:40:46.617 回答