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

あなたが提案するインデックスは関連性があります。

ただし、「正しい」または「最適な」インデックス自体はありません。テーブルの完全な構造とカーディナリティを考慮する必要があります。たとえば、次のレコードは (比例して) いくつありis_category_valid = 1ますか? ほとんどのレコードがこの条件を満たす場合、このフィールドのインデックスはほとんど役に立ちません。

根底にある考え方は、「重要度」の高い順に列を含めることです。つまり、最も差別的な列を最初に含めます。たとえば、is_category_validほとんどのカテゴリが「有効」である場合、列をインデックスの最後にプッシュします。

GROUP BY(the節とthe節に出てくる列は例外ですがORDER BY、これはもうご存知のことと思います)

クエリ実行プラン ( EXPLAIN SELECT [your query here]) を見て、クエリがどのように処理されるかを確認してください。さまざまな組み合わせを試して、どれがより効果的かを確認してください。現在の「最適な」インデックスは、データ セットが進化するにつれて最適でなくなる可能性があることに注意してください。

于 2013-07-07T14:40:46.617 に答える
0

RandomSeed には非常に優れた点があります。ただし、あなたが実行していることについては、あなたが求めている最小の粒度でインデックスを最適化しようとします。この場合、特定の「item_ID」を具体的に探しています..それをインデックスの前の位置に移動します。次に、結果の期待値の粒度に基づいて、次の考慮事項として他の基準またはグループ化を行います。Is_Category_Valid と Created_At があります。ほとんどのカテゴリが有効であるため、created_at を 2 番目の位置に配置すると予想されます。これは基本的に、インデックスがアイテム 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 に答える