国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

從SQLSERVER/MYSQL數據庫中隨機取一條或者N條記錄

2024-07-24 12:59:17
字體:
來源:轉載
供稿:網友
從SQLSERVER/MySQL數據庫中隨機取一條或者N條記錄從SQLSERVER/MYSQL數據庫中隨機取一條或者N條記錄

很多人都知道使用rand()函數但是怎麼使用可能不是每個人都知道

建立測試表

USE [sss]GOCREATE TABLE RANDTEST(ID INT DEFAULT RAND()*100,NAME NVARCHAR(200) DEFAULT 'nihao')GOCREATE INDEX IX_RANDTEST_ID ON RANDTEST(ID)GOINSERT INTO RANDTEST DEFAULT VALUESGO 2000SELECT * FROM RANDTEST

第一種寫法:大家會想到ORDER BYNEWID()

SET STATISTICS TIME ON SET STATISTICS IO ONSELECT TOP 50 [id]  FROM    [dbo].[RANDTEST]GROUP BY IDORDER BY NEWID() SET STATISTICS TIME OFFSET STATISTICS IO OFF

這種寫法使用到索引掃描,而且每次select出來的結果都是一樣的,都是50條記錄

第二種寫法

SET STATISTICS TIME ON SET STATISTICS IO ONSELECT TOP 50 [t1].[ID] FROM [dbo].[RANDTEST] t1 JOIN (SELECT RAND()*100 AS nid) t2 ON [t1].[ID]>[t2].[nid]GROUP BY [t1].[ID]SET STATISTICS TIME OFFSET STATISTICS IO OFF

跟t2這個表做比較,而且每次能夠達到隨機取一條或者N條記錄的效果

每次select出來的行數都是不一樣的

比較一下IO和時間

當兩種寫法select出來的結果條數都是50條的時候,時間和IO都是一樣的,如果第二種寫法select出來的記錄條數不是50條

那么IO肯定比第一種寫法要少

--第一種寫法  select出來50條記錄SQL Server 執行時間:   CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。(50 行受影響)表 'RANDTEST'。掃描計數 1,邏輯讀取 5 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。SQL Server 執行時間:   CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。--------------------------------------------------------------------------------第二種寫法  select出來37條記錄SQL Server 執行時間:   CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。(27 行受影響)表 'RANDTEST'。掃描計數 1,邏輯讀取 4 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。SQL Server 執行時間:   CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。

總結

如果第一種寫法寫成下面的樣子,那么每次select出來的結果都是一樣的,而且不會進行排序,在執行計劃里面你看不到排序這個運算符

因為非聚集索引是排好序的,掃描非聚集索引只會得到排好序的結果

SELECT TOP 50 [id]  FROM    [dbo].[RANDTEST]GROUP BY IDORDER BY RAND()*100

綜上,想從SQLSERVER數據庫中隨機取一條或者N條記錄時,最好把RAND()生成隨機數放在JOIN子查詢中以提高效率。

SELECT TOP n [id]  FROM    tableGROUP BY IDORDER BY NEWID()

改造成下面這個:

SELECT TOP n   [t1].[ID]  FROM table  t1 JOIN (SELECT RAND()*100 AS nid) t2 ON [t1].[ID]>[t2].[nid]GROUP BY [t1].[ID]

就可以享受在SQL中直接取得隨機數了,不用再在程序中構造一串隨機數去檢索了。

MYSQL也是同樣的原理

CREATE TABLE `t_innodb_random` (`id` INT(10) UNSIGNED NOT NULL,`user` VARCHAR(64) NOT NULL DEFAULT '',KEY `idx_id` (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('1','lily');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('3','tom');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('5','fancy');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('6','cici');INSERT INTO `t_innodb_random` (`id`, `user`) VALUES('9','syan');SELECT * FROM t_innodb_random;SELECT id FROM t_innodb_random ORDER BY RAND() LIMIT 5;-- 改造成下面這個:SELECT id FROM t_innodb_random t1 JOIN (SELECT RAND()*10 AS nid) t2 ON t1.id > t2.nid LIMIT 5;

---------------------------------------------------------------------------------------------

如有不對的地方,歡迎大家拍磚o(∩_∩)o


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 京山县| 神木县| 鹤峰县| 丰镇市| 饶阳县| 道孚县| 南昌市| 舒城县| 广汉市| 芦溪县| 保山市| 元氏县| 汾西县| 出国| 九龙坡区| 黄山市| 宜兰市| 锦屏县| 康保县| 华容县| 清水河县| 利津县| 井研县| 泽州县| 庆阳市| 濮阳县| 华坪县| 镇雄县| 安塞县| 神池县| 彩票| 道孚县| 永泰县| 西乌珠穆沁旗| 东丽区| 高台县| 全椒县| 莱州市| 普安县| 开江县| 施甸县|