我正在使用powerbuilder 10.2
我有一个简单的select语句,它从一个包含300万行的表中返回一个结果。
SELECT SOME_DATA
INTO :ls_data
FROM SOME_TABLE
WHERE PARAM1 = :ls_param
AND PARAM2 = :ls_param2;
当我在应用程序中运行查询时,大约需要2秒,但是当我在SSMS中运行它时,结果返回的时间不到100毫秒。当我使用SQL分析器捕获从powerbuilder应用程序运行的查询时,我发现了一个非常有趣的发现:
exec sp_executesql N'SELECT SOME_DATA FROM SOME_TABLE WHERE PARAM1 =@P1 AND PARAM2 =@P2 ',N'@P1 nvarchar(10),@P2 nvarchar(3)',N'112223',N'44252525'
where子句PARAM1
和PARAM2
被定义为VARCHAR
类型,但powerbuilder在某种程度上认为它是NVARCHAR
列。这导致了我们业绩的瓶颈。
有没有办法强制powerbuilder生成varchar
类型的SQL而不是nvarchar
?
编辑:
我尝试在数据存储区中运行上述查询以查看是否存在任何差异。它生成几乎相同的查询,仍然遇到同样的问题。我猜这个问题并不仅限于嵌入式SQL
EDIT2:
深入研究这个问题,SQL Server's sp_executesql只接受unicode类型(ntext,nchar,nvarchar)作为参数,这就是我假设powerbuilder默认为nvarchar的原因。所以我想我的问题现在变成了如何阻止powerbuilder使用sp_executesql并使用其他类似EXECUTE(@SQL)的东西。或者任何其他想法将不胜感激。
答案 0 :(得分:0)
经过长时间的分析,我终于发现了这个问题。
<强> tldr; Powerbuilder错误。嗯,更确切地说,平台的巨大限制。在数据库连接字符串中设置DisableBind = 1
长答案:
在数据库连接字符串中,有一个称为 DisableBind 的选项,用于将SQL语句中的变量绑定到其支持的数据类型。 Detailed information can be found in the documentation。无论如何,当disablebind设置为0时,程序提供的WHERE子句的所有SQL查询都包含在sp_executesql中。遗憾的是,Powerbuilder没有简洁的方法来确定是否将参数包装为VARCHAR或NVARCHAR,因此如果启用了Unicode选项,则在生成sp_executesql语句时,Powerbuilder默认为NVARCHAR。
启用disablebind选项后,所有查询都是通过sp_executesql本地执行的,因此上述问题不会发生。不幸的是,对于我们的应用程序,启用此选项会引入一些重大更改,因此我们最终将数据库数据类型从varchar更改为nvarchar以解决此问题。这使我们的应用程序性能提高了至少20%,在某些情况下超过70%。
希望这可以帮助其他可能遇到这个模糊问题的人。或者更好的是,不惜一切代价避免使用Powerbuilder。这件事就像癌症。我很高兴SAP正在慢慢杀死它。