Я потратил довольно много времени на эту проблему, и, исходя из множества сценариев, я понял это:
если у вас есть Contains или ContainsTable где-либо в вашем запросе, то эта часть выполняется в первую очередь и довольно независимо. Это означает, что даже если остальные условия ограничивают ваш поиск только одной записью, это ни содержит, ни содержит в себе заботы об этом. Так что это похоже на параллельное выполнение.
Теперь, когда полнотекстовый поиск возвращает только поле Key, он немедленно ищет Key как первое поле других индексов, выбранных для запроса. Таким образом, для приведенного выше примера он ищет индекс с помощью [key], field1, field2. Проблема в том, что он выбирает индекс для остальной части запроса на основе полей в предложении where. так что для примера выше он выбирает покрытый индекс, который у меня есть, что-то вроде field1, field2, Id. (Идентификатор таблицы такой же, как [Ключ], возвращаемый из полнотекстового поиска). Итак, резюме:
- выполняет содержащийся в таблице
- выполняет оставшуюся часть запроса и выбирает индекс на основе предложения where запроса
- Он пытается объединить эти два. Следовательно, если индекс, выбранный для остальной части запроса, начинается с поля [key], это нормально. Однако, если индекс не имеет поля [key] в качестве первого ключа, он начинает выполнять циклы. Он даже не выполняет сканирование таблицы, иначе просмотр 5000 записей не будет таким медленным. То, как он выполняет цикл, заключается в том, что он запускает цикл для общего числа результатов от FTS, умноженного на общее количество результатов из остальной части запроса. Таким образом, если FTS возвращает 2000 записей, а остальная часть запроса возвращает 3000, цикл 2000 * 3000 = 6 000 000. Я не понимаю, почему.
Так что в моем случае он выполняет полнотекстовый поиск, затем выполняет остальную часть запроса, но выбирает закрытый индекс, который у меня есть, который основан на field1, field2, id (что неверно), и в результате он привинчивает вверх. Если бы я изменил свой покрытый индекс на Id, field1, field2, все было бы очень быстро.
Мое ожидание состояло в том, что FTS возвращает группу [key], остальная часть запроса возвращает группу [Id], а затем Id должен быть сопоставлен с [key].
Конечно, я попытался упростить свой запрос здесь, но фактический запрос намного сложнее, и я не могу просто изменить индекс. У меня также есть сценарии, в которых текст, переданный в виде полного текста, является пустым, и в этих сценариях я даже не хочу объединяться с содержащимися таблицами.
В этих случаях изменение моего покрытого индекса на поле id в качестве первого поля приведет к катастрофе.
В любом случае, сейчас я выбрал решение для временной таблицы, так как оно работает для меня. Я также ограничиваю результат несколькими тысячами, что помогает с потенциальными проблемами производительности переменных таблицы, когда число записей становится слишком большим.
спасибо