2016-12-30 11 views
1

私はこのクエリを持っている:クエリでインデックスが使用されていません。パフォーマンスを向上させる方法

SELECT 
    * 
FROM 
    `av_cita` 
JOIN `av_cita_cstm` ON (
    (
     `av_cita`.`id` = `av_cita_cstm`.`id_c` 
    ) 
) 
WHERE 
    av_cita.deleted = 0 

このクエリが終了するのを120秒以上かかり、まだ私はすべてのインデックスを追加しました。

私は実行計画を尋ねる:

explain SELECT * FROM `av_cita` 
     JOIN `av_cita_cstm` ON ((`av_cita`.`id` = `av_cita_cstm`.`id_c`)) 
     WHERE av_cita.deleted = 0; 

を私はこれを取得:

+----+-------------+--------------+--------+----------------------+---------+---------+---------------------------+--------+-------------+ 
| id | select_type | table  | type | possible_keys  | key  | key_len | ref      | rows | Extra  | 
+----+-------------+--------------+--------+----------------------+---------+---------+---------------------------+--------+-------------+ 
| 1 | SIMPLE  | av_cita  | ALL | PRIMARY,delete_index | NULL | NULL | NULL      | 192549 | Using where | 
| 1 | SIMPLE  | av_cita_cstm | eq_ref | PRIMARY    | PRIMARY | 108  | rednacional_v2.av_cita.id |  1 |    | 
+----+-------------+--------------+--------+----------------------+---------+---------+---------------------------+--------+-------------+ 

delete_indexpossible_keys列に表示されますが、キーはnullであり、それは使用されません。インデックス。

表と索引の定義:

+------------------+--------------+------+-----+---------+-------+ 
| Field   | Type   | Null | Key | Default | Extra | 
+------------------+--------------+------+-----+---------+-------+ 
| id    | char(36)  | NO | PRI | NULL |  | 
| name    | varchar(255) | YES | MUL | NULL |  | 
| date_entered  | datetime  | YES | MUL | NULL |  | 
| date_modified | datetime  | YES |  | NULL |  | 
| modified_user_id | char(36)  | YES |  | NULL |  | 
| created_by  | char(36)  | YES | MUL | NULL |  | 
| description  | text   | YES |  | NULL |  | 
| deleted   | tinyint(1) | YES | MUL | 0  |  | 
| assigned_user_id | char(36)  | YES | MUL | NULL |  | 
+------------------+--------------+------+-----+---------+-------+ 
+---------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name   | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+---------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| av_cita |   0 | PRIMARY   |   1 | id    | A   |  192786 |  NULL | NULL |  | BTREE  |   |    | 
| av_cita |   1 | delete_index  |   1 | deleted   | A   |   2 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | name_index   |   1 | name    | A   |  96393 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | date_entered_index |   1 | date_entered  | A   |  96393 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | created_by   |   1 | created_by  | A   |   123 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | assigned_user_id |   1 | assigned_user_id | A   |  1276 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | deleted_id   |   1 | deleted   | A   |   2 |  NULL | NULL | YES | BTREE  |   |    | 
| av_cita |   1 | deleted_id   |   2 | id    | A   |  192786 |  NULL | NULL |  | BTREE  |   |    | 
| av_cita |   1 | id     |   1 | id    | A   |  192786 |  NULL | NULL |  | BTREE  |   |    | 
+---------+------------+--------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

どのように私はこのクエリのパフォーマンスを向上させることができますか?

+0

'av_cita'のテーブルとすべてのインデックス定義を表示することができます。 – mustaccio

+0

