0

実行に 1 秒以上かかることがある MySQL クエリがあります。クエリは次のとおりです。

SELECT `id`,`totaldistance` FROM `alltrackers` WHERE `deviceid`='FT_99000083426364' AND (`gpsdatetime` BETWEEN 1341100800 AND 1342483200) ORDER BY `id` DESC LIMIT 1

このクエリは、月の特定の日などに行を取得するためにループで実行されます。これにより、ページの読み込みに 25 秒以上かかることがあります...

テーブル構造は次のとおりです。

CREATE TABLE IF NOT EXISTS `alltrackers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `deviceid` varchar(50) NOT NULL,
  `lat` double NOT NULL,
  `long` double NOT NULL,
  `gpsdatetime` int(11) NOT NULL,
  `version` int(11) DEFAULT NULL,
  `totaldistance` int(11) NOT NULL DEFAULT '0',
  `distanceprocessed` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_deviceid` (`id`,`deviceid`),
  UNIQUE KEY `deviceid_id` (`deviceid`,`id`),
  KEY `deviceid` (`deviceid`),
  KEY `deviceid_gpsdatetime` (`deviceid`,`gpsdatetime`),
  KEY `gpsdatetime_deviceid` (`gpsdatetime`,`deviceid`),
  KEY `gpsdatetime` (`gpsdatetime`),
  KEY `id_deviceid_gpsdatetime` (`id`,`deviceid`,`gpsdatetime`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=677242 ;

MySQLにクエリのインデックスを使用させるために、あらゆる種類のインデックスの組み合わせを追加しました(どれを削除するか教えてください)が、役に立ちません。

EXPLAIN の出力は次のとおりです。

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
1 SIMPLE alltrackers index deviceid_id,deviceid,deviceid_gpsdatetime,gpsdatet... PRIMARY 4 NULL 677238 Using where 

ORDER BY ASC/DESC LIMIT 1 を使用している理由は、クエリの最初と最後の行が必要だからです。LIMIT 1 なしでクエリを実行し、PHP を使用して最初と最後の行を取得する方が高速でしょうか?

助けてくれて本当にありがとうございます!

4

2 に答える 2

0

頭のてっぺんから思いつくことができるいくつかのこと:

1.) 私は決して mySQL/DBA の第一人者ではありませんが、そこにあるインデックスは少しやり過ぎのようです。通常、クエリが実行される列または結合される列がインデックス化されていることを確認します。したがって、deviceid と gpsdatetime 用に 1 つ必要です。クエリごとに 1 秒というのは恐ろしいことではないため、ここでのリターンは限られている可能性があります。

2.) ループをなくすようにしてください。データベースに 25 回戻る場合。接続を開いたり閉じたりするだけでオーバーヘッドが発生します。一度データベースにアクセスしてから、PHP を使用して結果を処理し、必要な最終データを取得する方が高速な場合があります。

于 2012-08-11T13:24:49.433 に答える
0

あなたの正確なケースについては言えませんが、すべての行を照会し、最初の行を除くすべてを無視する方が limit ステートメントよりも高速であることがわかりました (ただし、これは SQL Server を使用していました)。やり方は簡単です - limit 1 句を削除して試してみてください。その後、PHP を使用して最初と最後を読み取ることができるため、MySQL インスタンスの負荷を軽減できます (つまり、2 つではなく単一のクエリを実行します)。

ちなみに、id_deviceid と deviceid_id という同じ列を持つ 2 つの一意のキーがあるのはなぜですか? すべてのインデックスを削除してから、再度追加します。高速な DB には、できるだけ少ないインデックスが必要です。

于 2012-08-11T13:25:06.757 に答える