2016-04-19 11 views
0

Wir verfügen über eine Webanwendung, mit der Sie biologische Experimente organisieren können (Benutzer beschreiben das Experiment und laden Experimentdaten hoch). Auf der Hauptseite zeigen wir die ersten 10 Experimente und dann unter Zurück Weiter 1 2 3 .. 30.So erstellen Sie effiziente Seitenumbrüche mit Gesamtzählung

Ich habe Probleme mit der effizienten Zählung und Seitenumrechnung. Derzeit:

select count(id) from experiments; // not very efficient in large datasets 

aber wie skaliert dies im Umgang mit großen Datensätzen> 200.000. Ich habe versucht, zufällige Experimente in Tabelle zu importieren, aber es funktioniert immer noch ganz ok (0,6 s für 300.000 Experimente).

Die andere Alternative, über die ich nachgedacht habe, ist die zusätzliche Tabelle statistics (column tableName, column recordsCount) hinzuzufügen. Also nach jedem Einfügen in die Tabelle experiments würde ich recordsCount in statistics erhöhen (das bedeutet das Einfügen in eine Tabelle und das Aktualisieren anderer, mit SQL-Transaktion natürlich). Umgekehrt gilt delete statement (recordsCount--).

Für Paginierung ist der effizienteste Weg zu tun where id > last_id als SQL verwendet Index natürlich. Gibt es einen anderen besseren Weg?

Für den Fall, dass die Ergebnisse z.B. select * from experiment where name like 'name%', Option mit Tabelle statistics schlägt fehl. Wir müssen die Gesamtzahl erhalten als: select count(id) from experiment where name like 'name%'.

Anwendung wurde mit Laravel 3 entwickelt, falls es einen Unterschied macht.

Ich möchte eine Seitennummerierung entwickeln, die immer das gleiche leistet. Die Anzahl der Datensätze darf sich nicht auf die Paginierung oder die Gesamtzahl der Datensätze auswirken.

Antwort

0

Bitte haben Sie die Abfrage wie folgt:

CREATE PROCEDURE [GetUsers]  
( 
@Inactive Bit = NULL,  
@Name Nvarchar(500),  
@Culture VarChar(5) = NULL,  
@SortExpression VarChar(50),  
@StartRowIndex Int,  
@MaxRowIndex Int, 
@Count INT OUTPUT  
)  
AS  
BEGIN  



    SELECT ROW_NUMBER()  
    OVER  
    ( 
    ORDER BY  

    CASE WHEN @SortExpression = 'Name' THEN [User].[Name] END,  
    CASE WHEN @SortExpression = 'Name DESC' THEN [User].[Name] END DESC  

    ) AS RowIndex, [User].*  
    INTO #tmpTable 
    FROM [User] WITH (NOLOCK)  
    WHERE (@Inactive IS NULL OR [User].[Inactive] = @Inactive)  
    AND (@Culture IS NULL OR [User].[DefaultCulture] = @Culture)  
    AND [User].Name LIKE '%' + @Name + '%'  



SELECT *  
FROM #tmpTable WITH (NOLOCK)  
WHERE #tmpTable.RowIndex > @StartRowIndex  
AND #tmpTable.RowIndex < (@StartRowIndex + @MaxRowIndex + 1)  

SELECT @Count = COUNT(*) FROM #tmpTable    

IF OBJECT_ID('tempdb..#tmpTable') IS NOT NULL DROP TABLE #tmpTable;  
END 
Verwandte Themen