0

テーブルにデータを入力しようとしています。クエリは、約 5,000 万レコードを含むテーブルで実行されています。私が現在使用しているクエリは以下のとおりです。templateID に一致し、BETWEEN2 つの UNIX タイムスタンプである行の数をカウントします。

SELECT COUNT(*) as count FROM `s_log` 
WHERE `time_sent` BETWEEN '1346904000' AND '1346993271' 
AND `template` = '1'

上記のクエリは機能しますが、それぞれをループしている間はパフォーマンスがかなり遅くtemplateなり、数百になることもあります。タイムスタンプはint適切にインデックス化されて保存されます。テストするために、time_sent制限を省略して以下のクエリを実行してみました。

SELECT COUNT(*) as count FROM `s_log` 
AND `template` = '1'

予想どおり、非常に高速に実行されますが、カウント結果が正しい時間枠内に制限されていないことは明らかです。2 つの UNIX タイムスタンプtemplateをカウントする特定の AND 制限のカウントを取得するにはどうすればよいですか?BETWEEN

EXPLAIN:

1 | シンプル | s_log | 参照 | time_sent,テンプレート | テンプレート | 4 | 定数 | 71925 | where の使用

SHOW CREATE TABLE s_log:

CREATE TABLE `s_log` (
 `id` int(255) NOT NULL AUTO_INCREMENT,
 `email` varchar(255) NOT NULL,
 `time_sent` int(25) NOT NULL,
 `template` int(55) NOT NULL,
 `key` varchar(255) NOT NULL,
 `node_id` int(55) NOT NULL,
 `status` varchar(55) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `email` (`email`),
 KEY `time_sent` (`time_sent`),
 KEY `template` (`template`),
 KEY `node_id` (`node_id`),
 KEY `key` (`key`),
 KEY `status` (`status`),
 KEY `timestamp` (`timestamp`)
) ENGINE=MyISAM AUTO_INCREMENT=2078966 DEFAULT CHARSET=latin1
4

3 に答える 3

1

この場合に最適なインデックスは複合インデックスですtemplate + time_sent

CREATE INDEX template_time_sent ON s_log (template, time_sent)

PS: また、クエリ内のすべての列が整数である限り、それらの値を引用符で囲まないでください(場合によっては、少なくとも古いバージョンの mysql では問題が発生する可能性があります)。

于 2012-09-07T05:22:37.103 に答える
0

最初に、両方の列を (別々ではなく) まとめたインデックスを作成する必要があります。また、テーブルの種類を確認してください。テーブルがinnoDBの場合はうまくいくと思います。

最後に、WHERE 句を次のように使用します。

`WHEREtemplate = '1' ANDtime_sent` BETWEEN '1346904000' AND '1346993271'

これが行うことは、最初にテンプレートが 1 であるかどうかをチェックし、そうである場合は 2 番目の条件をチェックし、それ以外の場合はスキップします。これにより、間違いなくパフォーマンスが向上します

于 2012-09-07T06:23:06.890 に答える
0

テンプレートごとにクエリを呼び出す必要がある場合は、次を使用して 1 回のクエリ呼び出しですべての情報を取得する方が高速になる可能性がありますGROUP BY

SELECT template, COUNT(*) as count FROM `s_log` 
WHERE `time_sent` BETWEEN 1346904000 AND 1346993271;
GROUP BY template

これはより高速であり、コードを少し再設計する必要があるという推測に過ぎません。


InnoDBの代わりに 使用することもできますMyISAMInnoDB大きなテーブルでパフォーマンスが向上する可能性があるクラスター化インデックスを使用します。MySQL サイトから:

行データはインデックス検索が導く同じページにあるため、クラスター化インデックスを介して行にアクセスするのは高速です。テーブルが大きい場合、インデックス レコードとは別のページを使用して行データを格納するストレージ組織と比較すると、クラスター化インデックス アーキテクチャは多くの場合、ディスク I/O 操作を節約します。(たとえば、MyISAM はデータ行用に 1 つのファイルを使用し、インデックス レコード用に別のファイルを使用します。)

との間のパフォーマンスについて議論する Stackoverflow に関するいくつかの質問がありInnoDBますMyISAM

于 2012-09-07T06:40:47.630 に答える