0

現在、多くの SQL 選択を使用するアプリケーションでパフォーマンスの問題が発生しています。

プログラミング言語は Java で、mysql データベースを使用しています。約 1000 万件のレコードが含まれています。実行する必要があるのは、パラメーターとして郵便番号と番地を使用してデータベース内のレコードを検索することです。レコードが見つからない場合は、郵便番号のみを使用してクエリを実行し、家番号が最も小さいレコードを取得する必要があります。データベースで郵便番号が見つからない場合、アプリケーションはこれに対処する必要があります。

したがって、単一のクエリを実行するためのコードは次のようになります。

Statement select = "select * from zipcode_addresses where zipcode = ? and houseNo =?";
ResultSet rs = select.executeQuery();
if(rs.next()) {
    dealWithResult(rs);
}
else {
    Statement alternativeSelect = "select * from zipcode_addresses where zipcode = ? group by houseNo having min(houseNo)";
    ResultSet rs = alternativeSelect.executeQuery();
    if(rs.next()) {
        dealWithResult(rs);
    } else {
        System.err.println("Could not find zipcode :" + zipcode);
    }
}

見つからないデータを処理するバッチ選択クエリを実行する適切な方法はありますか?

ありがとう!

アップデート

テーブル構造は次のとおりです。

+-----------------+-------------+------+-----+---------+-------+  
| Field           | Type        | Null | Key | Default | Extra |   
+-----------------+-------------+------+-----+---------+-------+   
| zipcode         | varchar(6)  | NO   | PRI | NULL    |       |   
| house_no        | int(11)     | NO   | PRI | NULL    |       |   
| sanddcode       | varchar(45) | NO   |     | NULL    |       |   
| depot           | varchar(3)  | NO   |     | NULL    |       |   
| network_point   | varchar(6)  | NO   |     | NULL    |       |   
| region          | varchar(3)  | NO   |     | NULL    |       |   
| seq             | int(11)     | NO   |     | NULL    |       |   
| cluster_id      | varchar(1)  | NO   |     | NULL    |       |   
| strand_id       | int(11)     | NO   |     | NULL    |       |   
| strand_props_id | int(11)     | NO   |     | NULL    |       |   
| version_id      | int(11)     | NO   | PRI | NULL    |       |   
+-----------------+-------------+------+-----+---------+-------+   

バージョン ID、zipcode、house_no の主キー zipcode と house_no のインデックス、および zipcode の別のインデックス。どちらも BTREE インデックスを使用します。

アプリケーションを使用して 100 万の個別の選択クエリを実行すると、時間がかかりすぎます。

4

4 に答える 4

1

コード スニペットは、ステートメントがどのように準備されているかを示していません。ステートメントが何度も呼び出されている場合は、PreparedStatement オブジェクトを確認する必要があります。

http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

その後、ステートメントをキャッシュして、将来のオーバーヘッドを削減できます。

于 2013-02-22T13:27:13.273 に答える
0

2 つのパラメーターを持つストアド プロシージャを作成し、番地をオプションとして使用するか、単にプロシージャが存在するかどうかを検出できるようにすることができます。

于 2013-02-22T13:21:45.260 に答える
0

多くは使用パターンに依存します。実行するクエリの数、郵便番号のミスの頻度など。まず、可能な場合は PreparedStatements を使用します。私は MySQL にあまり詳しくありませんが、通常は接続データベースによってキャッシュされて再利用されるため、パフォーマンスが向上します。次に、郵便番号のミスが一般的である場合、郵便番号のメモリ内キャッシュを構築して、ミスで 3 つのクエリを実行する短絡回路を構築するでしょう。その後、ZIP + 家番号のビューを作成する場合があります。さらに進むには、アプリケーションがどのように機能するかによって異なりますが、これらのことが役立ちます。

于 2013-02-22T13:22:23.593 に答える
0

2 番目の SQL クエリの「グループ化」は不要であり、パフォーマンスを低下させます。最大のパフォーマンスを得るには、この select (コードの 2 番目のもの) を置き換えます ...

select * from zipcode_addresses where zipcode = ? 
  group by houseNo having min(houseNo)

これとともに ...

select min(houseNo) from zipcode_addresses where zipcode = ?

また、zipcode + houseNo のインデックスがあることを確認してください (更新された投稿からのように見えます)。

于 2013-02-22T13:28:40.703 に答える