Принудительно выполнить внутренний запрос перед внешним запросом - PullRequest
3 голосов
/ 14 апреля 2011

У меня есть две таблицы, к которым мне нужно присоединиться:

Таблица VarValues ​​имеет поле Value, которое является varchar и содержит настраиваемые свойства, которые могут быть text og int в зависимости от типа свойства

Таблица Vars имеет тип свойства.

В элементах таблицы есть элементы, в частности идентификатор и данные, которые проиндексированы в полнотекстовом формате, и мне нужно выполнить поиск.

Когда я запрашиваю вот так:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, convert(int, [value]) as fileid
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
        WHERE
            [type] = 6 --This type is an int
            AND
            [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]

Внутренний запрос возвращает целые числа только в качестве fileid, но когда весь запрос выполняется, я получаю сообщение об ошибке, поскольку первая строка в VarValues ​​содержит текст, хотя тип не равен 6.

Не оптимизирует ли оптимизатор запросов мой внутренний запрос? Как я могу остановить это? Или я делаю это совершенно неправильно?

Ответы [ 3 ]

2 голосов
/ 14 апреля 2011

Оптимизатор может расширять представления (включая встроенные) и может самостоятельно выбирать порядок фильтрации.

Другими словами, он может сначала выполнить объединение с полнотекстовой таблицей, а затем отфильтровать результаты на type = 6 (что, похоже, и происходит в вашем случае).

Вы можете попробовать добавить OPTION (FORCE ORDER) к вашему запросу, однако это гарантирует только порядок таблиц в операциях соединения, а не порядок применения фильтров.

Попробуйте переписать ваш запрос так:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, CAST(CASE WHEN IsNumeric([value]) = 1 THEN [value] END AS INT) AS field
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
        WHERE
            [type] = 6 --This type is an int
            AND
            [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]
1 голос
/ 14 апреля 2011

Вы можете попытаться сохранить результат внутреннего запроса во временной / переменной таблице и использовать его в основном запросе.

Что-то вроде:

CREATE TABLE #vars (itemid, fileid)

-- store values for inner query
INSERT INTO 
    #vars (itemid, fileid)
SELECT  
    [values].itemid, 
    CAST(CASE WHEN IsNumeric([value] = 1 THEN [value] END AS INT) AS field
FROM 
    VarValues [values]
    JOIN 
        Vars vars 
    ON 
        [values].VarID = vars.ID
WHERE
    [type] = 6 --This type is an int
    AND [values].[value] <> ''


SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    #vars as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]    

Это должно решить вашу проблему.

0 голосов
/ 14 апреля 2011

Я думаю, вы также можете добавить условие IsNumeric([value]) = 1 к первому соединению:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, convert(int, [value]) as fileid
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
                          AND IsNumeric([value]) = 1 
        WHERE
            [type] = 6 --This type is an int
            AND [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items
      ON SelectedItems.fileid = items.[KEY]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...