Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:如何高效地读取数据库?_Java_Sql_Performance - Fatal编程技术网

Java:如何高效地读取数据库?

Java:如何高效地读取数据库?,java,sql,performance,Java,Sql,Performance,我试图从java中的sql数据库中读取一列,我希望结果以数组形式返回。以下是函数: public static double[] open(Connection conn,String symbol,int startdate,int enddate) throws SQLException { int id = database.get_stockid(conn, symbol); Statement stat = conn.createStat

我试图从java中的sql数据库中读取一列,我希望结果以数组形式返回。以下是函数:

public static double[] open(Connection conn,String symbol,int startdate,int enddate)                 throws SQLException {
    int id = database.get_stockid(conn, symbol);
    Statement stat = conn.createStatement();
    ResultSet rs = stat.executeQuery("select price_open from stock_data where stock_id="+id+" and date>="+startdate+" and date<="+enddate+";");
    ArrayList<Double> data = new ArrayList<Double>();
    while(rs.next()) {
        data.add(rs.getDouble("open"));
    }
    double[] data1 = new double[data.size()];
    for(int a = 0; a < data1.length; ++a) {
        data1[a]=data.get(a);
    }
    return data1;
}
这相当慢。我的sqlite数据库需要1.5秒。这是阅读专栏的标准方式还是我做错了什么?这是我的应用程序中的瓶颈,所以我需要它尽可能快

编辑: 谢谢我刚刚发现ArrayList并不是问题的根源。瓶颈必须位于sql部分: 如果我只加载10天的数据,则加载数据所需的时间与加载10年的时间一样长。所以我必须改进我的sql,但如何改进

下面是改进的代码:

public static double[] open(Connection conn,String symbol,int startdate,int enddate) throws SQLException {
    int id = database.get_stockid(conn, symbol);

    PreparedStatement stat = conn.prepareStatement("select price_open from stock_data where (stock_id="+id +") and (date between "+startdate+" and "+enddate+");");
    ResultSet rs = stat.executeQuery();
    ArrayList<Double> data = new ArrayList<Double>();
    while(rs.next()) {
        data.add(rs.getDouble(1));
    }
    double[] data1 = new double[data.size()];
    for(int a = 0; a < data1.length; ++a) {
        data1[a]=data.get(a);
    }
    return data1;
}
替换

double[] data1 = new double[data.size()];
for(int a = 0; a < data1.length; ++a) {
    data1[a]=data.get(a);
}
通过分析此应用程序或在数据库端投资日志来检查查询运行时间,检查是否可以通过在where子句i.d.stock_id和date中使用的列上引入索引来减少查询运行时间

如果您能够估计查询将返回的记录数量,或者您知道查询将至少返回N条记录,则可以使用以下方法代替:

ArrayList<Double> data = new ArrayList<Double>();
这样可以节省与数据库通信的时间,并且返回的结果更少,需要处理的结果也更少

使用PreparedStatement而不是Statement来:

防止SQL注入 但也因为性能原因,因为使用PreparedStatement允许数据库重用已解析的查询 更新1

请记住始终释放所有资源,i.d.ResultSet和PreparedStatement。 在Java 1.7+中,可以使用新的try with resources语句 在较旧的Java版本中,必须在finally块中调用close方法,并对每个调用进行单独的异常处理,以防止在第一个close中抛出的异常阻止调用第二个close时出现这种情况。
可以通过使用基元数组而不是ArrayList来提高性能,但这需要知道结果集有多大

按索引而不是名称引用列-这也可以提供一点改进

 datars.getDouble(1);
您的查询是:

select price_open
from stock_data
where stock_id="+id+" and date>="+startdate+" and date<="+enddate+"
要对此进行优化,请在stock\u datastock\u id,date上创建一个索引。索引查找将用于获取数据


如果你的数据真的很大,那么你可以打开股票id、日期、价格的指数。这是查询中引用的仅有三列,因此索引可以满足查询,而无需加载原始数据页。

有助于SQL注入,是的。答案是什么?没有那么多。@Makoto我太快了,又增加了两点,但是应该使用PreparedStatement,这不仅仅是因为SQL注入的保护。使用java.util.List比ArrayList更有效,+1是一个好答案。您的查询选择price_open,但您的结果集调用getDoubleopen。这真的像预期的那样有效吗?另外,您一次提取多少行数据?首先,让查询运行得更快。您的数据库是否正确索引?完全同意@ntalbs。您是否在java之外对db运行了此查询,以便了解它自己的性能?首先调整查询;确保您具有与条件匹配的正确索引。然后关注java代码,可能会将语句转换为PreparedStatement。只有部分答案:避免将ArrayList转换为数组的第二个循环。要么更改opentolist的返回类型,要么使用ArrayList的toArray方法,要么最好在第一个循环中甚至在数据库中进行计算。这将避免数据传输的大部分开销和额外的双重包装。
select distinct price_open from stock_data ...
 datars.getDouble(1);
select price_open
from stock_data
where stock_id="+id+" and date>="+startdate+" and date<="+enddate+"