当它们包含 ROW_NUMBER() 时,JDBC-driver / SQL Server 总是重新编译我准备好的语句
Posted
技术标签:
【中文标题】当它们包含 ROW_NUMBER() 时,JDBC-driver / SQL Server 总是重新编译我准备好的语句【英文标题】:JDBC-driver / SQL Server recompiles my prepared statements all the time when they contain ROW_NUMBER() 【发布时间】:2009-09-17 13:23:27 【问题描述】:我注意到包含 ROW_NUMER() 代码的准备好的语句经常被重新编译,尽管它们的 SQL 代码没有改变。
(Inside Microsoft SQL Server 2008: T-SQL Querying 一书中的示例):
WITH SalesRN AS (
SELECT
ROW_NUMBER() OVER (ORDER BY qty, empid) AS rownum,
empid,
mgrid,
qty
FROM
dbo.SalesOrder
)
SELECT
rownum,
empid,
mgrid,
qty
FROM
SalesRN
WHERE
rownum > 100 * (?-1)
AND rownum <= 100 * ?
ORDER BY
rownum
我正在使用最新版本的 jTDS JDBC 驱动程序 (1.2.3),并注意到 SQL Server 2005 和 2008 都存在问题。
有人知道发生了什么吗?为什么它会重新编译语句,尽管它们的代码没有改变?对于我的一个查询,重新编译大约需要 1200 毫秒,与低至 31 毫秒的执行时间相比,这是很多。
【问题讨论】:
【参考方案1】:我怀疑它被重新编译以优化分页,因为这个位:
rownum > 100 * (?-1)
AND rownum <= 100 * ?
不过,我也符合 SalesRN 的条件 (dbo.SalesRN)。这也可能是原因。
最后,您可以使用query hint。这是一门黑色艺术。我会从 KEEP PLAN 或 OPTIMIZE FOR UNKNOWN 开始。
【讨论】:
听起来很可能,这取决于 SalesRN 中的行数和 rownum 的整体分布。 但是决定何时重新编译语句的不是 JDBC 驱动程序,而不是 SQL Server? 不,SQL Server 优化器。 JDBC如何重新编译它?它可以准备不同的语句以上是关于当它们包含 ROW_NUMBER() 时,JDBC-driver / SQL Server 总是重新编译我准备好的语句的主要内容,如果未能解决你的问题,请参考以下文章
在运行 spark 应用程序时包含 aws jdbc 驱动程序