1

さまざまなオブジェクトでのさまざまなユーザーによる1つの特定のアクションの発生をカウントするテーブルがあります。

CREATE TABLE `Actions` (
    `object_id` int(10) unsigned NOT NULL,
    `user_id` int(10) unsigned NOT NULL,
    `actionTime` datetime
);

ユーザーがこのアクションを実行するたびに、行が挿入されます。各オブジェクトで実行されたアクションの数を数え、「アクティビティ」でオブジェクトを並べ替えることができます。

SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count;

結果を上位n個のオブジェクトに制限するにはどうすればよいですか?LIMIT句は集計の前に適用されるため、間違った結果になります。テーブルは潜在的に巨大(数百万行)であり、おそらく1分間に数十回カウントする必要があるため、これを可能な限り効率的に実行したいと思います。

編集:実際には、マシンは正しいです、そして私はLIMITが適用される時間に間違っていました。私のクエリは正しい結果を返しましたが、それらを提示するGUIは私を失望させました...この種の質問は、この質問を無意味にします。ごめん!

4

4 に答える 4

2

実際には...LIMITは、最終的なHAVING句の後の最後に適用されます。したがって、誤った結果が得られることはありません。ただし、LIMITは最後に適用されるため、結果を切り取る前に一時テーブルを作成してアクションカウントの順に並べ替える必要があるため、クエリをより高速に実行することはできません。また、降順で並べ替えることを忘れないでください。

SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count DESC
LIMIT 10;

最適化のためにobject_idにインデックスを追加してみてください。このようにして、アクションテーブルの代わりにインデックスのみをスキャンする必要があります。

于 2009-05-26T20:26:37.687 に答える
1

どうですか:

SELECT * FROM
(
SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count
)
LIMIT 15

また、含める必要のあるアクションの最小数をある程度測定できる場合(たとえば、上位n個のアクションが確実に1000を超える場合)、HAVING句を追加することで効率を上げることができます。

SELECT * FROM
(
SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
HAVING action_count > 1000
ORDER BY action_count
)
LIMIT 15
于 2009-05-26T20:20:46.297 に答える
1

このスレッドは2年前のものですが、stackflowはそれでも関連性があると判断しているので、$0.02を使用します。ORDER BY句は計算コストが非常に高いため、大きなテーブルでは使用しないでください。私が使用したトリック(一部はJoeCelkoのSQLfor Smartiesから)は次のようなものです。

SELECT COUNT(*) AS counter, t0.object_id FROM (SELECT COUNT(*), actions.object_id FROM actions GROUP BY id) AS t0, (SELECT COUNT(*), actions.object_id FROM actions GROUP BY id) AS t1 WHERE t0.object_id < t1.object_id  GROUP BY object_id HAVING counter < 15

ソートせずに編集された上位15個のオブジェクトを表示します。v5以降、mysqlは正確に重複する(空白を含む)クエリの結果セットのみをキャッシュするため、ネストされたクエリはキャッシュされないことに注意してください。ビューを使用すると、その問題は解決します。

はい、2つではなく3つのクエリであり、唯一の利点は、グループ化されたクエリを並べ替える必要がないことですが、グループが多い場合は、より高速になります。

補足:クエリは、並べ替えなしの中央値関数に非常に便利です

于 2011-03-03T00:47:12.783 に答える
0
SELECT * FROM (SELECT object_id, count(object_id) AS action_count 
        FROM `Actions` 
        GROUP BY object_id 
        ORDER BY action_count) LIMIT 10;
于 2009-05-26T20:20:44.673 に答える