當(dāng)你需要查詢數(shù)據(jù)的時(shí)候你往往需要在WHERE條件中多加一個(gè)判斷條件IS NOT NULL,這樣的一個(gè)條件不僅僅增加了額外的開銷,而且對(duì)查詢的性能產(chǎn)生很大的影響,有可能就因?yàn)槎嗔诉@個(gè)查詢條件導(dǎo)致你的查詢變的非常的慢;還有一個(gè)比較重要的問題就是允許為空的數(shù)據(jù)可能會(huì)導(dǎo)致你的查詢結(jié)果出現(xiàn)不準(zhǔn)確的問題,
----如果整形字段可以賦0,字符型可以賦值空(這里只是給建議)這里的空和NULL是不一樣的意思--增加整形字段可以這樣寫ALTER TABLE TABLE_NAME ADD COLUMN_NAME INT NOT NULL DEFAULT(0)--增加字符型字段可以這樣寫ALTER TABLE TABLE_NAME ADD COLUMN_NAME NVARCHAR(50) NOT NULL DEFAULT('')4,少用TEXT和IMAGE,二進(jìn)制字段的讀寫是比較慢的,而且,讀取的方法也不多,大部分情況下最好不用5,建立自增列時(shí)單獨(dú)再給自增列添加唯一約束
如果要保證ID是唯一的,單單只設(shè)置自增值不行,需要給字段設(shè)置主鍵或者唯一約束
6,建立索引可以根據(jù)功能和性能的需求進(jìn)行初步的索引設(shè)計(jì),這里需要根據(jù)預(yù)計(jì)的數(shù)據(jù)量和查詢來設(shè)計(jì)索引
A、根據(jù)數(shù)據(jù)量決定哪些表需要增加索引,數(shù)據(jù)量小的可以只有主鍵
B、根據(jù)使用頻率決定哪些字段需要建立索引,選擇經(jīng)常作為連接條件、篩選條件、聚合查詢、排序的字段作為索引的候選字段
C、把經(jīng)常一起出現(xiàn)的字段組合在一起,組成組合索引,組合索引的字段順序與主鍵一樣,也需要把最常用的字段放在前面,把重復(fù)率低的字段放在前面
D、一個(gè)表不要加太多索引,因?yàn)樗饕绊懖迦牒透碌乃俣?/p>
建立索引后,并不是每個(gè)查詢都會(huì)使用索引,在使用索引的情況下,索引的使用效率也會(huì)有很大的差別。只要我們?cè)诓樵冋Z句中沒有強(qiáng)制指定索引,索引的選擇和使用方法是SQLSERVER的優(yōu)化器自動(dòng)作的選擇,而它選擇的根據(jù)是查詢語句的條件以及相關(guān)表的統(tǒng)計(jì)信息,這就要求我們?cè)趯慡QL語句的時(shí)候盡量使得優(yōu)化器可以使用索引。
二、編碼1,查詢條件不要使用計(jì)算列例:查詢條件為 year(createdate)=2014
優(yōu)化:createdate>='20140101' and createdate<='20141231'
原因:使用計(jì)算列查詢,是通過[索引掃描]方式查找
不使用計(jì)算列,走的是索引查找
絕大部分情況下索引查找的查詢性能要高于索引掃描,特別是查詢的數(shù)據(jù)庫不是非常大的情況下,索引查找的消耗時(shí)間要遠(yuǎn)遠(yuǎn)少于索引掃描的時(shí)間,相關(guān)知識(shí)[聚集、非聚集、堆的索引]
2,分組統(tǒng)計(jì)時(shí)避免使用count(*)
if OBJECT_ID('Customer') is not null drop table [Customer]gocreate table [Customer] (CId int not null,Name nvarchar(20));goif OBJECT_ID('Order') is not null drop table [Order]gocreate table [Order] (OId int not null, CusId int);goinsert into Customer values(1,'小米'),(2,'大米'),(3,'mini')insert into [Order] values(1,1),(2,2),(3,NULL),(4,1)
--例如:需要統(tǒng)計(jì)每個(gè)顧客的訂單量--使用count(*)select CID,count(*) from Customer left join [order] on Customer.CId=[order].CusId group by CId
實(shí)際情況CusId=3是沒有訂單的,數(shù)量應(yīng)該是0,但是結(jié)果是1,count()里面的字段是左連接右邊的表字段,如果你用的是主表字段結(jié)果頁是錯(cuò)誤的。
--正確的方法是使用count(CusId)select CID,count(CusId) from Customer left join [order] on Customer.CId=[order].CusId group by CId
3,子查詢的表加上表別名4,查詢時(shí)使用*
查詢時(shí)一定不能使用”*”來代替字段來進(jìn)行查詢,無論你查詢的字段有多少個(gè),就算字段太多無法走索引也避免了解析”*”帶來的額外消耗。
查詢字段值列出想要的字段,避免出現(xiàn)多余的字段,字段越多查詢開銷越大而且可能會(huì)因?yàn)槎嗔谐隽四硞€(gè)字段而引起查詢不走索引。
5,使用存儲(chǔ)過程的好處默認(rèn)情況下,存儲(chǔ)過程將返回過程中每個(gè)語句影響的行數(shù)。如果不需要在應(yīng)用程序中使用該信息(大多數(shù)應(yīng)用程序并不需要),請(qǐng)?jiān)诖鎯?chǔ)過程中使用 SET NOCOUNT ON 語句以終止該行為。根據(jù)存儲(chǔ)過程中包含的影響行的語句的數(shù)量,這將刪除客戶端和服務(wù)器之間的一個(gè)或多個(gè)往返過程。盡管這不是大問題,但它可以為高流量應(yīng)用程序的性能產(chǎn)生負(fù)面影響。6,判斷一條查詢是否有值
IF NOT EXISTS/IF EXISTS 優(yōu)于 COUNT(*)
7, 理解TRUNCATE和DELETE的區(qū)別TRUNCATE操作沒有記錄刪除日志操作
主要的原因是因?yàn)門RUNCATE操作不會(huì)激活觸發(fā)器,因?yàn)門RUNCATE操作不會(huì)記錄各行的日志刪除操作,所以當(dāng)你需要?jiǎng)h除一張表的數(shù)據(jù)時(shí)你需要考慮是否應(yīng)該如有記錄日志刪除操作,而不是根據(jù)個(gè)人的習(xí)慣來操作。
8,事務(wù)的理解XACT_ABORT
---查詢是否有打開事務(wù)SELECT XACT_STATE()DBCC OPENTRAN未查詢到有打開事務(wù)當(dāng) SET XACT_ABORT 為 ON 時(shí),如果執(zhí)行 Transact-SQL 語句產(chǎn)生運(yùn)行時(shí)錯(cuò)誤,則整個(gè)事務(wù)將終止并回滾。當(dāng) SET XACT_ABORT 為 OFF 時(shí),有時(shí)只回滾產(chǎn)生錯(cuò)誤的 Transact-SQL 語句,而事務(wù)將繼續(xù)進(jìn)行處理。如果錯(cuò)誤很嚴(yán)重,那么即使 SET XACT_ABORT 為 OFF,也可能回滾整個(gè)事務(wù)。OFF 是默認(rèn)設(shè)置。編譯錯(cuò)誤(如語法錯(cuò)誤)不受 SET XACT_ABORT 的影響。9,條件字段的先后順序
對(duì)于經(jīng)常用作查詢的字段放在第一個(gè)位置,其它的字段根據(jù)表的實(shí)際字段順序排列,這樣往往你的查詢語句走索引的概率會(huì)更大。
10,避免使用長字節(jié)字段排序order by Id 優(yōu)于 order by CreateTime
新聞熱點(diǎn)
疑難解答
圖片精選