SQLServer查询使用内存效率不高

时间:2016-01-18 07:34:28

标签: sql sql-server optimization insert query-optimization

我在Sql Server中开发了一个insert语句。它利用了几个连接以及内部选择。由于内存不足,导致数据库出现问题。

尽管只插入了几百行,但还需要几分钟才能运行。有没有人建议我如何改进这个查询,以便在不改变最终结果的情况下更有效地运行?谢谢!

insert into This_Table 
select distinct *
from fv
join lv on lv.field1 = fv.field1
join sa on sa.field1 = fv.field2
where field3 + field2 not in (select distinct field3 + field2
from fv
join lv on lv.field1 = fv.field1
join This_Table T on fv.field2 COLLATE SQL_Latin1_General_CP1_CI_AS + case 
when COMPONENT_PART COLLATE SQL_Latin1_General_CP1_CI_AS like 'S%' or `COMPONENT_PART COLLATE SQL_Latin1_General_CP1_CI_AS like 'T%' then STUFF(field3 COLLATE SQL_Latin1_General_CP1_CI_AS, 1, 1, '') else COMPONENT_PART COLLATE     SQL_Latin1_General_CP1_CI_AS end like T.field4 + case when field5 like 'S%' or     field5 like 'T%' then STUFF(field5, 1, 1, '') else T.field5 end + '%')`
and SA.field6 <> 'EXPIRED'
order by field3

1 个答案:

答案 0 :(得分:0)

这里的赠品是您的查询中有DISTINCT。如果它适用于此处,我无法从您提供的信息中了解到,但在99%的情况下,我已经看到它被用来修复&## 39;不完整JOIN s。

其他一些说明:

  • 添加别名,尤其是在同一查询中多次使用同一个表时;这使事情更具可读性
  • 您可以使用LIKE '[AB]%'代替LIKE 'A%' OR LIKE 'B%'
  • 分别比较field3field2可能更有趣,而不是比较它们的总和
  • 尽量保持&#39;过滤器&#39;尽可能接近他们的表定义。在这种情况下,我建议将sa.field6 <> 'EXPIRED'放在JOIN sa子句旁边。这是可选的,但是如果您需要OUTER JOIN它突然变得必需!
  • 我对这里所有的整理魔法都有点警惕......但也许你的数据需要它......

无论如何,稍微改写你的代码,我来到这里:

INSERT INTO This_Table 
SELECT DISTINCT * -- need ALL fields? Even then, better specify them explicitly!
  FROM fv
  JOIN lv 
    ON lv.field1 = fv.field1
  JOIN sa 
    ON sa.field1 = fv.field2
   AND sa.field6 <> 'EXPIRED'
 WHERE NOT EXISTS ( SELECT *
                    FROM fv fv22
                    JOIN lv lv2 
                      ON lv2.field1 = fv2.field1
                    JOIN This_Table T 
                      ON fv2.field2 COLLATE SQL_Latin1_General_CP1_CI_AS 
                                + (CASE WHEN COMPONENT_PART COLLATE SQL_Latin1_General_CP1_CI_AS LIKE '[ST]%' 
                                            THEN STUFF(field3 COLLATE SQL_Latin1_General_CP1_CI_AS, 1, 1, '')             
                                            ELSE COMPONENT_PART COLLATE SQL_Latin1_General_CP1_CI_AS END) 
                               LIKE T.field4 + (CASE WHEN field5 LIKE '[ST]%' 
                                                        THEN STUFF(field5, 1, 1, '') 
                                                        ELSE T.field5 END + '%')

                   WHERE fv2.field2 = fv.field2 -- not quite the same as what you had but I'm guessing this is what you wanted
                     AND fv2.field3 = fv.field3 )

回顾这一点,假设我没有陷入困境,我现在想知道你是否真的需要lv加入到ViewController