1

我们的软件部署在他们遇到性能问题的客户站点,他们聘请了一位 SQL 顾问来查看数据库并了解他们的瓶颈在哪里。

顾问发现的一件事是,我们的许多陈述都转换为nvarchar. 经过一番调查,我发现它是PreparedStatement这样做的。

给你举个例子:

PreparedStatement query = connection.prepareStatement("SELECT * FROM sys.tables WHERE"
        + " name LIKE ?");
query.setString(1, "%%");

变成

declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@P0 nvarchar(4000)',N'SELECT * FROM sys.tables WHERE name LIKE @P0        ',N'%%'
select @p1

另一方面,adhoc executeQuery 方法只是通过发送 SQL

ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM sys.tables WHERE  name LIKE '%%'");

变成

SELECT * FROM sys.tables WHERE  name LIKE '%%'

我正在努力解决的是这实际上有多糟糕。准备好的语句在我们的整个应用程序中都使用,因为它们的使用应该比即席查询更有效(如果执行多次)。

此外,我看不出微软的人会在他们的驱动程序中加入一些他们知道会导致性能问题的东西。

这是我们真正应该研究的问题,还是顾问正在寻找根本不存在的问题?

4

2 回答 2

1

pepared 语句强制查询成为参数化查询(这是一件好事),而 ad-hoc 查询可能会或可能不会被 SQL 引擎自动参数化。简而言之,它不会对性能造成重大影响。

但是,从设计的角度来看,是否应该使用参数化存储过程(不一定是性能方面的)总是存在很多争论。我认为大多数 DBA(可能还有数据库顾问)更喜欢存储过程,因为它们更容易使用传统的数据库管理工具进行调试(以及提供安全优势,并且默认情况下包括参数化)。

于 2012-06-29T17:17:36.410 回答
0

Prepared statements 具有比 ad-hoc 查询更多的优化选项,并且从安全角度来看通常会更好(设计上没有 SQL 注入)。

nvarchar的使用通常来自非功能性需求。如果您希望您的应用程序支持任何现在很常见的 Unicode 字符,那么您需要它。如果这是要求,请不要更改它。

我认为LIKE查询是罪魁祸首,您实际上应该查看后端数据库中的全文索引功能。该查询看起来超级简单,它是 LIKE '%' 查询导致扫描每个字段中的字符序列。

于 2014-09-06T06:47:23.340 回答