1 什么绑定变量
绑定变量是为了减少解析的,比如有个语句:
Select aaa,bbb from cc where ddd=eee;
如果经常改变eee这个谓词赋值来查询,如:
Select aaa,bbb from cc where ddd=fff;
Select aaa,bbb from cc where ddd=ggg;
这样,每条语句都要被数据库解析一次,比较浪费资源,如果把eee换成“:1”这样的绑定变量形式,无论ddd后面是什么值,都不需要重复解析。
2 Java实现绑定变量
PreparedStatement pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 15.00);
pstmt.setInt(2, 110592);
//result statmement: UPDATE employees SET salay = 15.00 WHERE id = 110592
pstmt.executeQuery();
假设要讲Id从1到1000的员工的工资都更新为150元,不使用绑定变量,则:
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 1");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 2");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 3");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 4");
....
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 1000");
使用绑定变量,则:
PreparedStatement pstmt;
for (id = 1; id < 1000; id++)
{
if (null == pstmt)
pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 150.00);
pstmt.setInt(2, id);
pstmt.executeQuery();
}
区别是:
不用绑定变量,会反复解析、执行了**1千次**sql语句
使用绑定变量,解析*sql语句只用了一次,之后的999次复用第一次的执行计划*。这样效率会高一些。
3 绑定变量不必要的情况
1) 一条大查询一跑几个小时,没必要做绑定变量,因为解析的消耗微乎其微
2) 变量值对优化器产生执行计划有很重要的影响时:绑定变量在被使用时,优化器会忽略其具体值,因此其预估的准确性远不如使用具体值真实,尤其在表存在数据倾斜(表上的数据非均匀分布)的列上会提供错误的执行计划,从而是非高效的执行计划被使用。