2017-08-15 14 views
0

テーブルに180万個以上のレコードがある場合、このクエリが実行されるのがなぜ遅いのか分かりません。jdbcTemplate.query何百万ものレコードで低速実行中

public CustomerEmailFreq getFreqCodeByEmail(String email, String domain) { 
CustomerEmailFreq customerEmailFreq = new CustomerEmailFreq(); 
Map namedParameters = new HashMap(); 
namedParameters.put("email", email); 
namedParameters.put("domain", domain); 

String sql = "select freq_cde,email_local,email_domain,last_src_date,last_src_time from ADDRESS where upper(email_local)=upper(:email) and upper(email_domain)=upper(:domain) ORDER BY TIMESTAMP(LAST_SRC_DATE,LAST_SRC_TIME) DESC FOR READ ONLY WITH UR FETCH FIRST ROW ONLY"; 

this.jdbcTemplate.query(sql, namedParameters, (rs, rowNum) -> 

{ 
    customerEmailFreq.setEmailDomain(rs.getString("EMAIL_DOMAIN").trim()); 
    customerEmailFreq.setEmailLocal(rs.getString("EMAIL_LOCAL").trim()); 
    customerEmailFreq.setFreqCode(rs.getString("FREQ_CDE")); 
    customerEmailFreq.setLastSrcDate(rs.getString("LAST_SRC_DATE")); 
    customerEmailFreq.setLastSrcTime(rs.getString("LAST_SRC_TIME")); 
    return null; 

}); 
return customerEmailFreq; 

}

これを助けるために任意のヒント。

+1

dbで直接実行するとクエリにかかる時間はどのくらいですか? なぜあなたはnullを返していますか? –

+0

4分以上かかる。ラムダ式を使用したので、nullを返す必要があります。 –

+0

なぜあなたはそれが速く走ると思いますか? – mustaccio

答えて

1

1億80万行が重大な番号です。したがって、データベースでアクセスされるブロックの数を制限するために索引を使用できない場合は、しばらくの間実行する必要があります。あなたはそれを高速に実行することを期待なぜ質問

に答えるのコメントで

テーブルインデックスは列email_localemail_domain上に設定されているため。 where節で私が使っているので、より速く実行することを期待しています。

問題は、これらのインデックスを使用していない可能性が高いことです。

  1. 実際には複数のインデックスである場合、データベースはたぶん1つしか使用しません。ほとんどのデータベースでは、ほとんどの場合、複数の索引を結合することはできません。

  2. 句は次のようになりますあなたのどこ場合:

    where upper(email_local)=upper(:email) and upper(email_domain)=upper(:domain) 
    

    これはあなたがいないインデックス列にwhere句を適用しているが、これらの列に基づいて結果を機能することを意味します。これにより、インデックスはほとんど役に立たなくなります。ここで

  1. add a function based index(ここではDB2の専門家で、より多くのではないがあるかもしれない)あなたが何ができるかです。これはあなたが本当にやるべきことです。他のものは、あなたがこれを行うことができない場合のためです。(別のRDBMS、古いバージョン、マッドDB管理者)

  2. 大文字の名前を持つカラムをテーブルに追加し、それらのインデックスを付けてクエリに使用します。

  3. where句の列にupperをドロップします。これは明らかにあなたのクエリを変更し、おそらく受け入れられません。あなたは、インデックスを使用する制約を追加することができ、最終的な本当にハックのアプローチとして

  4. where column between lower(:value) and upper(:value) and upper(column) = upper(:value) 
    

    あなたが複数の列に、このアプローチを適応し、任意の非ASCII文字は次のようにソートされていることを確認する必要があると思います期待される(彼らはそうしない)。いずれの場合においても

それはあなたの文explain planを見て、変更前と後を比較するのは良いアイデアです。数億の行で作業する場合は、このツールが必要です。

+0

おかげでジェンスズは私に見てみましょう –

関連する問題