mysql - 一个sql的问题
PHP中文网
PHP中文网 2017-04-17 14:44:08
0
4
799

stat表 字段 uid,act,time
我想取出每个uid最近的一个act
我现在的sql:

select * from (select * from stat order by uid,time desc) a group by uid

这个表数据量比较大,查起来有点慢,有没有更好的办法

甚至这个:

select act,count(*) num from (select * from (select * from stat order by uid,time desc) a group by uid) b group by act

表:

CREATE TABLE `stat` (
  `uid` varchar(40) COLLATE utf8_unicode_ci NOT NULL,
  `act` bigint(20) NOT NULL,
  `time` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`uid`,`act`),
  KEY `index_time` (`time`) USING BTREE,
  KEY `index_act` (`act`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
PHP中文网
PHP中文网

认证0级讲师

全員に返信(4)
刘奇

最初に私の意見を述べさせていただきます。間違いがあれば修正してください。
まず質問者のSQL文は間違っていると思いますが、group byを実行するのはデータベースの実装機構に依存しているだけなので結果は正しいと思われます。たとえば、並べ替え順序を変更すると、結果は間違ったものになります。
group byを使用した後、サブジェクトがクエリできるフィールドは、データベースがAfterに準拠しているため、集計関数またはgroup byのフィールドのいずれかになります。 uid がグループ化されると、act フィールドと time フィールドの値のセットがランダムに選択されます。質問のSQLは正常に動作しているようです。ソート後、データベースはデフォルトで最もソートされたものを選択するはずです。
正しい SQL は次のようになると思います。

select stat.* from stat ,(select uid,max(time) as time from stat group by uid) tmp where stat.uid=tmp.uid and stat.time=tmp.time;

まず、グループ内の各人の最新の実行時間をクエリし、uid と時間に基づいて完全な操作情報を取得します。
対象のデータベースにインデックス付きの uid がある場合でも、この SQL のクエリ効率は許容できるはずです。
ちょっと個人的な意見です。

元のベースにいくつかの変更を加えたところ、ローカル テストのパフォーマンスがわずかに向上しました。ローカル テスト データは 30,000 セットです。

select stat.* from stat ,(select uid,max(time) as time from stat group by uid order by null) tmp where stat.time=tmp.time and stat.uid=tmp.uid; 
いいねを押す +0
左手右手慢动作

クエリ条件の列にインデックス、B 番号インデックス、B+ 番号インデックスなどを作成してみてください。

作成方法の詳細については、Baidu で検索できます。

いいねを押す +0
左手右手慢动作

このステートメントにネストされたサブクエリが必要なのはなぜですか? 1 つのステートメントで実行できないのでしょうか? ロジックはあまり明確ではありませんが、通常の状況ではクエリ情報を出力するために Explain を使用します。

いいねを押す +0
Ty80

グループ化は 1 つで十分ですが、なぜ 2 つのレイヤーを記述する必要があるのですか

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート