1

何百万もの行を含む MYISAM MySQL DB テーブルを使用するように依頼されましたが、最初にクエリを高速化する必要があります。

以前はインデックス作成はまったくありませんでした。「タイプ」列に新しいインデックスを追加しましたが、これは役に立ちましたが、インデックスを作成するのに最適な列が他にあるかどうか知りたいですか?

ここに私のCREATE TABLEがあります:

CREATE TABLE `clicks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`companyid` int(11) DEFAULT '0',
`type` varchar(32) NOT NULL DEFAULT '',
`contextid` int(11) NOT NULL DEFAULT '0',
`period` varchar(16) NOT NULL DEFAULT '',
`timestamp` int(11) NOT NULL DEFAULT '0',
`location` varchar(32) NOT NULL DEFAULT '',
`ip` varchar(32) DEFAULT NULL,
`useragent` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `companyid` (`companyid`,`type`,`period`),
KEY `type` (`type`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

典型的な SELECT ステートメントは、一般にcompanyid,typeおよびcontextid列でフィルタリングします。

例えば:

SELECT period, count(period) as count FROM clicks WHERE contextid in (123) AND timestamp > 123123123 GROUP BY period ORDER BY timestamp ASC

また

SELECT period, count(period) as count FROM clicks WHERE contextid in (123) AND type IN('direct') AND timestamp > 123123123 GROUP BY period ORDER BY timestamp ASC

私の質問の最後の部分は次のとおりです。インデックスを追加したとき、type約 1 時間かかりました。複数のインデックスを追加または削除する場合、1 つのクエリで実行できますか、それとも 1 つずつ実行して待つ必要がありますかそれぞれが終了するには?

ご意見ありがとうございます。

4

5 に答える 5

3

インデックス作成は非常に強力ですが、思ったほど黒魔術ではありません。MySQL の EXPLAIN PLAN 機能について学びます。これは、どこを改善できるかを体系的に見つけるのに役立ちます。

http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html

于 2012-05-22T16:18:21.417 に答える
1

どのインデックスを追加するかは、クエリによって異なります。並べ替え (GROUP BY) または選択 (WHERE) する対象はすべて、インデックスの候補として適しています。

また、 Mysql がどのようにインデックスを使用するかを確認することもできます。

インデックスの追加にかかる時間に関しては、複数のインデックスを追加したい場合は、mysqldump を実行し、.sql ファイルのテーブル構造を手動で編集してから、再インポートすることができます。これには時間がかかる場合がありますが、少なくともすべての変更を一度に行うことができます。ただし、これは実際にテストを行うという考えには適合しません。そのため、このアプローチは注意して使用してください。(同じ構造を持つ多数のテーブルを変更し、それらすべてにいくつかのインデックスを追加したいときにそれを行いました。)

また、100% 確実ではありませんが、インデックスを追加すると、Mysql はインデックスを使用してテーブルのコピーを作成し、元のテーブルを削除すると思います。そのため、サーバー/パーティションに十分なスペースがあることを確認してください。テーブルの現在のサイズとマージンについて。

于 2012-05-22T16:19:11.520 に答える
0

1 つのクエリに複数のインデックスを追加できます。これにより全体的に時間が節約されますが、クエリ全体が完了するまでテーブルにアクセスできなくなります。

ALTER TABLE table1 ADD INDEX `Index1`('col1'),
 ADD INDEX `Index2`('col2')

インデックスに関しては、複雑な問題です。ただし、WHERE 句に含まれるカーディナリティの高い単一の列にインデックスを追加することから始めることをお勧めします。MySQL は、クエリに最適なインデックスを選択して使用しようとします。

パフォーマンスをさらに微調整するには、「companyid」インデックスで実装したマルチカラム インデックスを検討する必要があります。

GROUP BYまたはORDER BY句に至るまでインデックスを利用できるようにするためには、多くの条件に依存しているため、詳細を確認する必要があります。

インデックスを最大限に活用するには、データベース サーバーにインデックス全体をメモリに格納するのに十分な RAM が必要であり、実際にメモリを利用できるようにサーバーを適切に構成する必要があります。

于 2012-05-22T16:43:05.283 に答える
0

私の意見timestampでは、句periodで使用されているため、インデックスを付けることができます。WHERE

また、使用contextid in (123)する代わりに、使用するcontextid = 123代わりにtype IN('direct')使用するtype = 'direct'

于 2012-05-22T16:11:49.900 に答える
0

これはクエリの 1 つです。読みやすいように複数の行に分割されています。

SELECT period, count(period) as count 
FROM clicks 
WHERE contextid in (123) 
AND timestamp > 123123123 
GROUP BY period 
ORDER BY timestamp ASC

これが有効なクエリであるかどうかさえわかりません。GROUP BY と ORDER BY は SQL で一致する必要があると思いました。countGROUP BY は で注文するので、 で注文する必要があると思いますperiod

最適化のためのクエリの重要な部分は WHERE 句です。この場合、 と にインデックスを付けるcontextidtimestamp、クエリが高速化されます。

もちろん、すべての WHERE 句にインデックスを付けることはできません。最も一般的な WHERE 句にインデックスを付けます。

一度に 1 つずつ、既存のテーブルにインデックスを追加します。はい、遅いです。ただし、インデックスを追加する必要があるのは 1 回だけです。

于 2012-05-22T16:14:02.100 に答える