Тип данных text не очень хорошо работает в предложении where - PullRequest
3 голосов
/ 21 марта 2012

У меня есть хранимая процедура, которая возвращает несколько полей, большинство из которых содержат некоторую информацию о клиенте, а затем еще 1, которая содержит xslfo «blob» в текстовом поле типа данных.Я пытаюсь оптимизировать процесс, чтобы игнорировать записи, которые не имеют значения в этом текстовом поле типа данных, но когда я добавляю это в предложение where:

And cl.CorrespondenceFO IS NOT NULL
And Convert(varchar(1), cl.CorrespondenceFO) <> ''

Тайм-аут запроса.Я понимаю, что текстовый тип данных устарел, поэтому в будущем мне нужно будет преобразовать этот столбец, но мне нужно оптимизировать его до того, как это произойдет.Есть ли какие-либо предложения о том, как я могу получить эту хранимую процедуру для возврата результатов с этими двумя дополнительными предложениями where?TIA

Редактировать: я обновил типы данных до varchar (max) и перепробовал все приведенные ниже предложения, но запрос все еще не закончился.Любые другие предложения?

Ответы [ 5 ]

4 голосов
/ 21 марта 2012
  1. Конвертировать в varchar(max) сейчас
  2. Исправьте ваши данные при записи, запретив пустую строку с ограничением CHECK
  3. Использовать WHERE ... cl.CorrespondenceFO IS NOT NULL только

Я не могу проверить, но проверка IS NOT NULL должна использовать битовую карту NULL

Либо используйте вычисляемый столбец с LEN (или DATALENGTH для текста) и отфильтруйте / отфильтруйте его.

3 голосов
/ 21 марта 2012

Почему вы все еще используете TEXT?Это должно быть VARCHAR(MAX).Вместо вашего запроса, почему бы и нет:

WHERE DATALENGTH(cl.CorrespondenceFO) > 0;

(хотя я согласен с @gbn - вам не следует разрешать пустую строку, если она означает для вас то же, что и NULL.)

1 голос
/ 21 марта 2012

Преобразование в VARCHAR не очень эффективно, вы уверены, что cl.CorrespondenceFO IS NOT NULL недостаточно для фильтрации строк с пустыми BLOB-объектами?

Если этого действительно недостаточно, вы можете использоватьDATALENGTH чтобы избежать конвертации:

And cl.CorrespondenceFO IS NOT NULL
And DATALENGTH(cl.CorrespondenceFO) > 0
0 голосов
/ 05 апреля 2012

Я наконец получил это на работу. После предложений по преобразованию моих старых типов данных text, ntext и image в varchar (max), nvarchar (max) и varbinary (max) запрос все еще не выполнялся. Итак, вот исправление, которое сработало.

Старая версия = Выберите FieldA, FieldB Из таблицы А Где FieldA In («значение1», «значение2») А Лен (FieldB)> 0 - это то, что не сработало

Новая версия = Создать таблицу #temp ( FieldA varchar (10), FieldB varchar (max) )

Вставить в #temp ( FieldA, FieldB ) Выберите FieldA, FieldB Из таблицы А Где FieldA In ('значение1', 'значение2')

Выбрать * От #temp Где Лен (FieldB)> 0

Drop Table # temp

(я не уверен, почему мое форматирование не работает, извините)

По какой-то причине запрос всегда прерывался, когда я пытался выполнить проверку Len () в исходном запросе (может иметь отношение к таблице, превышающей 17 миллионов записей), поэтому просто генерируем подмножество записи, с которыми нужно иметь дело, а затем проверка Len () этого подмножества позволила мне своевременно получить свои записи.

Спасибо всем!

0 голосов
/ 21 марта 2012

Я не знаком с SQL Server, но если его текстовый тип похож на текстовый тип MySQL / PostGres, он будет неэффективным. Эти типы хранятся вне таблицы, поэтому фактическая строка содержит только указатель на фактический текстовый блоб. Это означает, что поиск дисков много, индекс не принесет вам много пользы и т. Д.

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