sql >> Databáze >  >> RDS >> Sqlserver

Dotaz běží pomalu s výrazem data, ale rychle s řetězcovým literálem

Tohle by mohlo fungovat lépe:

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

Pokud neběžíte s příznakem trasování 4199, existuje chyba což ovlivňuje odhady mohutnosti. V době psaní

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

Vrátí

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

Chyba je v tom, že predikát v otázce používá při odvozování odhadů mohutnosti spíše první datum než druhé. Takže pro následující nastavení.

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)

Dotaz 1

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

Odhaduje se, že počet odpovídajících řádků bude 100 000. Toto je číslo, které odpovídá datu '1786-06-01' .

Ale oba následující dotazy

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)

Dejte tento plán

Vzhledem k mnohem přesnějším odhadům mohutnosti nyní plán provádí pouze hledání jednoho indexu namísto úplného skenování.



  1. Nemůžete použít dotaz LIKE v JDBC PreparedStatement?

  2. existuje způsob, jak se vyhnout volání nextval(), pokud vložení selže v PostgreSQL?

  3. problém s návrhem databáze při přidávání nových sloupců do tabulky z aplikace

  4. Předat ID tenanta přes připojení k serveru SQL