Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Най-бързият начин за тази заявка (коя е най-добрата стратегия) при даден период от време

Актуализация:

Вижте тази статия в моя блог за ефективна стратегия за индексиране за вашата заявка с помощта на изчислени колони:

Основната идея е, че просто изчисляваме закръглена length и startDate за вашите диапазони и след това ги потърсете, като използвате условия за равенство (които са добри за B-Tree индекси)

В MySQL и в SQL Server 2008 можете да използвате SPATIAL индекси (R-Tree ).

Те са особено добри за условия като „избиране на всички записи с дадена точка в диапазона на записа“, което е точно вашият случай.

Вие съхранявате start_date и end_date като начало и край на LineString (преобразувайки ги в UNIX времеви отпечатъци с друга числова стойност), индексирайте ги с SPATIAL индексирайте и потърсете всички такива LineString s чиято минимална ограничителна кутия (MBR ) съдържа въпросната стойност на датата, използвайки MBRContains .

Вижте този запис в моя блог за това как да направите това в MySQL :

и кратък преглед на производителността за SQL Server :

Същото решение може да се приложи за търсене на даден IP срещу мрежови диапазони, съхранени в базата данни.

Тази задача, заедно с вашата заявка, е друг често използван пример за такова условие.

Обикновено B-Tree индексите не са добри, ако диапазоните могат да се припокриват.

Ако не могат (и вие го знаете), можете да използвате брилянтното решение, предложено от @AlexKuznetsov

Също така имайте предвид, че ефективността на тази заявка изцяло зависи от вашето разпространение на данни.

Ако имате много записи в B и няколко записа в A , можете просто да създадете индекс върху B.dates и нека TS/CIS на A върви.

Тази заявка винаги ще чете всички редове от A и ще използва Index Seek на B.dates във вложен цикъл.

Ако вашите данни се разпространяват обратно, т.е. д. имате много редове в A но малко в B , а диапазоните обикновено са кратки, тогава можете да преработите малко таблиците си:

A

start_date interval_length

, създайте съставен индекс на A (interval_length, start_date)

и използвайте тази заявка:

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. Избройте акаунтите, свързани с пощенски профил на база данни в SQL Server

  2. Активни сесии и състояние на SQL Server

  3. Разделянето води до текуща заявка за общи суми

  4. Инсталирайте SQL Server 2019 на Mac

  5. datetime срещу smalldatetime в SQL Server:Каква е разликата?