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

各大資料庫取前 N 筆資料與隨機抽樣 SQL 寫法對照表

     編輯:關於SqlServer

取前 N 筆資料 (Top-N Query)

資料庫標準語法備註
OracleSELECT * FROM table_name WHERE ROWNUM <= NOracle 12c+ 可用 FETCH FIRST N ROWS ONLY
DB2SELECT * FROM table_name FETCH FIRST N ROWS ONLY或使用 ROW_NUMBER() OVER() 視窗函數
SQL ServerSELECT TOP N * FROM table_name搭配 ORDER BY 確保確定性
MySQL / MariaDBSELECT * FROM table_name LIMIT NLIMIT offset, N 支援分頁
PostgreSQLSELECT * FROM table_name LIMIT N標準 SQL:2008 FETCH FIRST N ROWS ONLY 亦支援
SQLiteSELECT * FROM table_name LIMIT N
ANSI SQL:2008 標準SELECT * FROM table_name FETCH FIRST N ROWS ONLYOracle 12c、PostgreSQL、DB2、SQL Server 2012+ 支援

帶排序的 Top-N (確定性結果)

-- Oracle 12c+
SELECT * FROM table_name ORDER BY col1 DESC FETCH FIRST 10 ROWS ONLY;

-- SQL Server
SELECT TOP 10 * FROM table_name ORDER BY col1 DESC;

-- MySQL / PostgreSQL
SELECT * FROM table_name ORDER BY col1 DESC LIMIT 10;

-- DB2
SELECT * FROM table_name ORDER BY col1 DESC FETCH FIRST 10 ROWS ONLY;

分頁查詢 (Pagination)

資料庫語法 (第 2 頁,每頁 10 筆)
Oracle 12c+SELECT * FROM table_name ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
SQL Server 2012+SELECT * FROM table_name ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
PostgreSQL / MySQLSELECT * FROM table_name ORDER BY id LIMIT 10 OFFSET 10
Oracle 11g 及之前需使用巢狀 ROWNUM 或視窗函數 ROW_NUMBER()

隨機抽樣前 N 筆

資料庫語法效能備註
DB2SELECT * FROM mytable ORDER BY RAND() DESC FETCH FIRST 10 ROWS ONLY全表掃描 + 排序,大表極慢
SQL ServerSELECT TOP 10 * FROM userinf ORDER BY NEWID()NEWID() 產生 GUID 排序,大表效能差
MySQLSELECT * FROM tablename ORDER BY RAND() LIMIT 10臨時表 + 檔案排序,大表不可用
PostgreSQLSELECT * FROM tablename ORDER BY RANDOM() LIMIT 10同全表排序
OracleSELECT * FROM (SELECT * FROM table_name ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 10子查詢排序

大表高效隨機抽樣替代方案

伯努利採樣 / 系統採樣 (TABLESAMPLE)

-- SQL Server (系統採樣,頁面層級)
SELECT * FROM large_table TABLESAMPLE (10 PERCENT) REPEATABLE (42);

-- PostgreSQL (伯努利/系統採樣)
SELECT * FROM large_table TABLESAMPLE BERNOULLI (10) REPEATABLE (42);
SELECT * FROM large_table TABLESAMPLE SYSTEM (10) REPEATABLE (42);

優點:極快,不掃描全表。缺點:非精確 N 筆、可能有叢集偏差、REPEATABLE 種子確保可重現。

主鍵範圍隨機抽樣 (適用連續整數主鍵)

-- 取得主鍵範圍
DECLARE @min_id INT, @max_id INT, @sample_size INT = 10;
SELECT @min_id = MIN(id), @max_id = MAX(id) FROM large_table;

-- 產生隨機 ID 清單 (應用層或 T-SQL 迴圈)
-- 然後查詢
SELECT * FROM large_table WHERE id IN (/* 隨機 ID 清單 */);

預先計算隨機排序欄位

-- 表中新增欄位
ALTER TABLE large_table ADD rand_order INT;
UPDATE large_table SET rand_order = CHECKSUM(NEWID());  -- 或 RAND()

-- 建立索引
CREATE INDEX IX_rand_order ON large_table(rand_order);

-- 快速取樣
SELECT TOP 10 * FROM large_table ORDER BY rand_order;

適合固定抽樣比例、定期重算的場景。

效能比較總結

方法適用資料量隨機品質查詢速度實作複雜度
ORDER BY RAND/NEWID< 10 萬筆高慢 (全表排序)低
TABLESAMPLE任意 (百萬+)中 (頁面/列層級)極快低
主鍵範圍 + IN任意 (需連續 PK)高快 (索引搜尋)中
預計算 rand_order任意高極快 (索引排序)中 (需維護)

最佳實踐建議

  1. 生產環境大表嚴禁 ORDER BY RAND(),會導致 CPU 飆升、磁碟 I/O 暴增、查詢超時
  2. 優先使用 TABLESAMPLE (SQL Server/PostgreSQL) 或主鍵範圍法
  3. 需精確 N 筆且高隨機性時,應用層產生隨機 ID 清單再 IN 查詢
  4. 分頁查詢大偏移量 (OFFSET 1000000) 同樣效能差,改用「游標分頁」:WHERE id > @last_id ORDER BY id LIMIT 10
  5. 跨資料庫開發時,封裝成通用 Repository 介面,內部針對各 DB 實作最佳語法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved