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

Zapytanie działa wolno z wyrażeniem daty, ale szybko z literałem ciągu

To mogłoby działać lepiej:

Where FK.DT = cast(getdate() + 1 - datepart(day, getdate()) as date)

Jeśli nie korzystasz z flagi śledzenia 4199, istnieje błąd co wpływa na szacunki kardynalności. W momencie pisania

SELECT DATEADD(m, DATEDIFF(m, getdate(), 0), 0), 
       DATEADD(m, DATEDIFF(m, 0, getdate()), 0)

Zwroty

+-------------------------+-------------------------+
| 1786-06-01 00:00:00.000 | 2013-08-01 00:00:00.000 |
+-------------------------+-------------------------+

Błąd polega na tym, że orzeczenie w pytaniu używa pierwszej daty, a nie drugiej podczas wyprowadzania szacunków liczności. Tak więc dla następującej konfiguracji.

CREATE TABLE FK
(
ID INT IDENTITY PRIMARY KEY,
DT DATE,
Filler CHAR(1000) NULL,
UNIQUE (DT,ID)
)

INSERT INTO FK (DT)
SELECT TOP (1000000) DATEADD(m, DATEDIFF(m, getdate(), 0), 0)
FROM master..spt_values o1, master..spt_values o2
UNION ALL
SELECT               DATEADD(m, DATEDIFF(m, 0, getdate()), 0)

Zapytanie 1

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  

Szacuje, że liczba pasujących wierszy wyniesie 100 000. To jest liczba pasująca do daty '1786-06-01' .

Ale oba poniższe zapytania

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(GETDATE() + 1 - DATEPART(DAY, GETDATE()) AS DATE)

SELECT COUNT(Filler)
FROM FK
WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  
OPTION (QUERYTRACEON 4199)

Daj ten plan

Ze względu na znacznie dokładniejsze oszacowania kardynalności, plan teraz wykonuje tylko pojedyncze wyszukiwanie indeksu, a nie pełne skanowanie.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. T-SQL:dzielenie i agregowanie wartości oddzielonych przecinkami

  2. SQL Server 2000:Pomysły na wykonanie podkwerendy agregacji konkatenacji

  3. Chcę pokazać wszystkie tabele, które mają określoną nazwę kolumny

  4. Problemy z T-SQL TRY CATCH?

  5. Jak utworzyć użytkownika w SQL-Server, który ma dostęp tylko do jednej tabeli i może wstawiać tylko wiersze?