2016-04-05 6 views
0

サーバ上でmysqlのパフォーマンスに重大な問題があります。私は非常に大きなテーブルを持っていますが、特に行数(〜900,000行)ではなく、列数(〜90列)と多くのインデックス(〜30インデックス)(これはInnodbテーブルです)を持っています。メモリ不足のMysqlパフォーマンス

私はしばらくの間、任意のクエリをしたdidntの後、私はテーブルからのカウント(*)を行うと、クエリが時間のlaaaaarge量を取ることができ、ここではショーPROCESSLISTの結果である:

| Command | Time | State  | Info                      | 
| Query | 430 | Sending data | SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null) | 

mysql> SELECT SQL_NO_CACHE COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null); 
+----------+ 
| COUNT(*) | 
+----------+ 
| 900872 | 
+----------+ 
1 row in set (0.66 sec) 

またはキャッシュを持つ::私は後にキャッシュなしでそれをしようとすると、カウント(*)を行う、とする

ほとんど10mn

mysql> SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null); 
+----------+ 
| COUNT(*) | 
+----------+ 
| 900872 | 
+----------+ 
1 row in set (0.00 sec) 

この表のmysqlは何10mnのためにできるのですか?多分それは記憶がないのでしょうか?スワップは、サーバー上でかなりの高いです...

編集:ここSHOW CREATE TABLESHOW TABLE STATUS LIKE 'CATALOG';を提供してくださいクエリ

mysql> explain SELECT COUNT(*) FROM CATALOG where PUBLISH = 1 and (Exclusions = 2 or Exclusions is null); 
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+ 
| 1 | SIMPLE  | CATALOG | ALL | NULL   | NULL | NULL | NULL | 905537 | Using where | 
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+ 
1 row in set (0.14 sec) 
+1

count(*)はすべての列を使用します。 COUNT(1)を使用するとどうなりますか? – Random

+0

^ええ、具体的であるかもしれません。また、あなたのインデックスがあなたのクエリにとってそれほど良いものではないかもしれません。インデックスを使用する代わりに、テーブル全体のスキャンに戻りました。 –

+1

カウントクエリのEXPLAINを使用して、使用している可能性のある30個のインデックスのうちのどれがあるかを確認しましたか? –

答えて

0

の説明です。

インデックスが30個多いです。

INDEX(PUBLISH, Exclusions) 

このクエリの最適な指標になります。 EXPLAINUsing whereの代わりにUsing indexと表示されます。

EXPLAINに基づいて、テーブルスキャンを行いました。 0.66sは悪くないです。キャッシュされたバージョンは無関係です。それは "クエリキャッシュ"でクエリを見つけ、実際の作業をせずに結果を返しました。 InnoDBは "buffer_pool"を持っています。これはテーブル全体を含んでいるように見えます。そのため、0.66s、明らかにI/Oはありません。

innodb_buffer_pool_sizeの値は何ですか?

「このテーブルでmysqlが10mnでできることはありますか?」 - 何を聞いていますか;何が 'mn'ですか? MySQLは事実上あらゆるサイズのテーブルを扱うことができます。表スキャンは、表が大きくなるにつれて時間がかかります。テーブルがbuffer_poolより大きくなると、テーブルスキャンがI/Oバウンドになり、このクエリが大幅に遅くなります。しかし、それは(最終的に)終わるでしょう。 (私は出力のどこにでも "10 "が表示されません)

"スワップ"するように、あまりにも多くのRAMを使用するようにMySQLを構成すると、パフォーマンスが実際に悪くなります。一行ルール:buffer_poolは約70%または使用可能なRAMでなければなりません。小さい方が効率が悪い。スワップする大きな脅威。

このテーブルはどのエンジンですか? MyISAMの場合、他の操作によってテーブルがロックされる可能性があります。 InnoDBは一般的に優れています。

COUNT(*)これは通常の方法です。 COUNT(1)は、同じ努力で同じ答えをあなたに与えます。 COUNT(col)は、をNULLとしてチェックする負担があります。

あなたがそれを求める以外は、ALTERまたはOPTIMIZEでインデックスを再構築しません。インデックスは徐々に維持されます。まれな例外を除いて、それらは常に最適な形式になっています。

問題を引き起こしていることがわからない場合、メモリを倍増させることは費用対効果に優れない可能性があります。