0

我目前遇到了一个使用许多 sql select 的应用程序的性能问题。

编程语言是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

您的第二个 SQL 查询中的“分组依据”是不必要的,并且会降低性能。为了获得最佳性能,请替换此选择(代码中的第二个)...

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 回答
0

您可以创建一个带有两个参数的存储过程,并使用门牌号作为可选参数,或者只是让该过程查找是否存在。

于 2013-02-22T13:21:45.260 回答
0

很大程度上取决于使用模式。您运行了多少查询,邮政编码缺失的频率等。首先,我会在可能的情况下使用 PreparedStatements。我对 MySQL 不太熟悉,但它们通常被连接数据库缓存和重用,这将有助于提高性能。接下来,如果邮政编码丢失很常见,我可能会在内存中构建邮政编码缓存,以缩短对未命中的 3 次查询。之后,我可能会创建一个 ZIP + 门牌号的视图。更进一步取决于您的应用程序如何工作,但这些事情会有所帮助。

于 2013-02-22T13:22:23.593 回答