Я склонен согласиться с вашим рецензентом. Вот почему:
Риск того, что у вас есть, составляет SQL Сервер скомпилирует этот запрос один раз при первом выполнении. Он будет делать оценки количества элементов на основе значений параметров, предоставленных в то время, и основывать на этом план выполнения. Этот план выполнения будет оставаться в кеше в течение некоторого времени, независимо от того, что на самом деле происходит при последующих запусках. Это может привести к очень плохим планам выполнения для некоторых значений параметров.
Как предлагает г-н Линофф (а он действительно знает свое дело), вы можете учесть это с помощью option(recompile)
. Однако это означает, что SQL серверу потребуется перекомпилировать этот запрос при каждом выполнении . Если эти запросы выполняются часто, это может привести к тому, что SQL сервер со временем потратит много дополнительных усилий на перекомпиляцию.
Более того, мой опыт работы с этим типом запросов заключается в том, что пользователи склонны предоставлять определенные столбцы гораздо больше. чаще, чем другие. Если вы создаете запрос динамически, SQL Server может кэшировать планы для общих перестановок и сохранить эту дополнительную работу по перекомпиляции. С точки зрения администратора баз данных, теперь это также отдельные записи в кэше планов, которые вы можете проверить, чтобы понять, какие индексы могут быть более ценными для поддержки этой функции поиска с течением времени.
Конечно, зная, будут ли или нет, это будет выигрыш, значит знать свои данные, свою систему и своих пользователей. Вы должны выполнить работу, чтобы go вернуться и проверить, действительно ли пользователи выполняют поиск в одних и тех же наборах столбцов, или же они более случайны. создайте этот динамический c SQL в клиентском коде, что немного похоже на то, что вы ожидаете сделать это как часть хранимой процедуры.
Например, с псевдокодом C#:
sql = "SELECT ... FROM... WHERE 1=1";
if (txtCol1.Text != "")
{
sql += " AND Col1 = @Col1"
cmd.Parameters.AddWithValue("@Col1", txtCol1.Text);
}
if (txtCol1.Text != "")
{
sql += " AND Col2 = @Col2"
cmd.Parameters.AddWithValue("@Col2", txtCol2.Text);
}
//...
// Note this is just pseudocode. I'm not a fan of AddWithValue() in actual practice.
cmd.ExecuteReader();
Я знаю, что 1=1
кажется странным, но это не повредит SQL серверу, и это простой способ убедиться, что синтаксис все еще действителен, независимо от того, какой (если есть) из дальнейшие условия - первое, которое удерживает значение.