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

SQL NOW() 函數完全指南:獲取當前日期時間、跨資料庫差異、時區處理與效能考量

     編輯:SQL 基礎

SQL NOW() 函數完全指南:獲取當前日期時間、跨資料庫差異、時區處理與效能考量

NOW() 返回資料庫伺服器當前的日期與時間(YYYY-MM-DD HH:MM:SS),是時間戳記錄、審計日誌、排程判斷、相對時間查詢的基石。但各資料庫函數名、時區行為、精度、效能特性差異顯著,本文系統梳理主流資料庫的 NOW/對應函數,並給出時區最佳實踐與效能建議。

主流資料庫 NOW() 對應表

資料庫 函數 返回類型 精度 時區行為
MySQL / MariaDBNOW() / SYSDATE()DATETIME秒 (微秒可用 NOW(6))會話時區 (time_zone 系統變數)
PostgreSQLNOW() / CURRENT_TIMESTAMP / CLOCK_TIMESTAMP()TIMESTAMP WITH TIME ZONE微秒會話時區 (TimeZone 參數)
SQL ServerGETDATE() / SYSDATETIME() / SYSUTCDATETIME()DATETIME / DATETIME2 / DATETIME23.33ms / 100ns / 100ns伺服器作業系統時區 (無會話時區概念)
OracleSYSDATE / SYSTIMESTAMP / CURRENT_TIMESTAMPDATE / TIMESTAMP WITH TIME ZONE / TIMESTAMP WITH TIME ZONE秒 / 微秒 / 微秒伺服器作業系統時區 / 會話時區
SQLiteCURRENT_TIMESTAMP / datetime('now')TEXT (ISO8601)秒UTC (預設)

關鍵差異深度解析

MySQL:NOW() vs SYSDATE()

  • NOW():語句執行開始時刻固定,同一語句多次呼叫返回相同值。受 SET time_zone 影響。
  • SYSDATE():實時 獲取,同一語句多次呼叫可能不同。不受 SET time_zone 影響,始終返回系統時區時間。複製/備份場景慎用(非確定性函數)。

PostgreSQL:三大時間函數

  • NOW() / CURRENT_TIMESTAMP:事務開始時刻固定,同一事務多次呼叫相同。
  • CLOCK_TIMESTAMP():實時時鐘,每次呼叫不同。
  • STATEMENT_TIMESTAMP():當前語句開始時刻。

SQL Server:精度與時區

  • GETDATE():DATETIME,精度 ~3.33ms,舊版相容。
  • SYSDATETIME():DATETIME2(7),精度 100ns,推薦新專案。
  • SYSUTCDATETIME():UTC 時間,避免時區轉換 Bug,跨地域系統首選。
  • 無會話時區:所有時間函數基於作業系統時區,應用層統一用 UTC 存儲、顯示層轉換。

Oracle:DATE vs TIMESTAMP

  • SYSDATE:DATE 類型,精度秒,無時區資訊。
  • SYSTIMESTAMP:TIMESTAMP WITH TIME ZONE,精度微秒,含資料庫時區位移。
  • CURRENT_TIMESTAMP:會話時區 (ALTER SESSION SET TIME_ZONE)。

演示資料庫:Websites 表

+----+--------------+---------------------------+-------+---------+
| id | name         | url                       | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1  | Google       | https://www.google.cm/    | 1     | USA     |
| 2  | 淘寶         | https://www.taobao.com/   | 13    | CN      |
| 3  | 菜鳥教程     | https://www.runoob.com/    | 4689  | CN      |
| 4  | 微博         | https://weibo.com/         | 20    | CN      |
| 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
| 7  | stackoverflow| https://stackoverflow.com/ | 0     | IND     |
+----+--------------+---------------------------+-------+---------+

範例:查詢網站名、URL 與當前日期時間

SELECT name, url, NOW() AS current_datetime
FROM Websites;

SQL NOW 範例輸出

時區最佳實踐(跨資料庫通用)

  1. 資料庫層統一 UTC:
    • MySQL:SET GLOBAL time_zone = '+00:00'; 或 my.cnf: default-time-zone='+00:00'
    • PostgreSQL:postgresql.conf: timezone = 'UTC'
    • SQL Server:作業系統設為 UTC,或應用層統一 AT TIME ZONE 'UTC'
    • Oracle:ALTER DATABASE SET TIME_ZONE = '+00:00'; (需重啟)
  2. 應用層連線指定 UTC:
    • MySQL/PostgreSQL:連線字串 timezone=UTC / options=-c TimeZone=UTC
    • JDBC:connectionTimeZone=SERVER + 伺服器 UTC
  3. 存儲用 TIMESTAMP WITH TIME ZONE (PG/Oracle) 或 DATETIME (MySQL UTC),避免無時區類型。
  4. 顯示層按用戶時區格式化:前端 Intl.DateTimeFormat、後端 DateTimeZone 轉換。

效能考量

  • NOW() 為非確定性函數:查詢緩存不緩存、複製時需行級格式、不可用於分區裁剪。
  • 大量插入時批次傳入應用層生成時間戳,避免逐行呼叫 NOW() 開銷。
  • 索引範圍查詢:WHERE created_at >= NOW() - INTERVAL 1 DAY 可用索引,但 NOW() 每次執行值不同,緩存失效。

相對時間查詢常用模式

-- MySQL
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
WHERE created_at BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()

-- PostgreSQL
WHERE created_at >= NOW() - INTERVAL '7 days'

-- SQL Server
WHERE created_at >= DATEADD(DAY, -7, GETDATE())

-- Oracle
WHERE created_at >= SYSDATE - 7

NOW() 看似簡單,實則牽涉時區、精度、複製、效能、確定性等深層機制。掌握各資料庫差異、統一 UTC 基線、應用層掌控時區轉換、避開非確定性陷阱,才能讓時間相關業務精準、可靠、可遷移。

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