I am using JDBC PreparedStatement to query a Teradata database from a web service. My table has a PHONE_NUMBER column, stored as VARCHAR(10). I have always used PreparedStatement setString()
to supply the parameter for this column, like below:
String myPhoneNumber = "5551234567";
String sql = "SELECT * FROM MYTABLE " +
"WHERE PHONE_NUMBER = ? ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);
It returns correct results, but I noticed the CPU Teradata is using for this query is quite high. According to the EXPLAIN plan, it appears that Teradata is interpreting the myPhoneNumber
parameter as a FLOAT, instead of VARCHAR, and so it has to do a data conversion to compare it to the VARCHAR column PHONE_NUMBER
. Here is an excerpt of the EXPLAIN plan:
...
MYDATABASE.MYTABLE.PHONE_NUMBER (FLOAT, FORMAT
'-9.99999999999999E-999'))= 5.55123456700000E 009)
So, I came up with the below, which showed a great improvement in CPU usage (99.86% improvement):
String myPhoneNumber = "5551234567";
String sql = "SELECT * FROM MYTABLE " +
"WHERE PHONE_NUMBER = ''||?||'' ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);
So my question is why is this necessary? Shouldn't setString
tell JDBC to tell Teradata to expect a String/VARCHAR parameter?
Thanks!