sql >> Database teknologi >  >> RDS >> Sqlserver

Paginering i SQL - Performance problem

Jeg tjekker altid, hvor mange data jeg har adgang til i forespørgslen, og forsøger at fjerne unødvendige kolonner såvel som rækker. Nå, det er blot indlysende punkter, som du måske allerede har tjekket, men bare ville påpege, hvis du ikke allerede har gjort det. forespørgsel den langsomme ydeevne kan skyldes, at du laver "Vælg *". At vælge alle kolonner fra tabellen tillader ikke at komme med en god eksekveringsplan. Tjek, om du kun har brug for udvalgte kolonner, og sørg for, at du har korrekt dækkende indeks på tabelordrer.

Fordi den eksplicitte SKIPP- eller OFFSET-funktion ikke er tilgængelig i SQL 2008-versionen, skal vi oprette en, og den kan vi oprette ved INNER JOIN. I en forespørgsel genererer vi først ID med OrderDate, og intet andet vil være i den forespørgsel. Vi gør det samme i anden forespørgsel, men her vælger vi også nogle andre interesserede kolonner fra tabellen ORDRE eller ALLE, hvis du har brug for kolonnen ALLE. Så JOINER vi dette for at forespørge resultater efter ID og OrderDate og ADD SKIPP rækker filter for første forespørgsel, hvor datasættet har sin minimale størrelse hvad der kræves. Prøv denne kode.

    SELECT q2.*
    FROM
    (
        SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, OrderDate
        FROM      Orders
        WHERE     OrderDate >= '1980-01-01'
    )q1
    INNER JOIN 
    (
        SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
        FROM      Orders
        WHERE     OrderDate >= '1980-01-01'
    )q2
        ON q1.RowNum=q2.RowNum AND q1.OrderDate=q2.OrderDate AND q1.rownum BETWEEN 30000 AND 30020
    IF object_id('TestSelect','u') IS NOT NULL
        DROP TABLE TestSelect
    GO
    CREATE TABLE TestSelect
    (
        OrderDate   DATETIME2(2)
    )
    GO

    DECLARE @i bigint=1, @dt DATETIME2(2)='01/01/1700'
    WHILE @I<=2000000
    BEGIN

        IF @i%15 = 0
            SELECT @DT = DATEADD(DAY,1,@dt)

        INSERT INTO dbo.TestSelect( OrderDate )
        SELECT @dt

        SELECT @[email protected]+1
    END
    SELECT q2.*
    FROM
    (
        SELECT  ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum 
                ,OrderDate
        FROM TestSelect
        WHERE OrderDate >= '1700-01-01'
    )q1
    INNER JOIN
    (
        SELECT  ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum 
                ,*
        FROM TestSelect
        WHERE OrderDate >= '1700-01-01'
    )q2
        ON q1.RowNum=q2.RowNum 
        AND q1.OrderDate=q2.OrderDate 
        AND q1.RowNum BETWEEN 50000 AND 50010



  1. "O" i ORDBMS:PostgreSQL Inheritance

  2. Formater et tal som valuta i SQLite

  3. Hvad svarer til null-safe equality operatoren <=> i SQLite?

  4. Sådan opretter og bruger du MySQL-visninger