2017-05-31 10 views
0

私は2つのテーブルticket_dataとnps_dataを持っています。MySQLは非常に遅く参加し、usuallは永久にハングします

ticket_dataは一般的なITの問題情報を保持し、nps_dataはユーザーのフィードバックを保持します。 テーブルの基本的な考え方は、

ticket_dataテーブルです。 aprox。 1,500,000行:30フィールド:ticket_number、logged_date、logged_team上 指数、resolution_date

 
|ticket_number | logged_date | logged_team | resolution_date | 
| I00001  | 2017-01-01 | Help Desk | 2017-01-02  | 
| I00002  | 2017-02-01 | Help Desk | 2017-03-01  | 
| I00010  | 2017-03-04 | desktop sup | 2017-03-04  | 

は明らかに他のフィールドがたくさんありますが、これはImは

nps_dataテーブルで およそ10mlの液体フッ化水素を圧入83,000行を作業です:10のフィールド:

 
|ticket_number | resolving team| q1_score| 
| I00001  | helpdesk  | 5  | 
| I00002  | desktop sup | 0  | 
| I00010  | desktop sup | 10  | 

ticket_number 指数私は、単純なクエリを実行するときのような

 
select a.*, b.q1_score from 
(select * from ticket_data 
where resolution_date > '2017-01-01') a 
left join nps_data b 
on a.ticket_number = b.ticket_number 

クエリは永遠に実行され、私がそれを言うとき、私は10分後にクエリを停止することを意味します。 は、しかし、私は

 
select * 
(select * from ticket_data 
where resolution_date > '2017-01-01') a 
left join ticket_details b 
on a.ticket_number = b.ticket_number 

クエリを実行するのに約1.3秒かかり、次のクエリを使用して、1,000,000以上の行を持つticket_detailsと呼ばれる表、とticket_data参加するためにクエリを実行する場合。

答えて

0

上記のクエリでは、インデックス上で実行されていないエイリアスaのサブクエリがあります。索引が作成されていないフィールドresolution_dateを照会しています。

簡単な修正は、そのフィールドにインデックスを追加することです。

チケット番号です。これはおそらく、それに参加したときにクエリがより速く実行される理由です。

これをさらに最適化するもう1つの方法は、サブクエリ内でselect *を実行しないようにします(とにかく運用システムでは悪いことです)。 DBMSがサブクエリ内のすべての結果を渡すためにより多くのオーバーヘッドを作成します。

もう一つの方法は、次のような列に部分インデックスを行うには、次のようになります。

create index idx_tickets on ticket_data(ticket_number) where resolution_date > '2017-01-01'

しかし、「2017年1月1日」のタイムスタンプがその意志一定であれば、私は唯一のことを行うだろう常に使用してください。

複合インデックスを作成することもできます。クエリエンジンはIndex Only Scanを実行します。これにより、テーブルに戻らずにインデックスからデータを直接引き出すことができます。

これについて私が何かを参照するためには、あなたが実行しているDBMSを知る必要があります。

もちろん、これは実行しているDBMSのタイプによって異なります。

+0

申し訳ありませんresolution_dateのインデックスが作成され、そのサブクエリの実行に1秒未満がかかります – user2220694

+0

あなたはどのDBMSを使用していますか?また、EXPLAINを実行してクエリの実行計画を確認しましたか? –

+0

また、 'nps_data'の中に膨大な数の行があり、クエリプランナーが何とかふるい落としようとしているように、テーブル(Postgresを使用している場合)を真空にすることもできます。 –

関連する問題