sql >> Database >  >> RDS >> Sqlserver

Snelste manier voor deze zoekopdracht (wat is de beste strategie) gegeven een datumbereik

Bijwerken:

Zie dit artikel in mijn blog voor een efficiënte indexeringsstrategie voor uw zoekopdracht met behulp van berekende kolommen:

Het belangrijkste idee is dat we gewoon de afgeronde length . berekenen en startDate voor u bereiken en zoek ze vervolgens met behulp van gelijkheidsvoorwaarden (die goed zijn voor B-Tree indexen)

In MySQL en in SQL Server 2008 je zou SPATIAL . kunnen gebruiken indexen (R-Tree ).

Ze zijn vooral goed voor de voorwaarden zoals "selecteer alle records met een bepaald punt binnen het bereik van de record", wat precies uw geval is.

Je slaat de start_date . op en end_date als het begin en het einde van een LineString (ze converteren naar UNIX tijdstempels van een andere numerieke waarde), indexeer ze met een SPATIAL indexeer en zoek naar al dergelijke LineString s waarvan het minimale begrenzingsvak (MBR ) bevat de datumwaarde in kwestie, met behulp van MBRContains .

Zie dit bericht in mijn blog over hoe je dit kunt doen in MySQL :

en een kort prestatieoverzicht voor SQL Server :

Dezelfde oplossing kan worden toegepast voor het zoeken naar een bepaald IP tegen netwerkbereiken die zijn opgeslagen in de database.

Deze taak, samen met uw vraag, is een ander vaak gebruikt voorbeeld van een dergelijke voorwaarde.

Effen B-Tree indexen zijn niet goed als de bereiken elkaar kunnen overlappen.

Als ze dat niet kunnen (en je weet het), kun je de briljante oplossing gebruiken die wordt voorgesteld door @AlexKuznetsov

Houd er ook rekening mee dat deze queryprestaties volledig afhankelijk zijn van uw gegevensdistributie.

Als u veel records heeft in B en enkele records in A , je zou gewoon een index kunnen bouwen op B.dates en laat de TS/CIS op A ga.

Deze zoekopdracht leest altijd alle rijen van A en zal Index Seek . gebruiken op B.dates in een geneste lus.

Als uw gegevens andersom worden verspreid, i. e. je hebt veel rijen in A maar weinig in B , en de reeksen zijn over het algemeen kort, dan zou je je tabellen een beetje kunnen herontwerpen:

A

start_date interval_length

, maak een samengestelde index op A (interval_length, start_date)

en gebruik deze vraag:

SELECT  *
FROM    (
        SELECT  DISTINCT interval_length
        FROM    a
        ) ai
CROSS JOIN
        b
JOIN    a
ON      a.interval_length = ai.interval_length
        AND a.start_date BETWEEN b.date - ai.interval_length AND b.date


  1. Toestaan ​​dat een met een wachtwoord beveiligde pagina op sociale media wordt gedeeld?

  2. SQL 'LIKE'-syntaxis

  3. Ontbrekende sequenties in HSQL voor testen

  4. Hoe de resultaten van een procedure daarbuiten in Oracle weer te geven