为什么参数比where子句中的文字值慢?

情况:c#,sql 2000

我有一张桌子,让我们称它为'mytable',有三千万行。 主键由字段A和B组成:

A char(16)
B smallint(2)

当我做这样的搜索时,它运行得非常慢(例如,它可以完成一个完整的扫描)

string a="a";
int b=1;
string sql = "select * from table(nolock) where a=@a and b=@b";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
  cmd.Parameters.AddWithValue("@a", a);
  cmd.Parameters.AddWithValue("@b", b);
  using (SqlDataReader rdr = cmd.ExecuteReader()) {...}
}

然而,把它改为这个,它运行得非常快(例如它碰到索引):

string where =
  String.Format("a='{0}' and b={1}", a, b);

string sql = "select * from table(nolock) where " + where;
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
  using (SqlDataReader rdr = cmd.ExecuteReader()) {...}
}

究竟是怎么回事? 对我来说似乎很陌生。


参数和列的数据类型是否匹配? 它们不会显示,因此数据类型优先级适用

该列是smallint,但您发送int。 该列将被转换为int,因为它具有更高的优先级。 所以它不会使用索引。


如果将b变量声明为short而不是int它会有什么区别吗? 如果您明确指定参数的类型,它有什么区别吗? 如果使用“where a = @ a和b = @ b”而不是逗号形式,它有什么区别吗?

我同意这听起来很奇怪,我不会期望这些变化有任何帮助,但这可能值得一试。


您可以告诉SQL Server查询使用哪个索引。 使用WITH (INDEX = INDEX_ID)选项,其中INDEX_ID是索引的ID。

获取索引ID:

SELECT i.indid, i.name FROM sysindexes i
INNER JOIN sysobjects o ON o.ID = i.id
WHERE o.Name = 'table'

那么试试吧:

SELECT * FROM table(NOLOCK) WITH (INDEX = 1) WHERE a=@a and b=@b
链接地址: http://www.djcxy.com/p/7653.html

上一篇: Why are parameters slower than literal values in a where clause?

下一篇: Getting a query to index seek (rather than scan)