2016-02-24 63 views
1

我对SQL Server非常陌生,最终让我的代码运行,但速度很慢。我的数据库有点大(1.22毫米行,3列),我有一些while循环,我知道这并不理想,但我找不到解决方法。获取SQL服务器查询运行速度更快

任何帮助将不胜感激!

declare @b float 
declare @c float 
declare @dateloopfora datetime 
declare @dateloopforc datetime 

BEGIN 
    SET @MYCURSOR = CURSOR FOR 
     SELECT DISTINCT [STOCKS] FROM [tsxvPrices].[dbo].[3coldata] 

    OPEN @MYCURSOR 

    FETCH NEXT FROM @MYCURSOR INTO @STOCK 

    set @end = '12/30/2012' 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     print ('Stockname restart: ' + @stock) 
     SET @dateloop = '01/01/2012' 

     WHILE (@dateloop <= @end) 
     BEGIN 
      set @datedelta = 0 
      SET @dateloop = dateadd(day,1,@dateloop) 
      set @b = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = @dateloop and [stocks] = @stock)) 

      WHILE (@datedelta < 4) 
      BEGIN 
       set @datedelta = @datedelta + 1 

       if (@b is null) 
       begin 
        SET @dateloop = dateadd(day,1,@dateloop) 
        set @b = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = @dateloop and [stocks] = @STOCK)) 
        /*print ('b= ' + cast(@b as varchar(10)) + ' dateadd1=' + cast(@datedelta as varchar(10))) */ 
       end 
      END 

     SET @datedelta = 0 
     set @a = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = dateadd(day,-1,@dateloop) and [stocks] = @stock)) 
     set @c = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = dateadd(day,+96,@dateloop) and [stocks] = @stock)) 

     if @b/@a < 0.8 
     begin 
      WHILE (@datedelta < 4) 
      BEGIN 
       set @datedelta = @datedelta + 1 

       if (@a is null) 
       begin 
        SET @dateloopfora = dateadd(day,[email protected],@dateloop) 
        set @a = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = @dateloopfora and [stocks] = @STOCK)) 
        /*print ('b= ' + cast(@b as varchar(10)) + ' dateadd1=' + cast(@datedelta as varchar(10))) */ 
       end 

       if (@c is null) 
       begin 
        SET @dateloopforc = dateadd(day,[email protected],@dateloop) 
        set @c = (SELECT [val] FROM [tsxvPrices].[dbo].[3coldata] WHERE([dates] = @dateloopforc and [stocks] = @STOCK)) 
        /*print ('b= ' + cast(@b as varchar(10)) + ' dateadd1=' + cast(@datedelta as varchar(10))) */ 
       end 
      END 

      /*print ('Stockname: ' + @stock) 
      print @dateloop 
      print('daily') 
      print @b/@a 
      print ('quarterly')*/ 
      print @c/@b 
      /*print ('======================')*/ 
     end 
    END 

    FETCH NEXT FROM @MYCURSOR INTO @STOCK 
END 

CLOSE @MYCURSOR 
DEALLOCATE @MYCURSOR 
+5

你有一个嵌套循环的O(N^3)。这将会有非常糟糕的表现。我建议使用基于集合的方法。如果您提供样本数据,并且期望的输出将会很好。 –

+1

您正在编写SQL,就像它是面向对象的编程语言,而不是基于集合的查询语言。 我建议你首先用你所拥有的表格列出需求(你期待的结果集)。然后再次,堆栈溢出不是真的是我的论坛的一个请写我的代码。但是,我不确定从你发布的内容开始。 我想如果我是主持人,我会投票结束。 – maplemale

+1

你没有机会去sql server来优化任何东西,因为你正在一步一步做。 –

回答

0

我可以直接看到一个简单的问题,您使用的是光标。 这可能是处理SQL的最糟糕的方法之一,它非常慢,并且迫使SQL引擎非常低效。

你是新来的SQL所以我就放弃了技术解释,但请看看这个StackOverflow的其他问题:

Why is it considered bad practice to use cursors in SQL Server?

我可能能够提供进一步的建议,什么版本的SQL你用?

+0

我正在使用MS sql server 2014.最初我打算使用循环代替游标,但由于这些数据是股票名称,我开始寻找一个可以工作的循环,并且我找到了Cursor。 – Jordan

+0

是的,对于初学SQL的人来说,这是一个容易陷阱,也许你可以像maplemale一样对你的问题发表评论,并发布一些我们需要分析的数据。 –

相关问题