Sql千萬數據執行測試

如何得到SQL精確的執行時間

方法一:
declare @d datetime
set @d=getdate()
-->查詢語句
select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())
 
方法二:
SET STATISTICS TIME ON
SELECT * FROM SYSOBJECTS  -->你的查詢
SET STATISTICS TIME OFF

set statistics time on的理解:http://www.studyofnet.com/news/568.html

SqlServer索引及優化詳解 http://blog.csdn.net/china2010pan/article/details/6953498

(*)當擁有千萬級數據時,修改字段默認值會花費巨量的時間。修改字段類型不費時間,添加字段並設置默認值也不費時間。

(*)union和or執行結果一樣,但是,當搜索條件中搜索字段不同時,union效率比or要高;當搜索條件中搜索字段一樣時,效率一樣差。union默認會去除重複記錄,union all會顯示全部記錄

(*)搜索同一條記錄,搜索聚集索引耗時0ms,搜索無索引的字符串字段耗時420ms(如果此字符串爲純數字,耗時246ms),

(*)distinct會導致全表掃描,group by 會優先掃描索引

(*)sum函數注意溢出,需要使用sum(cast(id as bigint))轉換成8字節的bigint

(*)order by 根據索引排序很快,非索引字段效率低下;其中非聚集索引排序效率略微高於聚集索引

(*)建立複合索引後,查詢條件中一定要包含聚集索引或非聚集索引,否則無效。A:聚集 B:非聚集  A+B+C:複合,如果where只有C,則無效,AC或者BC或者ABC都有效

(*)聚集索引有大小排序,物理存儲順序和邏輯順序一致,增刪改操作系統消耗大,查詢快速。非聚集索引,不改變物理存儲,根據B樹(二叉樹)建立邏輯索引表,增刪改不營銷,查詢效率比聚集索引低。索引詳解:http://blog.csdn.net/donglynn/article/details/49618255

(*)誤區:聚集索引並不一定是唯一索引,由於SQL SERVER將主鍵默認定義爲聚集索引,事實上,索引是否唯一與是否聚集是不相關。但一般建立在唯一索引上,可以提高等值查詢效率

(*)可以在同一個字段上同時設置聚集索引和非聚集索引,例如id字段,但是對於查詢效率沒有任何的提升,當兩個索引同時設置在同一個字段,那麼耗時和只有聚集索引一樣

(*)建立索引的目的就是幫助查詢,如果查尋用不到則索引就沒有必要建立,另外如果數據表過大(5w以上)則有些字段(字符型長度超過(40))不適合作爲索引,另外如果表是經常需要更新的也不適合做索引 

環境:

分頁方案;

/*
分頁方案一(達到10萬頁,200萬條時,耗時300ms):
select top 20 id,username,password from A_User 
where id> 
(select max (id) from (select top 2000000 id from A_User order by id) as T )     
order by id 

分頁方案二(達到6.5萬頁,130萬條時,耗時300ms;提取指定的id、password、username反而耗時更長):
select top 20 * from A_User where id not in(select top 1300000 id from A_User )

分頁方案三(達到6.5萬頁,130萬條時,耗時300ms):
SELECT TOP 20 * FROM A_User a WHERE not exists 
(select id,password,username from (select top 1300000 id,password,username from A_User order by id) b where b.id=a.id ) 
order by id 

分頁方案四(達到4.25萬頁,85萬條時,耗時300ms):
SELECT TOP 20 * FROM 
(SELECT TOP 850000 id,password,username FROM A_User ORDER BY id DESC) f 
ORDER BY f.id ASC

分頁方案五(達到3.7萬頁,74萬條時,耗時300ms):
SELECT TOP 20 * 
FROM(SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM A_User) as A  
WHERE RowNumber > 20*(37000-1)

兩表聯動分頁:
//方案一,效率很低。

select top 20 tt.id from (select n.id,n.title,u.username from A_New n join A_User u on n.userid=u.id) tt where tt.id>
(select MAX(t.id) from 
(select top 20 n.id from A_New n join A_User u on n.userid=u.id) 
as t)

//方案二,效率高,和主表單獨查詢時間基本一樣

select t2.id,t2.username,r.* from
(select top 20 id,username,roleid from A_User where id> 
(select max (id) from (select top 1500000 id from A_User order by id) as T )     
order by id) as t2
left join A_Role r
on t2.roleid=r.id


兩表聯動耗時

1、(65207條記錄,耗時505ms。A_User中數據少,對應A_New中數據多):

select t1.* from
(select top 3 * from A_User) as t1
left join A_New n
on t1.id=n.userid

結果字段



2、(65207條記錄,耗時827ms。):

select t1.*,u.username from
(select top 65207 * from A_New) as t1
left join A_User u
on t1.userid=u.id


3、效率最低的方式(65207條記錄,耗時16252ms)

select top 65207 n.* from A_New n,A_User u where n.userid=u.id


三表聯動分頁:

方案一(首先提取出主表中當前頁的所有數據,然後使用left join去連接其他表):

select t2.id,t2.username from
(select top 20 id,username,roleid,classid from A_User where id>(select MAX(id) from (select top 2000000 id from A_User order by id) as t) order by id) as t2
left join A_Role r on t2.roleid=r.id
left join A_Class c on t2.classid=c.id
*/


1、select * from A_User where id in(9999999)

第一次查詢花費11秒,之後的查詢,無論數值變爲多少,花費時間爲0

2、搜索數值的速度遠遠快於搜索字符的速度

select top 200 id,addtime,roleid from A_User order by id desc//用時0

select top 200 id,username,[password],addtime,token,roleid from A_User order by id desc//用時46ms

select id,username,[password],addtime,token,roleid from A_User where id>10560000//用時43ms

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章