Setting work_mem in Postgres for specific queries - java

I'm using a library that delegates to a JDBC driver for PostgreSQL, and some queries are very complex and require more memory. I don't want to set work_mem to something large for all queries, just this subset. The problem is that executing the following code results in an error:
// pseudo-code for what is happening
String sql = "set work_mem = 102400;";
sql += "SELECT * FROM expensive_query";
ResultSet rs = DatabaseDriver.execute(sql);
When I run this I get an error that:
set work_mem = 102400;
returns no results.
This works in pgAdmin because you can execute multiple queries at once. Is there a better way to do this or do I need to execute arbitrary SQL and then extract the result set I want?

I have no idea what DatabaseDriver does, but with "plain" JDBC you just need to do the following:
Statment stmt = connection.createStatement();
stmt.execute("set work_mem = 102400");
ResultSet rs = stmt.executeQuery("select ...");

Try to do that using Batch Processing

Related

Get row count of successful bulk insert using jdbc from sql server

I have Java code to bulk-insert tab file to SQL Server.
I want to get the count of how many records were inserted. I tried using ##rowcount but I'm getting an error that "Statement did not return a result set".
If I run the bulk insert statement in management studio, I can get the count.
Statement stmt = sqlConnection.createStatement();
ResultSet rs = stmt.executeQuery ("BULK INSERT schema1.table1 FROM 'd:\temp1\file1.tab' SELECT ##rowcount");
Is there any way to get the inserted count?
I'm not familiar with SQL Server but it seems like you'll want to issue an executeUpdate instead of an executeQuery
Statement stmt = sqlConnection.createStatement();
int insertedRowCount = stmt.executeUpdate("BULK INSERT schema1.table1 FROM 'd:\temp1\file1.tab'");

Slow queries with preparedStatement but not with executeQuery

I'm having a weird problem with an Grails application accessing data. Going deeper I've isolated the problem to a plain java8 small application using PreparedStatement.executeQuery vs Statement.executeQuery.
Consider the following snippet of code:
// executes in milliseconds
directSql = "select top(10) * from vdocuments where codcli = 'CCCC' and serial = 'SSSS' ORDER BY otherField DESC;";
stmt = con.createStatement();
rs = stmt.executeQuery(directSql);
// More than 10 minutes
sqlPrepared = "select top(10) * from vdocuments where codCli = ? and serial = ? ORDER BY otherField DESC;";
PreparedStatement pStatement = con.prepareStatement( sqlPrepared );
pStatement.setString(1, "CCCC");
pStatement.setString(2, "SSSS");
rsPrepared = pStatement.executeQuery();
Same query.
Data comes from a view on SqlServer (2008, I think, have no access right now) from a table with more than 15 Million records. There are indexes for all needed fields and the same query (the first one) executed from console runs also quite fast.
If I execute the slow PreparedStatement query without the ORDER clause it also runs fast.
It looks clear to me that for any cause the database it's not using indexes and make a full scan when using preparedStatement, but maybe I'm wrong so I'm open to any idea.
I thought maybe the driver (sqlserver official latest and jtds has been tested) was holding the data waiting for any kind of EOF from connection but I've checked with tcpdump on my side and no data is received.
I can't find why this is happening so any idea will be welcomed.
Thank you in advanced!
I've finally found a solution, at least in for my case. I got it here http://mehmoodbluffs.blogspot.com.es/2015/03/hibernate-queries-are-slow-sql-servers.html . Telling (driver? sqlServer?) not to send parameters as Unicode have resolved the problem.
Current connection string it's now:
String connectionUrl = "jdbc:sqlserver://server:port;databaseName=myDataBase;sendStringParametersAsUnicode=false";
And now both direct queries and preparedStatements runs at millisecond speed.
Thank you #DanGuzman for your suggestions!

How to get the full query that a PreparedStatement is about to execute in DB2?

I'm working on a dynamic web project and using the PreparedStatement to execute the SQL queries against the DB2 database.
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = connection.prepareStatement(myQuery);
stmt.setString(1, test);
ResultSet resultSet = statement.executeQuery();
How can I receive the full SQL query that is about to be executed on the DB2 server in the console?
If you are familiar with Debugging options in Eclipse. You may try the following:
Set a Breakpoint at ResultSet resultSet = statement.executeQuery();
Right click your application, say Debug As select Java Application (or Whatever applicable in your case i.e. may be SpringBoot App etc.
Perform step that gets you to code mentioned in the Question.
If you check Variables tab in Debug Perspective of Eclipse, you will find variables like myQuery , stmt (according to your code)
Whatever you see as value of stmt would be the full SQL query you need.
Also, if you don't want to keep looking at this variable always you may try Java Logging and Print your Full SQL query in Logs.

How to query SQL Server CDC through JDBC incrementally

I am trying to incrementally read SQL Server CDC changes.
In my first interval, I query
Statement statement = connection.createStatement();
String queryString = "SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_mytable(sys.fn_cdc_get_min_lsn('dbo_mytable'), " +
"sys.fn_cdc_get_max_lsn(), 'all') ORDER BY __$seqval";
ResultSet rs = statement.executeQuery(queryString);
Now I know that __$start_lsn is an LSN (Log Sequence Number) in binary(10). Although I don't understand how I can read it as a Java type so that I can include it my next query and how should I create my next query where I will like to specify the min_lsn as the last LSN which I processed.
You can use several options for retrieving the data from the ResultSet
Then for creating a new query, look at using a a PreparedStatement. There are several options for setting the data based on the type that you you pulled out of the initial query.

Which way is better for update database record?

I have two method for update:
String query = "update mytable set name = 'new_value' where id ='20' ";
Connection conn;
PreparedStatement pState;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.executeUpdate();
} catch (SQLException sql) {
sql.printStackTrace();
}
OR:
String query = "update mytable set name = ?" + "where id = ?";
Connection conn;
PreparedStatement pState;
int s;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.setStringt(1, "new_value");
pState.setString(2, "20");
s = pState.executeUpdate(); // if s = 1 then update done successfully
} catch (SQLException sql) {
sql.printStackTrace();
}
Both methods update database record correctly, Which is better?
Second approach is good practice to avoid SQL Injection attacks.
And following is enough to construct query String, another + concatenation is not required.
String query = "update mytable set name = ? where id = ?";
I would say the second approach.
You aren't returning anything, so why create a result set and go down that path?
Edit:
Even after your comment, I would still use the second template. It's more flexible. Additionally, it's faster. The PreparedStatement is pre-compiled in the database which allows the database to execute a parametric query using the statement faster than a normal query. This won't happen if you use string concatenation (like in your first example).
See: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Additionally, from that page:
The main feature of a PreparedStatement object is that, unlike a
Statement object, it is given a SQL statement when it is created. The
advantage to this is that in most cases, this SQL statement is sent to
the DBMS right away, where it is compiled. As a result, the
PreparedStatement object contains not just a SQL statement, but a SQL
statement that has been precompiled. This means that when the
PreparedStatement is executed, the DBMS can just run the
PreparedStatement SQL statement without having to compile it first.
Although PreparedStatement objects can be used for SQL statements with
no parameters, you probably use them most often for SQL statements
that take parameters. The advantage of using SQL statements that take
parameters is that you can use the same statement and supply it with
different values each time you execute it.
The second way is more faster if you use frequently the same query. Depends of the database vendor, the query is cached and the efficiency is higher than that using flat sentences. But all that depends on the implementation of the JDBC driver and the services provided by the database.
See more in Using Prepared Statements in the The Java Tutorials.

Categories

Resources