2016-07-20 7 views
0

Ich bin mit SQL Server 2008 R2 und hatte unter AbfrageOptimierung Zeilennummer Abfrage

select * from 
(  
    select d.ID as ID, 
      .... 
      ....   
      ROW_NUMBER() OVER 
      (
       ORDER BY #some field       
      ) AS RowNum 
    from 
    /*some table*/ 
    LEFT join 
    (select Device_ID,   
      Level,   
      ROW_NUMBER() over (partition by Device_ID order by id desc) as rn 
    from #sometable as de WITH (NOLOCK) 
    where #some condition 
    ) t 
    where t.rn = 1)tmp on ID=tmp.Device_ID **/* sort operation 1*/** 
    /*some more joins */ 
    WHERE /*some condition*/ 
) as DbD 
where RowNum BETWEEN @SkipRowsLocal and (@SkipRowsLocal + @TakeRowsLocal - 1) 
order by RowNum 

Ich versuche Paginierung Art von Abfrage von Probe zu implementieren http://blog.sqlauthority.com/2013/04/14/sql-server-tricks-for-row-offset-and-paging-in-various-versions-of-sql-server/

aber sieht aus wie es ist sehr langsam ausgeführt wird, wenn ich in Abfrage Plan sort Operation untersucht verbraucht fast 50% der Abfrage Zeit und ich denke, es ist die erste Sortieroperation, die ich als 1 markiert, im Grunde in der temporären Tabelle t möchte ich den neuesten Wert abrufen und in der äußeren Reihe Nummer wollte ich holen sage nur 40 Datensätze.

Es ist im Grunde wie 10K Zeilen zu sortieren und dann 40 davon zu nehmen, gibt es eine Möglichkeit, diese Abfrage zu verbessern?

+0

Ausführungsplan und Tabelle Definition, bitte –

+0

haben Sie einen Index DeviceId, ID? Auch ein Index über 'ORDER BY #some field' - was auch immer das Feld #some ist? – Cato

+0

Versuchen Sie 'where t.rn = 1' in' äußere Anwendung zu drehen (wählen Sie oben 1' ohne Zeilennummer (die zweite). –

Antwort

0

anstelle eines linken Joins, versuchen Sie ein OUTER APPLY, um die TOP 1 des Gerätes zu erhalten, das Sie interessiert - denken Sie daran als 'Ich bekomme einen Datensatz aus der ersten Tabelle, dann gehe ich und erhalten die TOP 1 für die Geräte-ID in der anderen Tabelle, aber nicht vergessen, dass in der zweiten Tabelle, Sie durch die Daten aus der ersten Tabelle suchen müssen, anstatt eine Verknüpfung

select * from 
     (  
     select d.ID as ID, 
        .... 
        ....   
        ROW_NUMBER() OVER 
        (
         ORDER BY #some field       
        ) AS RowNum 
      from 
      /*some table*/ 
      OUTER APPLY 
      (select TOP 1 Device_ID,   
        Level   

         from #sometable as de WITH (NOLOCK) 
         where #some condition and Device_ID = [/*some table*/].id ORDER BY id DESC 
      ) t 
      )tmp 
      /*some more joins */ 
      WHERE /*some condition*/ 
     ) as DbD 
     where RowNum BETWEEN @SkipRowsLocal and (@SkipRowsLocal + @TakeRowsLocal - 1) 
     order by RowNum 

etwas auf diesen Linien, Sie Vielleicht möchten Sie nur die relevanten Teile der Abfrage erstellen und vergleichen, würde es scheinen zu vermeiden, sortieren und mit einem Index könnte auch schnell sein