使用LIKE运算符搜索SQL Server

时间:2010-12-28 17:16:14

标签: c# sql sql-like

当我尝试从C#

中的代码读取SQL Server 2005中的行时出现问题

这个想法:

在我的数据库(SQL Server 2005 Express)中,有一个表(包含数据类型为ntext的列)包含HTML代码。

在我的C#应用​​程序中,用户可以输入一个句子(HTML代码)并搜索包含此句子的行。

从我的应用生成的查询是:

USE test   
SELECT   
 al.aal_Id As ID,   
 al.aal_Description As Opis,   
 au.au_Title As Tytul_szablonu,   
 au.au_Note As Nazwa_szablonu   
FROM dbo.au_Allegro al   
LEFT OUTER JOIN dbo.au__Auction au ON (al.aal_AuctionId = au.au_Id)   
WHERE  
 au.au_Type = 11   
 AND al.aal_Description COLLATE SQL_Latin1_General_CP1_CS_AS LIKE '%%' ESCAPE '\'  

在我的应用程序中,我正在转换特殊字符(例如',)并添加转义字符。

用户试图搜索很长的句子(大约7000多个字符),当他试图这样做时sqlserver.exe进程消耗他所有的RAM内存并且搜索时间大约是30多分钟(他有大约1000分钟) +表中的行。)

查询返回0行。

当他尝试在SQL Server Management Studio中运行(同样)查询时,数据库会在几秒钟内显示结果(包含行)。

在我的应用中,我使用SqlDataAdapter

System.Data.DataTable dt = new System.Data.DataTable();  
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();  
cmd.CommandTimeout = 0;  
cmd.Connection = conn;  
System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(kwerenda, conn);  
try  
{
  da.Fill(dt);
}

我尝试了SqlDataReader

dr = cmd.ExecuteReader();  
while (dr.Read())  
{  
  string id = dr["ID"].ToString();  
  string opis = dr["Opis"].ToString();  
  string tytul = dr["Tytul_szablonu"].ToString();  
  string nazwa = dr["Nazwa_szablonu"].ToString();  
  dt.Rows.Add(id, opis, tytul, nazwa);  
}

当我在我的测试数据库中尝试模拟这个时,我对搜索(相同)句子没有任何问题。

你有什么提示吗?

我无法对用户数据表做任何更改,我不能去找他并检查会发生什么。

2 个答案:

答案 0 :(得分:1)

SQL命令是否正在执行存储过程?如果是这样,您可能会得到不同的查询计划,这可以解释应用程序之间的时间差异。您的ADO.Net调用可能会受到parameter sniffing的影响,这会导致查询执行时间完全不同。

您可以采取一些措施来避免此问题并产生一致的结果

  1. 将参数转换为存储过程内的局部变量。
  2. 完全禁用SQL服务器上的功能。
  3. John也指出,你的语法看起来很可疑。最好对该列使用NVARCHAR(MAX)数据类型,如果可能的话,应该避免使用NTEXT,因为它已被弃用。

    对像这样的非索引列进行搜索的更好的替代方法是利用SQL的全文搜索,该搜索针对这些类型的查询进行了优化。

答案 1 :(得分:1)

您可能想要做的一些事情。

首先,不要使用nText。 SQL 2005有一个名为nvarchar(max)的数据类型。存储大量文本更好。此外,ntext已被弃用,因此请省去一些麻烦并立即转换它。有关如何成功执行此操作,请参阅this link

其次,您发布的查询不常见。您有一个左外连接,但外连接表上有一个where子句。由于where子句,它被转换(希望)为内连接。你应该这样写它或移动au.au_type = 11成为join结构的一部分。我怀疑你想要后者。

第三,当客户端第一次通过您的应用程序运行查询时,它会根据这些参数生成查询计划。此后不久在Management Studio中运行完全相同的查询将重用该计划和缓存数据。因此第二次传球会很快,所以不会感到惊讶。

第四,我认为您没有发布已运行的实际查询。我怀疑你要比较的参数中有一些数据要么没有正确转义,要么使用其中一个保留字符,如'[',']',^等。