如何得到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