首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 時間查詢完全攻略:區間、點查、模糊比對與效能優化

     編輯:關於SqlServer

時間欄位 (DATETIME/DATETIME2) 查詢是資料庫開發高頻需求。本文系統整理區間查詢、精確點查、模糊比對 (年/月/日/時/分) 寫法,並解析 CONVERT 導致索引失效的效能陷阱與最佳替代方案。

範例環境

Table: dbo.tbBas_Subject
Column: CreateDate (DATETIME)
Sample: 2006-10-27 15:46:02.937

1. 區間查詢 (推薦:半開半閉區間)

-- 最佳寫法:利用索引 Seek
SELECT TOP 4 *
FROM dbo.tbBas_Subject
WHERE CreateDate >= '2006-10-27 15:46:02.937'
  AND CreateDate <  '2006-10-27 16:17:15.377';

避免 BETWEEN 於毫秒精度資料,邊界包含問題易致漏/重。

2. 精確點查 (罕見但有需求)

SELECT *
FROM dbo.tbBas_Subject
WHERE CreateDate = '2006-10-27 16:17:15.377';

需完全匹配至毫秒/百納秒,實務上較少用。

3. 模糊比對:常見但陷阱多

需求常見寫法 (❌ 索引失效)優化寫法 (✅ 索引可用)
某年某月WHERE CONVERT(VARCHAR(10), CreateDate, 120) LIKE '2006-10-%'WHERE CreateDate >= '2006-10-01' AND CreateDate < '2006-11-01'
某日某時WHERE CONVERT(VARCHAR(23), CreateDate, 120) LIKE '2006-10-27 15:%'WHERE CreateDate >= '2006-10-27 15:00:00' AND CreateDate < '2006-10-27 16:00:00'
某日某分WHERE CONVERT(VARCHAR(23), CreateDate, 120) LIKE '2006-10-27 %46:%'WHERE CreateDate >= '2006-10-27 15:46:00' AND CreateDate < '2006-10-27 15:47:00'

為何 CONVERT/LIKE 會殺死索引?

  • CONVERT 是 **非確定性標量函數**,導致查詢優化器無法使用索引 Seek,只能掃描全表 (Scan)
  • 資料量達百萬筆時,查詢時間從毫秒級飆升至秒級

最佳實務:日期維度表 / 計算欄位 / 範圍查詢

  1. 範圍查詢 (SARGable):如前表優化寫法,永遠優先
  2. 計算欄位 + 索引:ALTER TABLE ... ADD CreateDate_YM AS CONVERT(CHAR(7), CreateDate, 120) PERSISTED; CREATE INDEX ... ON CreateDate_YM;
  3. 日期維度表:數據倉庫場景下,Join 日期維表過濾,效能極佳
  4. DATETIME2(n):新專案優先使用,精度可控、儲存更小

快速備忘:常用日期邊界計算

-- 本月第一天 00:00:00
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
-- 本月最後一天 23:59:59.997
DATEADD(MILLISECOND, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0))

拒絕 CONVERT ... LIKE 反模式,擁抱範圍查詢與 SARGable 寫法,讓時間查詢跑得又快又穩。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved