0

Amazon RDS で MySQL データベースを持つアプリケーションを使用しています。問題の表は次のように設定されています。

CREATE TABLE `log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `timestamp` datetime NOT NULL,
  `username` varchar(45) NOT NULL,
  .. snip some varchar and int fields ..
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

このシステムはしばらくの間ベータ版でしたが、すでにデータセットは非常に大きく、クエリはかなり遅くなり始めています.

SELECT COUNT(*) FROM log --> 16307224 (takes 105 seconds to complete)

このテーブルは、ほとんどの場合、このようなクエリから 1 つのレポートを作成するためにのみ使用されます

SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp  BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

これは通常、完了するまでに約100〜180秒かかる1000〜6000行の何かを提供します。これは、Webアプリケーションがタイムアウトして空のレポートを残すことが多いことを意味します(タイムアウトも調べますが、この質問はルート向けです原因)。

私はデータベースがあまり得意ではありませんが、ここで私を殺しているのは BETWEEN だと思います。私が考えているのは、おそらく何らかの形でタイムスタンプをインデックスとして使用する必要があるということです。タイムスタンプとユーザー名を組み合わせることで、一意性が維持されるはずです (私は id フィールドを何にも使用しません)。

最適化のための提案を持っている人がいれば、私はすべて耳にします。

アップデート:

テーブルは次のように変更されました

CREATE TABLE `log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `timestamp` datetime NOT NULL,
  `username` varchar(45) NOT NULL,
  .. snip ..
  `task_id` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_un_ts` (`timestamp`,`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

EXPLAINSELECTステートメントの次を返します

id => 1
select_type => SIMPLE
table => log
type => range
possible_keys => index_un_ts
key => index_un_ts
key_len => 55
ref => 
rows => 52258
Extra => Using where; Using index
4

1 に答える 1

1

タイムスタンプ列とユーザーIDのインデックスが役立つでしょう。EXPLAIN ステートメントの出力を読み取ることができる必要があります。

MySQL に移動し、次の操作を行います。

EXPLAIN SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp  BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

これは、MySQL がクエリを実行するために使用するプランを示しています。キーという列があります。これは、MySQL がクエリで使用しているインデックスを示します。そこに ALL が表示されると思います。これは、MySQL がテーブルを上から下にスキャンして、すべての行を where 句と一致させていることを意味します。ここで、timestamp 列と userid 列に索引を作成します。EXPLAIN ステートメントを再度実行します。キー列に作成したインデックスが表示されます。

MySQL がインデックスを使用する場合、クエリはかなり高速になります。インデックスを作成しすぎないように注意してください。インデックスを使用すると、挿入、更新、および削除が遅くなります。新しい行をテーブルに挿入し、テーブルに 3 つのインデックスがある場合、新しい行は 3 つの値を 3 つの異なるインデックスに書き込む必要があります。だから諸刃の剣です。

于 2012-04-13T08:20:38.920 に答える