Если существует оператор SQL в тайм-ауте

2 user1400915 [2013-09-03 13:42:00]

If exists 
(
 select 1 from table A join table B
 on A.id = B.id
)
BEgin  
  Select 'Pass'
END
  Select 'Fail'

Я запутался с вышеуказанным запросом, который не выполняется вообще, пока он не истечет, когда он завернут в оператор If exists.

Когда выражение

 select 1 from table A join table B
 on A.id = B.id

выполняется, для получения результата требуется 20 секунд, но когда он завернут его в оператор If exists, он не выполняется вообще, и, наконец, после 4 -5 часов мне пришлось отменить его. Что может быть причиной этого?

sql sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2


2 ответа


0 Решение Used_By_Already [2013-10-10 07:47:00]

Изучили ли вы план выполнения? Я подозреваю, что проблема с производительностью глубже, чем конечное использование существует, и это помогло бы, если бы был доступен полный запрос, или, по крайней мере, полное представление о его структуре. В комментарии вы указываете эту более сложную структуру:

SELECT
        1
FROM table_A AS a
LEFT JOIN (                    -- << why a left join, is it achieving anything?
                SELECT
                        *            -- << not literally select * I hope
                FROM table_B AS b
                JOIN table_C AS c
                             ON b.thing = c.thing
                WHERE B.ColumnA IN (                -- << avoid this type of IN()
                                        SELECT      -- >> if this result is big
                                        columnX
                                        FROM table_D AS d
                                        )
                           ) AS x
                             ON a.thing = x.thing
;

Во внешнем запросе вы (или, по крайней мере, указываете), выполняете только "select 1", поэтому во вложенных подзапросах не нужно выбирать посторонние поля.

Вы указываете использование левого соединения, но так мало известно о деталях, которые я не могу сказать, нужно ли это или нет.

Возможно, наиболее очевидным местом для поиска было бы использование IN (подзапрос здесь), если этот подзапрос производит значительное количество строк, производительность ухудшится. Для этого лучше всего использовать соединение или использование EXISTS.

EDIT: в отношении получения плана выполнения рассмотрите возможность запуска каждого подзапроса независимо от самого внутреннего гнездования:

                                    SELECT      -- >> if this result is big
                                    columnX
                                    FROM table_D AS d

Использует ли он индексы, сколько строк возвращается (возможно, просто для этого счетчик (*))

Работайте оттуда до следующего подзапроса и рассмотрите альтернативы. например, это может сработать:

            SELECT
                    thing  -- << only that which is needed
            FROM table_B AS b
            JOIN table_C AS c
                         ON b.thing = c.thing
            JOIN (
                    SELECT distinct -- >> not a fan of distinct but might help here
                    columnX
                    FROM table_D
                 ) AS D
                   ON B.ColumnA = D.columnX

Что скажет вам план выполнения этой части?

Подобная работа должна способствовать общей оптимизации.


0 Jigar Shah [2013-09-04 07:55:00]

Попробуйте использовать верхнюю часть 1,

select top 1 1 from table A join table B  on A.id = B.id

Это может сократить время.