Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara tercepat untuk kueri ini (Strategi apa yang terbaik) dengan rentang tanggal

Pembaruan:

Lihat artikel ini di blog saya untuk strategi pengindeksan yang efisien untuk kueri Anda menggunakan kolom yang dihitung:

Ide utamanya adalah kita hanya menghitung length bulat dan startDate untuk rentang Anda dan kemudian mencarinya menggunakan kondisi kesetaraan (yang bagus untuk B-Tree indeks)

Di MySQL dan di SQL Server 2008 anda bisa menggunakan SPATIAL indeks (R-Tree ).

Mereka sangat baik untuk kondisi seperti "pilih semua catatan dengan titik tertentu di dalam rentang catatan", yang merupakan kasus Anda.

Anda menyimpan start_date dan end_date sebagai awal dan akhir dari LineString (mengubahnya menjadi UNIX stempel waktu dari nilai numerik lain), indeks dengan SPATIAL indeks dan cari semua LineString s yang kotak pembatas minimumnya (MBR ) berisi nilai tanggal yang dimaksud, menggunakan MBRContains .

Lihat entri ini di blog saya tentang cara melakukannya di MySQL :

dan ikhtisar kinerja singkat untuk SQL Server :

Solusi yang sama dapat diterapkan untuk mencari IP yang diberikan terhadap rentang jaringan yang disimpan dalam database.

Tugas ini, bersama dengan kueri Anda, adalah contoh lain yang sering digunakan untuk kondisi seperti itu.

B-Tree biasa indeks tidak bagus jika rentangnya bisa tumpang tindih.

Jika mereka tidak bisa (dan Anda tahu itu), Anda dapat menggunakan solusi brilian yang diusulkan oleh @AlexKuznetsov

Perhatikan juga bahwa kinerja kueri ini sepenuhnya bergantung pada distribusi data Anda.

Jika Anda memiliki banyak catatan di B dan beberapa catatan di A , Anda bisa membuat indeks pada B.dates dan biarkan TS/CIS di A pergi.

Kueri ini akan selalu membaca semua baris dari A dan akan menggunakan Index Seek pada B.dates dalam loop bersarang.

Jika data Anda didistribusikan sebaliknya, i. e. Anda memiliki banyak baris di A tapi sedikit di B , dan rentangnya umumnya pendek, maka Anda dapat mendesain ulang tabel Anda sedikit:

A

start_date interval_length

, buat indeks komposit pada A (interval_length, start_date)

dan gunakan kueri ini:

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. Cara mendapatkan substring di SQLsever dengan menemukan kemunculan karakter ke-n

  2. Cara Memperbaiki:JSON_VALUE Mengembalikan NULL dengan Long String (SQL Server)

  3. Apa cara terbaik untuk mengenkripsi SSN di SQL Server 2008?

  4. Meniru/Mensimulasikan SQL Azure Secara Lokal?

  5. Bagaimana Saya Menyalin Kumpulan Data, dan Mengubah Referensi FK untuk Menunjuk ke Semua Salinan?