2

何百万行もある次のテーブルがあります。

CREATE TABLE `points` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `DateNumber` int(10) unsigned DEFAULT NULL,
  `Count` int(10) unsigned DEFAULT NULL,
  `FPTKeyId` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  KEY `index3` (`FPTKeyId`,`DateNumber`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=16755134 DEFAULT CHARSET=utf8$$

ご覧のとおり、インデックスを作成しました。私はそれが正しいかどうかはわかりません。問題は、クエリの実行が非常に遅いことです。

簡単なクエリを見てみましょう

SELECT fptkeyid, count FROM points group by fptkeyid

タイムアウト (10 分) によってクエリが中止されるため、結果を取得できません。私は何を間違っていますか?

4

4 に答える 4

3

MySQL のばかげた動作に注意してください: GROUP BYing は暗黙的に実行しORDER BYます。

これを防ぐには、明示的に を追加ORDER BY NULLします。これにより、不要な順序付けが防止されます。

http://dev.mysql.com/doc/refman/5.0/en/select.html言います:

GROUP BY を使用すると、同じ列に対して ORDER BY があるかのように、出力行は GROUP BY 列に従って並べ替えられます。GROUP BY が生成する並べ替えのオーバーヘッドを回避するには、ORDER BY NULL を追加します。

SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;

+

http://dev.mysql.com/doc/refman/5.6/en/group-by-optimization.html言います:

GROUP BY にインデックスを使用するための最も重要な前提条件は、すべての GROUP BY 列が同じインデックスの属性を参照し、インデックスがそのキーを順番に格納することです (たとえば、これは HASHインデックスではなくBTREEインデックスです)。

于 2012-06-30T17:16:38.130 に答える
1

私は個人的にあなたのAUTO_INCREMENT価値から始めます。新しいレコードごとに増加する16,755,134ように設定しました。フィールド値が に設定されてINT UNSIGNEDいます。これは、値の範囲が0 to 4,294,967,295(またはほぼ 43 億) であることを意味します。これは、フィールドがデータ型の制限を超える前にしか256PRIMARY KEY INDEX持たないことを意味し、 .

データ型を に変更するBIGINT UNSIGNEDと、値の範囲が0 to 18,446,744,073,709,551,615(または 18.4 京をわずかに超える) になり、この値で最大1,100,960,700,983(または 1.1 兆をわずかに超える) の一意の値AUTO_INCREMENTを持つことができます。

AUTO_INCREMENT最初に、値をそれほど大きな数に設定する必要があるかどうかを尋ねます。そうでない場合は、フィールド値をvsとして保存するため、それを 1 (または少なくともそれよりも小さい数) に変更することをお勧めします。このような大きなテーブル。いずれにせよ、クエリの改善に役立つより安定したものを取得する必要があります。INTBIGINTPRIMARY KEY INDEX

于 2012-06-30T18:18:52.563 に答える
1

あなたのクエリは意味がありません:

SELECT fptkeyid, count FROM points group by fptkeyid

fptkeyid でグループ化するため、count はここでは役に立ちません。集計関数が必要です。カウント フィールドではありません。次に、そのカウントは MySQL 関数でもあるため、フィールドに同じ名前を使用することはあまり役に立ちません/お勧めできません。

次のようなものは必要ありませんか?

SELECT fptkeyid, SUM(`count`) FROM points group by fptkeyid

そうでない場合は、クエリから期待される結果を説明してください。

あなたの問題と同等のものを見つけることができるかどうかを確認するために、テスト データ、50 万件のレコードを含むデータベースを作成しました。これは説明が私に言うことです:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  points  index   NULL    index3  10  NULL    433756  

SUM クエリでは、次のようになります。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  points  index   NULL    index3  10  NULL    491781   

両方のクエリはラップトップ (macbook air) で 1 秒以内に実行され、時間がかかりません。挿入には時間がかかりましたが、50 万件のレコードを取得するのに数分かかりました。しかし、取得と計算はそうで​​はありません。

あなたの質問に完全に答えるには、さらに多くのことが必要です。メモリがほとんど割り当てられていないなど、データベースの構成が間違っている可能性がありますか?

于 2012-06-30T18:34:14.830 に答える
-1

問題はサーバーの帯域幅だと思います。100 万行あるとしたら、少なくともメガバイトの帯域幅が必要になるでしょう。

于 2012-06-30T16:45:01.993 に答える