SQL Server - 减少读取次数[关闭]

Posted

技术标签:

【中文标题】SQL Server - 减少读取次数[关闭]【英文标题】:SQL Server - Reduce number of Reads [closed] 【发布时间】:2011-08-09 14:29:32 【问题描述】:

我有一个关于 SQL Server 优化的一般性问题:如何减少存储过程中的读取次数?

我对以下良好做法感兴趣: - 在物理表和临时表上创建索引 - 在过程中使用临时表而不是使用同一个表几次 - DML 之前的 DDL - 在存储过程开始时设置 NOCOUNT ON - ...

由于几个存储过程导致大量读取,我们遇到了磁盘空间使用问题,我需要对其进行优化。

“最昂贵”的部分存储过程是:

create table #stavke   
(  
    Id_Br int identity(1, 1), IDStavke int, 
    HeaderID int, Currency varchar(3),  GLAcct varchar(20), id varchar(20), Trnuid varchar(60), 
    ReferenceID varchar(20), DocumentID varchar(20),
    DtAvail varchar(10), DtBooking varchar(10), DatePosted varchar(10),
    Amount money, AmountLcl money, 
    Description varchar(250), Type varchar(10), DP int  )
insert into #stavke   
  (  
    IDStavke, HeaderID, GLAcct, Currency, id , Trnuid , 
    ReferenceID, DocumentID ,
    DtAvail , DtBooking , DatePosted,
    Amount , AmountLcl , 
    Description , Type , DP 
  )  

SELECT S.ID as IDStavke,
   z.RB as HeaderID,  
   z.KONTO AS GLAcct,
   z.OZNVAL AS Currency,
   Si.BROJNALOGA as ID,
   D.TRN as Trnuid, 
   case substring(SI.BROJNALOGA,1,4)
        when '0746' then O.REFERENCA
        when '1450' then D.REFERENCA
        when '0743' then L.REFERENCA
        when '2021' then N.REFERENCA
   end   ReferenceID,
   case substring(SI.BROJNALOGA,1,4)
        when '3000' then 'Kursna razlika'
        when '2200' then 'PP-'+SI.BROJNALOGA
        when '2201' then 'KDP-'+SI.BROJNALOGA
        else SI.BROJNALOGA
   end DocumentID,
   dvalute as DtAvail, 
   si.dknizenja as DtBooking, 
   '' as DatePosted,        
   case si.teret
        when 0 then si.korist
        else si.teret 
   end Amount, 
   case SI.DINTERET
        when 0 then si.dinkorist
        else si.dinteret 
   end AmountLcl, 
   '' as Description,
   case substring(SI.BROJNALOGA,1,4)
        when '0746' then '0746'
        when '1450' then '1450'
        when '0743' then '0743'
        when '2021' then  'Ostalo'
   end  Type,
   case SI.DINTERET
        when 0 then 1
        else -1 
   end DP
FROM       A I
inner join B st on i.transfer=st.transfer and i.partija=st.partija 
INNER JOIN C SI ON st.RB=Si.RB
inner join D z on z.rb=st.rb
inner join E s on z.rb=s.rb AND s.BROJNALOGA = si.BROJNALOGA 
LEFT JOIN  F D ON  D.BROJ=SI.BROJNALOGA
LEFT JOIN  G L ON L.BROJ=SI.BROJNALOGA
LEFT JOIN  H O ON O.BROJ=SI.BROJNALOGA
LEFT JOIN  I N ON N.BROJ=SI.BROJNALOGA 
WHERE I.novi_izvod=convert(int,@StatementNumber) AND i.PARTIJA=@Account 
ORDER BY I.PARTIJA,z.RB,SI.id, z.KONTO,z.OZNVAL, SI.DKNIZENJA

表 B、G、H 和 I(我为这个示例更改了表的真实名称以便于阅读)非常大,即有很多列和大量数据。

【问题讨论】:

READS 如何在您的环境中造成磁盘空间问题? 这是一个非常广泛的问题,许多大书都专门讨论过这个问题。您最好问一个更具体的问题(如何优化 X)并提供代码和架构。 我同意您需要在这里提出具体问题。如果您有几个有问题的存储过程,请将它们发布并询问如何优化。 我会将此迁移到dba.stackexchange.com,但以目前的形式,这个问题太模糊了。 我以这种方式编辑了帖子,添加了部分“最昂贵”的存储过程,需要更改。另外,我建议管理员在关闭之前给帖子编辑更多时间,因为我看到你的答案太晚了,可能是因为不同的时区...... 【参考方案1】:

我希望你说的是通过一个过程来最小化磁盘活动。

首先,您可以使用

基准测试您当前的 IO 活动
set statistics IO on;

有了这些信息并使用 SET SHOWPLAN_ALL 或 XML 获取执行计划,或者您可以使用 ssms 以符合人体工程学的方式获得相同的结果。您可以使用 DTA 进行基本调整。

尝试将 SP 作为一组即席语句执行,看看哪里 IO 很重,然后专注于该段。有很多好的做法可能适合您的要求。

【讨论】:

谢谢你的回答,我用这种方式优化了存储过程,得到了很好的效果!首先我使用 SET STATISTICS IO ON;并且在执行计划中已经看到程序的哪些部分消耗了最多的资源。之后使用数据库引擎优化顾问并根据我得到的建议创建索引。还得到了创建 STATISTICS 和一些可以提高性能的表的建议。在 MSDN,我发现了接受 DETA 的建议以创建 STATISTICS 的建议。

以上是关于SQL Server - 减少读取次数[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从 MS Access 批量导入并插入 Sql Server [关闭]

任何程序可以将多个图像组合成一个以与 CSS 一起使用并减少往返次数? [关闭]

从 Kafka 提要读入 SQL Server [关闭]

sql server 中游标详解

如何在 SQL Server CE 数据库中插入多行? [关闭]

打印文件中每个单词的出现次数[关闭]