Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Najszybszy sposób na to zapytanie (Jaka jest najlepsza strategia) biorąc pod uwagę zakres dat

Aktualizacja:

Zobacz ten artykuł na moim blogu, aby zapoznać się z wydajną strategią indeksowania zapytania przy użyciu kolumn obliczanych:

Główną ideą jest to, że po prostu obliczamy zaokrągloną length i startDate dla ciebie zakresów, a następnie wyszukaj je używając warunków równości (które są dobre dla B-Tree indeksy)

W MySQL oraz w SQL Server 2008 możesz użyć SPATIAL indeksy (R-Tree ).

Są one szczególnie dobre w warunkach takich jak „wybierz wszystkie rekordy z danym punktem w zakresie rekordu”, co jest właśnie w Twoim przypadku.

Przechowujesz start_date i end_date jako początek i koniec LineString (konwertując je do UNIX znaczniki czasu innej wartości liczbowej), zaindeksuj je za pomocą SPATIAL indeksuj i szukaj wszystkich takich LineString s którego minimalne pole ograniczające (MBR ) zawiera kwestionowaną wartość daty, używając MBRContains .

Zobacz ten wpis na moim blogu, jak to zrobić w MySQL :

i krótki przegląd wydajności dla SQL Server :

To samo rozwiązanie można zastosować do wyszukiwania podanego IP z zakresami sieci przechowywanymi w bazie danych.

To zadanie, wraz z zapytaniem, jest kolejnym często używanym przykładem takiego warunku.

Zwykłe B-Tree indeksy nie są dobre, jeśli zakresy mogą się nakładać.

Jeśli nie mogą (a wiesz o tym), możesz skorzystać z genialnego rozwiązania zaproponowanego przez @AlexKuznetsov

Pamiętaj również, że wydajność tego zapytania całkowicie zależy od dystrybucji danych.

Jeśli masz dużo rekordów w B i kilka rekordów w A , możesz po prostu zbudować indeks na B.dates i niech TS/CIS na A idź.

To zapytanie zawsze odczyta wszystkie wiersze z A i użyje Index Seek w B.dates w zagnieżdżonej pętli.

Jeśli Twoje dane są dystrybuowane w odwrotny sposób, to znaczy. mi. masz dużo wierszy w A ale niewiele w B , a zakresy są zazwyczaj krótkie, możesz trochę przeprojektować swoje tabele:

A

start_date interval_length

, utwórz indeks złożony na A (interval_length, start_date)

i użyj tego zapytania:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. wyświetlanie wielu rekordów za pomocą zestawu wyników

  2. Nie można rozwiązać konfliktu sortowania

  3. TABLOCK vs TABLOCKX

  4. Wymień, które kolumny mają indeks pełnotekstowy w SQL Server 2005

  5. <> a NIE W