sql >> Databasteknik >  >> RDS >> Sqlserver

effektivt sätt att implementera personsökning

Försöker ge dig ett kort svar på dina tvivel om du kör skip(n).take(m) metoder på linq (med SQL 2005 / 2008 som databasserver) kommer din fråga att använda Select ROW_NUMBER() Over ... sats, med är på något sätt direkt personsökning i SQL-motorn.

För att ge dig ett exempel, jag har en db-tabell som heter mtcity och jag skrev följande fråga (fungerar lika bra med linq till entiteter):

using (DataClasses1DataContext c = new DataClasses1DataContext())
{
    var query = (from MtCity2 c1 in c.MtCity2s
                select c1).Skip(3).Take(3);
    //Doing something with the query.
}

Den resulterande frågan blir:

SELECT [t1].[CodCity], 
    [t1].[CodCountry], 
    [t1].[CodRegion], 
    [t1].[Name],  
    [t1].[Code]
FROM (
    SELECT ROW_NUMBER() OVER (
        ORDER BY [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]) AS [ROW_NUMBER], 
        [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]
    FROM [dbo].[MtCity] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]

Vilket är en dataåtkomst i fönster (ganska coolt, förresten kommer att returnera data från början och kommer åt tabellen så länge som villkoren är uppfyllda). Detta kommer att vara mycket likt:

With CityEntities As 
(
    Select ROW_NUMBER() Over (Order By CodCity) As Row,
        CodCity //here is only accessed by the Index as CodCity is the primary
    From dbo.mtcity
)
Select [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc

Med undantaget att denna andra fråga kommer att exekveras snabbare än linq-resultatet eftersom den kommer att använda exklusivt indexet för att skapa dataåtkomstfönstret; Det betyder att om du behöver lite filtrering, bör (eller måste finnas) filtreringen i Entity-listan (där raden skapas) och vissa index bör också skapas för att behålla det goda resultatet.

Nu, vad är bättre?

Om du har ett ganska stabilt arbetsflöde i din logik, kommer det att bli komplicerat att implementera rätt SQL-sätt. I så fall kommer LINQ att vara lösningen.

Om du kan sänka den delen av logiken direkt till SQL (i en lagrad procedur), blir det ännu bättre eftersom du kan implementera den andra frågan jag visade dig (med hjälp av index) och tillåta SQL att generera och lagra exekveringsplanen för fråga (förbättrar prestanda).



  1. Hur man använder SQL Server HierarchyID genom enkla exempel

  2. Postgresql json-gilla-fråga

  3. Hur man byter namn på en tabellkolumn i Oracle 10g

  4. Skillnad mellan text och varchar (tecken varierar)