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

Заявката работи бавно с израз за дата, но бързо с низов литерал

Това може да работи по-добре:

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

Освен ако не работите с включен флаг за проследяване 4199, има бъг което влияе върху оценките на кардиналността. Към момента на писане

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

Връщане

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

Грешката е, че предикатът във въпроса използва първата дата, а не втората, когато извлича оценките на кардиналността. И така за следната настройка.

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)

Заявка 1

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

Смята се, че броят на съвпадащите редове ще бъде 100 000. Това е числото, което съответства на датата '1786-06-01' .

Но и двете от следните заявки

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)

Дайте този план

Благодарение на много по-точните оценки на кардиналността планът сега прави само търсене с единичен индекс, а не пълно сканиране.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Преобразувайте датата във формат ГГГГММ

  2. Unicode SQL заявка W/ параметър вместо N префикс

  3. Динамична обобщена таблица с множество колони в sql сървър

  4. Драйверът не можа да установи защитена връзка със SQL Server чрез използване на криптиране на Secure Sockets Layer (SSL)

  5. Външен ключ към непървичен ключ