3

大きなテーブル(約10Mレコード)を持つMySQLサーバー(5.5)を実行しています。このテーブルは、2 つの列に主キーを持つある種のログです。

id <- integer,
date <- datetime

このデータベースに接続するアプリケーションは、次のようなクエリを送信しています。

SELECT * FROM bigtable  
INNER JOIN other_table
ON ....
WHERE UNIX_TIMESTAMP(date) BETWEEN #somevalue# AND #somevalue2#;

このクエリの実行には非常に時間がかかっていることがわかりました。一部の関数は、MySQL がインデックスを使用するのを防ぎ、代わりにフル テーブル スキャンを実行できることを知っています。

質問: 「... WHERE date BETWEEN '2012:01:01 00:00:00' AND '2012:02:01」の代わりに、示されているように、主キーの列で関数 UNIX_TIMESTAMP を使用することによって、パフォーマンス ヒットはありますか? 00:00:00' " ?

クエリ:

SELECT r.f_registro, r.latitud, r.longitud, r.velocidad, r.status, r.odometro, r.heading, r.sensor, a.nombre FROM registros r INNER JOIN activos a ON a.id_tracker = r.id_tracker WHERE a.id_activo = 2366 AND r.satelites > '3' AND UNIX_TIMESTAMP(r.f_registro) BETWEEN 1342159200 AND 1342760400 ORDER BY r.f_registro

実行には数秒または数分かかります。Explain を実行すると、次のように返されます。

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,a,const,PRIMARY,PRIMARY,4,const,1,"Using filesort"
1,SIMPLE,r,range,"id_tracker,satelites",satelites,4,NULL,1,"Using index condition; Using where"
4

2 に答える 2

7

日付列で関数を使用すると、MySQL が列のインデックスを利用できなくなることは間違いありません。

代わりに、範囲を 2 つの日付定数に計算し、BETWEEN を使用します。

また、日付列にインデックスがあることを示していないことに注意してください。インデックスは最も多くのプレフィックスが付けられたままになるため、id で始まる複合インデックスは、日付のみを要求するクエリには使用できません。

クエリの ON 部分 (除外した部分) は、クエリのパフォーマンスにおいて同様に重要である可能性があり、インデックスも使用できるかどうかを評価する必要があります。

于 2012-07-19T20:29:06.107 に答える