Поиск SQL Server с оператором LIKE - PullRequest
0 голосов
/ 28 декабря 2010

У меня проблема при попытке прочитать строки из SQL Server 2005 из кода на C #

Идея:

В моей базе данных (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 '\'  

В моем приложении я конвертирую специальные символы (например, ',) и добавляю escape-символы.

Пользователь пытается найти очень длинное предложение (около 7000+ символов), когда он пытается это сделать, процесс sqlserver.exe занимает всю его оперативную память, а время поиска составляет около 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 ]

1 голос
/ 28 декабря 2010

Пара вещей, которые вы можете захотеть сделать.

Во-первых, не используйте nText.SQL 2005 имеет тип данных nvarchar (max).Гораздо лучше для хранения большого количества текста.Кроме того, ntext устарела, так что избавьте себя от проблем и конвертируйте его сейчас.См. эту ссылку , чтобы узнать, как успешно это сделать.

Во-вторых, отправленный вами запрос необычен.У вас есть левое внешнее соединение, но у вас есть предложение where на внешнюю объединенную таблицу.Из-за предложения where он превращается (надеюсь) во внутреннее соединение.Вы должны просто написать это так, ИЛИ переместить au.au_type = 11, чтобы быть частью конструкции соединения.Я сомневаюсь, что вы хотите последнее.

В-третьих, когда клиент запускает запрос в первый раз через ваше приложение, он генерирует план запроса на основе этих параметров.Выполнение точно такого же запроса вскоре после этого в Management Studio позволит повторно использовать этот план и кэшированные данные.Поэтому второй проход будет быстрым, поэтому неудивительно.

В-четвертых, я не думаю, что вы опубликовали фактический запрос, который был выполнен.Я подозреваю, что в параметре, который вы сравниваете, есть данные, которые либо не экранируются правильно, либо используют один из зарезервированных символов, таких как '[', ']', ^ и т. Д.

1 голос
/ 28 декабря 2010

Команда SQL выполняет хранимую процедуру?Если это так, вы можете получать разные планы запросов, которые могут объяснить разницу во времени между приложениями.На ваш вызов ADO.Net может повлиять нечто, известное как сниффинг параметров , что может привести к радикально различному времени выполнения запроса.

Есть несколько вещей, которые можно сделать, чтобы избежать этой проблемы, ивыход последовательные результаты .

  1. Преобразование параметров в локальные переменные внутри хранимой процедуры.
  2. Отключение функции на сервере SQL в целом.

Также ваш синтаксис выглядит подозрительно какДжон указал.Было бы лучше использовать тип данных NVARCHAR (MAX) для этого столбца, если возможно, следует избегать NTEXT, поскольку он устарел.

Лучшая альтернатива выполнению подобных поисков по неиндексированному столбцу, как это, заключается в использованииполнотекстовый поиск SQL, оптимизированный для этих типов запросов.

...