2016-06-18 14 views
0

私は新しいテーブル値関数を作成しましたが、そのアプローチがあまり良くないことに気付きました。主な問題(私の意見では)は、tvfに宣言の新しいテーブルを使用しています。私はこれがtvfにはあまり良くないと確信しています。テーブル値関数での一時テーブルの使用。クエリの最適化

ALTER FUNCTION [dbo].[tvf_GetOnSaleDate] 
(
    @EntityType INT 
) 

RETURNS @Result TABLE(OnSaleDate DATETIME, EntityId INT) 
BEGIN 
    DECLARE @Sales TABLE (SaleDate DATETIME, EntityId INT, SaleDateVenueDate DATE, CurrentVenueDate DATE) 

    INSERT @Sales (SaleDate, EntityId, SaleDateVenueDate, CurrentVenueDate) 

    SELECT SaleDate, EntityId, CAST(DATEADD(hour, vc.HoursOffset, SaleDate) AS DATE) AS SaleDateVenueDate, CAST(DATEADD(hour, vc.HoursOffset, GETUTCDATE()) AS DATE) AS CurrentVenueDate 
    FROM dbo.om_EntityOnSale AS es WITH (NOLOCK) 
     INNER JOIN dbo.event AS e WITH (NOLOCK) ON e.event_id = es.EntityId AND es.EntityType = @EntityType 
     INNER JOIN dbo.om_Venue AS vc WITH (NOLOCK) ON vc.Indux_Venue_Id = e.venue_id 

    INSERT @Result(OnSaleDate, EntityId) 
    SELECT [OnSaleDate] = 
    CASE 
     WHEN (SELECT COUNT([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] = [CurrentVenueDate] AND [EntityId] = sales.EntityId) > 0 
     THEN ISNULL((SELECT MIN([SaleDate]) FROM @Sales WHERE [SaleDate] > GETUTCDATE() AND [SaleDateVenueDate] = [CurrentVenueDate] AND [EntityId] = sales.EntityId), 
        (SELECT MAX([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] = [CurrentVenueDate] AND [EntityId] = sales.EntityId)) 
     WHEN (SELECT COUNT([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] > [CurrentVenueDate] AND [EntityId] = sales.EntityId) > 0 
     THEN (SELECT MIN([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] > [CurrentVenueDate] AND [EntityId] = sales.EntityId) 

     WHEN (SELECT COUNT([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] < [CurrentVenueDate] AND [EntityId] = sales.EntityId) > 0 
     THEN (SELECT MAX([SaleDate]) FROM @Sales WHERE [SaleDateVenueDate] < [CurrentVenueDate] AND [EntityId] = sales.EntityId) 
    END, sales.[EntityId] 
    FROM @Sales sales 
    GROUP BY EntityId 

    RETURN 
END 

この機能を最適化するにはどうすればよいですか?

+0

このアプローチがあまりよくないと思われる理由を説明すると、役立つでしょう。今あなたの問題が何であるか把握するのに多くの時間がかかります。 – Roland

+0

私はたくさんのSQLを知っていませんが、別の「ビュー」から自分のテレビ番組を呼び出す場合は、「表示」の各行について「挿入」を行うことを意味する を意味します。それは良いとは思わない。 –

+0

@DenisGvozd、TVFではなくCTEを使用できますか? –

答えて

0

この操作では、インラインテーブル値関数がうまくいくはずですが、私はあなたのテーブル変数がSalesに必要ではないと思います。私が読んでいるコードから意図した結果が得られているとは思われません。私はあなたのスキーマについて推測しようとしています。しかし、あなたはテーブルのデータとあなたの意図した結果の例を与えていません。私はあなたがあなたのOnSaleDateをどのように選択しているのか少し混乱しています。同じ列のMaxまたはMinを選択しているのは、entityidが表す値に応じて同じ値になる場合があります。 SaleDateはどのテーブルですか?

+0

om_EntityOnSaleこの TABLE [DBO]。[om_EntityOnSale]( [ID] [INT] IDENTITY(1,1)NOT NULLのように見える、 [SaleDate] [日時] NOT NULL、 [メモ] [VARCHAR](2000私temproraryテーブルの)NULL、 [実体識別子]の[int]は、NOT NULL、 [EntityType]の[int]は、NOT NULL、 [IsDeleted] [ビット]、NOT NULL 主な目標 - 。SaleDateVenueDateとCurrentVenueDateを保存 私が使用して必要'case'セクションのロジックはもっと複雑ですが、私は例えば一部しかコピーしませんでした。これは、 "UI"に表示される "SaleDate"が現在の会場の時間に依存するためです。 –

+0

@Denis実際にテーブル変数を使用していますが、関数ではデータテーブルやスキーマの変更が許可されていないため、テンポラリテーブルは使用できません。その変数は、クエリを最適化するために排除する最も重要なものですが、あなたのロジックやロジックの記述がonSaleDateのためにわからないと、時間がかかることはありません。ロジックを使用して説明を更新したい場合は、もう一度見ていきます。 – Matt

+0

スクリプトを更新しました。このイベントで今日販売日が1つしかない場合は、今日、その日のSaleDateを表示します。 真夜中になると、そのイベントに他の販売日が設定されていない場合は、次の販売日に切り替える必要があります。 イベントに複数のセールがある場合は、現在のセールスが過ぎてすぐに次のセールス日が表示されるように切り替える必要があります。 –

0

Приветжеланиярегистрироватьсяна "фрилансим"、отвечуздесь。

  1. Проверитьдолголиработаетперваячастьзапроса、возможнопроблематам、(нужныкакие-либодополнительныеиндексыилипростосуществующиеиндексыфрагментированы)。

  2. Вовторойчастизапроса:УсловиявзаменитьсвычисленияCOUNT()наは(этоточнобудетработатьбыстрее)が存在し、MIN /МАХзаменитьнаTOP 1(этоскореевсегобудетработатьбыстрее)、соответственноубратьгруппировку

    INSERT @Result(OnSaleDate, EntityId) 
    

    EXISTSが

    ([SaleDateVenueDate] = [CurrentVenueDate] AND [実体識別子] = sales.EntityId @salesから1を選択)WHEN CASEを選択。
    THEN ISNULL((SELECT TOP 1 [SaleDate] FROM @Sales WHERE [SaleDate] > GETUTCDATE() AND [SaleDateVenueDate] = [CurrentVenueDate] AND [EntityId] = sales.EntityId ORDER BY [SaleDate]), 
          (SELECT TOP 1 [SaleDate] FROM @Sales WHERE [SaleDateVenueDate] = [CurrentVenueDate] AND [EntityId] = sales.EntityId ORDER BY [SaleDate] DESC)) 
    
    WHEN EXISTS(SELECT 1 FROM @Sales WHERE [SaleDateVenueDate] > [CurrentVenueDate] AND [EntityId] = sales.EntityId) 
    
    THEN (SELECT TOP 1 [SaleDate] FROM @Sales WHERE [SaleDateVenueDate] > [CurrentVenueDate] AND [EntityId] = sales.EntityId ORDER BY [SaleDate]) 
    
    WHEN EXISTS(SELECT 1 FROM @Sales WHERE [SaleDateVenueDate] < [CurrentVenueDate] AND [EntityId] = sales.EntityId) 
    
    THEN (SELECT TOP 1 [SaleDate] FROM @Sales WHERE [SaleDateVenueDate] < [CurrentVenueDate] AND [EntityId] = sales.EntityId ORDER BY [SaleDate] DESC) 
    

    END、@sales販売から販売[実体識別子] 実体識別子

    BY GROUP

МойпрофильвのFacebook:Denis Rubashkin、пишите、еслибудутвопросы。

+0

英語に翻訳してください – KornMuffin

関連する問題