2014-09-16 3 views
1

У меня есть функция внутри хранимой процедуры, которая заставляет мой sql перейти от 1 секунды до 10-14 секунд. Может кто-то помочь мне объединить их в одну встроенную функцию, так что мой sql ускорится.SQL-функции для преобразования inline

INSERT INTO 
    #tempTable 
SELECT DISTINCT 
    PRODUCT.name, 
    dbo.getProductTopImage(PRODUCT.name) as image 
FROM 
    dbo.PRODUCT 

getProductTopImage Функция

CREATE FUNCTION dbo.getProductTopImage 
(
    @PRODUCTNAME VARCHAR(255) 
) 
RETURNS VARCHAR(255) 
AS 
BEGIN 
    DECLARE @IMAGE AS VARCHAR(255) 
    DECLARE @ID AS INT 

    SELECT TOP 1 
     @IMAGE = PRODUCT.image, 
     @ID = PRODUCT.id 
    FROM 
     PRODUCT 
    WHERE 
     PRODUCT.name = @PRODUCTNAME 

    IF @IMAGE IS NULL 
     BEGIN 
      SET @IMAGE = dbo.func_getImageRefs(@ID, 1) 
     END 

    RETURN @IMAGE 
END 

func_getImageRefs Функция

CREATE FUNCTION dbo.func_getImageRefs 
    (
     @ProductId AS INT, 
     @Place AS INT 
    ) 
RETURNS VARCHAR(20) 
AS 

    BEGIN 
    DECLARE @REF AS VARCHAR(20) 
    SET @REF = '0' 
     SELECT 
      @REF = PLANTIMAGE.imageRef 
      FROM PRODUCT 
       LEFT OUTER JOIN 
      dbo.PLANTIMAGE 
     ON 
      dbo.PRODUCT.hls = PLANTIMAGE.plantid 
      WHERE PRODUCT.id = @ProductId AND PLANTIMAGE.imageNum = @Place 

      RETURN @REF 
    END 
+0

Итак, при замене 'SELECT @IMAGE = PLANTIMAGE.imageRef' с' SET @IMAGE = dbo.func_getImageRefs (@ID, 1) 'время выполнения увеличивается? – Bulat

+0

Не пожалеете, если я удаляю «dbo.getProductTopImage (PRODUCT.name) как изображение» из хранимой процедуры и заменяю что-то вроде «« как изображение », оно переходит на 1 секунду для запуска. Вышеупомянутая сохраненная процедура - это всего лишь фрагмент большого запроса, но это означает, что эта функция вызывает замедление. –

+1

. Пока неясно, где находится версия, которая занимает больше времени. – Bulat

ответ

3

Если я понять ваш вопрос правильно, я не думаю, что вы должны использовать функции на всех.

with cte as (
    select *, 
     row_number() over (partition by name order by id) rn 
    from product 
) 
select 
    c.name, 
    coalesce(c.image, pi.imageref) 
from cte c 
    left join plantimage pi on c.hls = pi.plantid and pi.imageNum = 1 
where c.rn = 1 

Это создает общее табличное выражение для хранения row_number(). Используя это поле, вы можете отобразить свой оператор SELECT TOP 1. Затем вы можете использовать COALESCE и присоединиться к таблице plantimage. Если изображение из таблицы product равно null, тогда оно вернет изображение из таблицы plantimage, если оно существует. Вам также необходимо переместить часть ваших критериев WHERE в JOIN для поддержания OUTER JOIN.

+0

Это выглядит очень впечатляюще, я быстро отдам его и посмотрю, как мы будем двигаться дальше. Большое вам спасибо за это предложение. –

+0

это будет по умолчанию imageref равным нулю - 'coalesce (c.image, pi.imageref, 0)' – Bulat

+0

также, если вы можете иметь несколько записей 'plantimage' с imageNumbe = 1, вам нужно будет сгруппировать по c.name – Bulat

Смежные вопросы