申し訳ありませんが、[URL:http://i.imgur.com/F4KPAnm.png] [img] http://imgur.com/F4KPAnml.png [/ img] [/ url] –

+0

http:// imgur.com/F4KPAnml.png http://imgur.com/irgBnldl.png –

答えて

0

このクエリは、結合を行う際に時間を失います。 av_cita_cstm.id_cを作成してインデックスを作成することを強くお勧めします。その後、av_cita_cstmテーブルのインデックスを使用するように計画が変更される可能性があります。これはPRIMARYよりはるかに優れています。結果としてPRIMARYac_citaで使用されます。

大きな改善がもたらされると思います。 delete_index(deleted, id)の2つのフィールドで定義されていることを確認してから、whereの条件をjoinの条件に移動すると、さらに改善される可能性があります。しかし、私はMySQLがこれを可能性として見ているかどうかはわかりません。

+0

迅速な回答ありがとうございます。やってみます !! –

+0

私はそれをして、同じ結果を得る。とにかくありがとう –

+0

'av_cita'のように' av_cita_cstm'の既存のインデックスに関する情報をあなたの質問に追加できますか? – trincot

0

オプティマイザが完全なテーブルスキャンがインデックスを使用するより安価であると判断したため、deletedのインデックスが使用されていない可能性があります。 MySQLは、検索する値が表の行の約20%以上にある場合、この決定を下します。

類推で、本の後ろのインデックスを考えてください。 「」のような一般的な単語がインデックスに登録されない理由を理解できます。あなたは大部分のページに「」と表示されているだけで、インデックスに前後に移動するよりも、カバーブックを読むだけで簡単に読むことができます。

あなたはMySQLが間違った決断をしたと思われる場合、あなたはそれがテーブルスキャンは、特定のインデックスを使用して、より高価であることをふりをすることができます:

SELECT 
    * 
FROM 
    `av_cita` FORCE INDEX (deleted_index) 
JOIN `av_cita_cstm` ON (
    (
     `av_cita`.`id` = `av_cita_cstm`.`id_c` 
    ) 
) 
WHERE 
    av_cita.deleted = 0 

読むhttp://dev.mysql.com/doc/refman/5.7/en/index-hints.htmlインデックスヒントの詳細については。索引ヒントをあまり使わないでください。まれにしか有用ではありません。ほとんどの場合、オプティマイザは正しい決定を下します。

あなたのEXPLAINプランは、av_cita_cstmへの参加が既にユニークなインデックスを使用していることを示しています(ヒントは「タイプ:eq_ref」と「rows:1」です)。私はそのテーブルに新しいインデックスは必要ないと思います。

私は、テーブルスキャンがav_citaにあると、推定192549行をスキャンしていることを示しています。私はこれに120秒かかると本当に驚いています。合理的に強力なコンピュータでは、はるかに高速に動作するはずです。

  • サーバー上で実行されている他のどのようなプロセス:あなたは、このサーバー上のチューニングや構成を必要とする何か他のものを持っている場合、私は思ってしまう

    ?おそらく、多くのアプリケーション?他のプロセスもこのサーバー上でゆっくり実行されていますか?サーバーのパワーを高めたり、アプリケーションを自社のサーバーに移動したりする必要がありますか?

    はMySQL 5.7にしている場合は、SYSスキーマを照会してみてください:この:

    select * from sys.innodb_buffer_stats_by_table 
    where object_name like 'av_cita%'; 
    
  • 同時に実行されているが、他の高価なSQLクエリはありますか?

  • あなたは、MySQLのinnodb_buffer_pool_sizeを割り振っていませんでしたか?それが小さすぎると、あなたのテーブルをスキャンする際にRAMのページを激しくリサイクルすることがあります。

    select @@innodb_buffer_pool_size; 
    
  • 過剰割り当てinnodb_buffer_pool_sizeあなたをしましたか?一度私は非常にゆっくりと動いていたサーバーを調整するのを手伝った。彼らは4GBのバッファプールを持っていたが、物理RAMは1GBしかなかったことが判明した。オペレーティングシステムが狂ったようにスワップして、すべてがゆっくりと実行されました。

もう一つの思考:あなたはav_cita_cstmのテーブル構造をav_citaに私たちの列を示しますが、していません。なぜSELECT *を取得していますか?あなたは本当にすべて列が必要ですか?後者の表に巨大なBLOB/TEXT列がありますか?そうであれば、必要のない大量のデータをディスクから読み取ることができます。

あなたはSQL質問をするときは、

SHOW CREATE TABLE av_cita\G 
SHOW TABLE STATUS LIKE 'av_cita'\G 

を実行しても、他のテーブルav_cita_cstmに同じコマンドを実行し、上記の質問での出力が含まれている場合、それが役立つだろう。