成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

養(yǎng)成一個SQL好習慣帶來一筆大財富

數(shù)據(jù)庫 SQL Server
我們做軟件開發(fā)的,大部分人都離不開跟數(shù)據(jù)庫打交道,特別是erp開發(fā)的,跟數(shù)據(jù)庫打交道更是頻繁,存儲過程動不動就是上千行,如果數(shù)據(jù)量大,人員流動大,那么我么還能保證下一段時間系統(tǒng)還能流暢的運行嗎?那么還能保證下一個人能看懂我么的存儲過程嗎?

我們做軟件開發(fā)的,大部分人都離不開跟數(shù)據(jù)庫打交道,特別是erp開發(fā)的,跟數(shù)據(jù)庫打交道更是頻繁,存儲過程動不動就是上千行,如果數(shù)據(jù)量大,人員流動大,那么我么還能保證下一段時間系統(tǒng)還能流暢的運行嗎?那么還能保證下一個人能看懂我么的存儲過程嗎?那么我結(jié)合公司平時的培訓和平時個人工作經(jīng)驗和大家分享一下,希望對大家有幫助。

要知道sql語句,我想我們有必要知道sqlserver查詢分析器怎么執(zhí)行我么sql語句的,我么很多人會看執(zhí)行計劃,或者用profile來監(jiān)視和調(diào)優(yōu)查詢語句或者存儲過程慢的原因,但是如果我們知道查詢分析器的執(zhí)行邏輯順序,下手的時候就胸有成竹,那么下手是不是有把握點呢?

一:查詢的邏輯執(zhí)行順序

(1) FROM < left_table>

(2) ON < join_condition>

(3) < join_type> JOIN < right_table>

(4) WHERE < where_condition>

(5) GROUP BY < group_by_list>

(6) WITH {cube | rollup}

(7) HAVING < having_condition>

(8) SELECT (9) DISTINCT (11) < top_specification> < select_list>

(10) ORDER BY < order_by_list>

標準的SQL 的解析順序為:

(1).FROM 子句 組裝來自不同數(shù)據(jù)源的數(shù)據(jù)

(2).WHERE 子句 基于指定的條件對記錄進行篩選

(3).GROUP BY 子句 將數(shù)據(jù)劃分為多個分組

(4).使用聚合函數(shù)進行計算

(5).使用HAVING子句篩選分組

(6).計算所有的表達式

(7).使用ORDER BY對結(jié)果集進行排序

#p#

二 執(zhí)行順序:

1.FROM:對FROM子句中前兩個表執(zhí)行笛卡爾積生成虛擬表vt1

2.ON:對vt1表應用ON篩選器只有滿足< join_condition> 為真的行才被插入vt2

3.OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行將行作為外部行添加到vt2 生成t3如果from包含兩個以上表則對上一個聯(lián)結(jié)生成的結(jié)果表和下一個表重復執(zhí)行步驟和步驟直接結(jié)束

4.WHERE:對vt3應用 WHERE 篩選器只有使< where_condition> 為true的行才被插入vt4

5.GROUP BY:按GROUP BY子句中的列列表對vt4中的行分組生成vt5

6.CUBE|ROLLUP:把超組(supergroups)插入vt6 生成vt6

7.HAVING:對vt6應用HAVING篩選器只有使< having_condition> 為true的組才插入vt7

8.SELECT:處理select列表產(chǎn)生vt8

9.DISTINCT:將重復的行從vt8中去除產(chǎn)生vt9

10.ORDER BY:將vt9的行按order by子句中的列列表排序生成一個游標vc10

11.TOP:從vc10的開始處選擇指定數(shù)量或比例的行生成vt11 并返回調(diào)用者

看到這里,那么用過linqtosql的語法有點相似啊?如果我們我們了解了sqlserver執(zhí)行順序,那么我們就接下來進一步養(yǎng)成日常sql好習慣,也就是在實現(xiàn)功能同時有考慮性能的思想,數(shù)據(jù)庫是能進行集合運算的工具,我們應該盡量的利用這個工具,所謂集合運算實際就是批量運算,就是盡量減少在客戶端進行大數(shù)據(jù)量的循環(huán)操作,而用SQL語句或者存儲過程代替。

#p#

三、只返回需要的數(shù)據(jù)

返回數(shù)據(jù)到客戶端至少需要數(shù)據(jù)庫提取數(shù)據(jù)、網(wǎng)絡傳輸數(shù)據(jù)、客戶端接收數(shù)據(jù)以及客戶端處理數(shù)據(jù)等環(huán)節(jié),如果返回不需要的數(shù)據(jù),就會增加服務器、網(wǎng)絡和客戶端的無效勞動,其害處是顯而易見的,避免這類事件需要注意:

A、橫向來看,

(1)不要寫SELECT *的語句,而是選擇你需要的字段。

(2)當在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤。

  1. 如有表table1(ID,col1)和table2 (ID,col2)  
  2. Select A.ID, A.col1, B.col2  
  3. -- Select A.ID, col1, col2 –不要這么寫,不利于將來程序擴展  
  4. from table1 A inner join table2 B on A.ID=B.ID Where … 

B、縱向來看,

 (1)合理寫WHERE子句,不要寫沒有WHERE的SQL語句。

(2) SELECT TOP N * --沒有WHERE條件的用此替代

 #p#

四 :盡量少做重復的工作

A、控制同一語句的多次執(zhí)行,特別是一些基礎(chǔ)數(shù)據(jù)的多次執(zhí)行是很多程序員很少注意的。

B、減少多次的數(shù)據(jù)轉(zhuǎn)換,也許需要數(shù)據(jù)轉(zhuǎn)換是設(shè)計的問題,但是減少次數(shù)是程序員可以做到的。

C、杜絕不必要的子查詢和連接表,子查詢在執(zhí)行計劃一般解釋成外連接,多余的連接表帶來額外的開銷。

D、合并對同一表同一條件的多次UPDATE,比如

  1. UPDATE EMPLOYEE SET FNAME='HAIWER' 
  2. WHERE EMP_ID=' VPA30890F' UPDATE EMPLOYEE SET LNAME='YANG' 
  3. WHERE EMP_ID=' VPA30890F' 

這兩個語句應該合并成以下一個語句

UPDATE EMPLOYEE SET FNAME='HAIWER',LNAME='YANG' WHERE EMP_ID=' VPA30890F'

E、UPDATE操作不要拆成DELETE操作+INSERT操作的形式,雖然功能相同,但是性能差別是很大的。

#p#

五、注意臨時表和表變量的用法

在復雜系統(tǒng)中,臨時表和表變量很難避免,關(guān)于臨時表和表變量的用法,需要注意:

A、如果語句很復雜,連接太多,可以考慮用臨時表和表變量分步完成。

B、如果需要多次用到一個大表的同一部分數(shù)據(jù),考慮用臨時表和表變量暫存這部分數(shù)據(jù)。

C、如果需要綜合多個表的數(shù)據(jù),形成一個結(jié)果,可以考慮用臨時表和表變量分步匯總這多個表的數(shù)據(jù)。

D、其他情況下,應該控制臨時表和表變量的使用。

E、關(guān)于臨時表和表變量的選擇,很多說法是表變量在內(nèi)存,速度快,應該首選表變量,但是在實際使用中發(fā)現(xiàn),

(1)主要考慮需要放在臨時表的數(shù)據(jù)量,在數(shù)據(jù)量較多的情況下,臨時表的速度反而更快。

(2)執(zhí)行時間段與預計執(zhí)行時間(多長)

F、關(guān)于臨時表產(chǎn)生使用SELECT INTO和CREATE TABLE + INSERT INTO的選擇,一般情況下,

SELECT INTO會比CREATE TABLE + INSERT INTO的方法快很多,

但是SELECT INTO會鎖定TEMPDB的系統(tǒng)表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用戶并發(fā)環(huán)境下,容易阻塞其他進程,

所以我的建議是,在并發(fā)系統(tǒng)中,盡量使用CREATE TABLE + INSERT INTO,而大數(shù)據(jù)量的單個語句使用中,使用SELECT INTO。

#p#

六、子查詢的用法

子查詢是一個 SELECT 查詢,它嵌套在 SELECT、INSERT、UPDATE、DELETE 語句或其它子查詢中。

任何允許使用表達式的地方都可以使用子查詢,子查詢可以使我們的編程靈活多樣,可以用來實現(xiàn)一些特殊的功能。但是在性能上,

往往一個不合適的子查詢用法會形成一個性能瓶頸。如果子查詢的條件中使用了其外層的表的字段,這種子查詢就叫作相關(guān)子查詢。

相關(guān)子查詢可以用IN、NOT IN、EXISTS、NOT EXISTS引入。 關(guān)于相關(guān)子查詢,應該注意:

(1)

A、NOT IN、NOT EXISTS的相關(guān)子查詢可以改用LEFT JOIN代替寫法。

比如: SELECT PUB_NAME FROM PUBLISHERS WHERE PUB_ID NOT IN (SELECT PUB_ID FROM TITLES WHERE TYPE = 'BUSINESS') 可以改寫成: SELECT A.PUB_NAME FROM PUBLISHERS A LEFT JOIN TITLES B ON B.TYPE = 'BUSINESS' AND A.PUB_ID=B. PUB_ID WHERE B.PUB_ID IS NULL

(2)

  1. SELECT TITLE FROM TITLES  
  2. WHERE NOT EXISTS  
  3. (SELECT TITLE_ID FROM SALES  
  4. WHERE TITLE_ID = TITLES.TITLE_ID) 

可以改寫成:

  1. SELECT TITLE  
  2. FROM TITLES LEFT JOIN SALES  
  3. ON SALES.TITLE_ID = TITLES.TITLE_ID  
  4. WHERE SALES.TITLE_ID IS NULL 

B、 如果保證子查詢沒有重復 ,IN、EXISTS的相關(guān)子查詢可以用INNER JOIN 代替。比如:

  1. SELECT PUB_NAME  
  2. FROM PUBLISHERS  
  3. WHERE PUB_ID IN 
  4. (SELECT PUB_ID  
  5. FROM TITLES  
  6. WHERE TYPE = 'BUSINESS'

可以改寫成:

  1. SELECT A.PUB_NAME --SELECT DISTINCT A.PUB_NAME  
  2. FROM PUBLISHERS A INNER JOIN TITLES B  
  3. ON B.TYPE = 'BUSINESS' AND 
  4. A.PUB_ID=B. PUB_ID 

(3)

C、 IN的相關(guān)子查詢用EXISTS代替,比如

  1. SELECT PUB_NAME FROM PUBLISHERS  
  2. WHERE PUB_ID IN 
  3. (SELECT PUB_ID FROM TITLES WHERE TYPE = 'BUSINESS'

可以用下面語句代替:

  1. SELECT PUB_NAME FROM PUBLISHERS WHERE EXISTS  
  2. (SELECT 1 FROM TITLES WHERE TYPE = 'BUSINESS' AND 
  3. PUB_ID= PUBLISHERS.PUB_ID) 

D、不要用COUNT(*)的子查詢判斷是否存在記錄,最好用LEFT JOIN或者EXISTS,比如有人寫這樣的語句:

  1. SELECT JOB_DESC FROM JOBS  
  2. WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)=0 

應該改成:

  1. SELECT JOBS.JOB_DESC FROM JOBS LEFT JOIN EMPLOYEE  
  2. ON EMPLOYEE.JOB_ID=JOBS.JOB_ID  
  3. WHERE EMPLOYEE.EMP_ID IS NULL 
  4. SELECT JOB_DESC FROM JOBS  
  5. WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)<>0 

應該改成:

  1. SELECT JOB_DESC FROM JOBS  
  2. WHERE EXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID) 

#p#

七:盡量使用索引

建立索引后,并不是每個查詢都會使用索引,在使用索引的情況下,索引的使用效率也會有很大的差別。只要我們在查詢語句中沒有強制指定索引,

索引的選擇和使用方法是SQLSERVER的優(yōu)化器自動作的選擇,而它選擇的根據(jù)是查詢語句的條件以及相關(guān)表的統(tǒng)計信息,這就要求我們在寫SQL

語句的時候盡量使得優(yōu)化器可以使用索引。為了使得優(yōu)化器能高效使用索引,寫語句的時候應該注意:

A、不要對索引字段進行運算,而要想辦法做變換,比如

SELECT ID FROM T WHERE NUM/2=100

應改為:

SELECT ID FROM T WHERE NUM=100*2

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

SELECT ID FROM T WHERE NUM/2=NUM1

如果NUM有索引應改為:

SELECT ID FROM T WHERE NUM=NUM1*2

如果NUM1有索引則不應該改。

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

發(fā)現(xiàn)過這樣的語句:

SELECT 年,月,金額 FROM 結(jié)余表 WHERE 100*年+月=2010*100+10

應該改為:

SELECT 年,月,金額 FROM 結(jié)余表 WHERE 年=2010 AND月=10

B、 不要對索引字段進行格式轉(zhuǎn)換

日期字段的例子:

WHERE CONVERT(VARCHAR(10), 日期字段,120)='2010-07-15'

應該改為

WHERE日期字段〉='2010-07-15' AND 日期字段<'2010-07-16'

ISNULL轉(zhuǎn)換的例子:

WHERE ISNULL(字段,'')<>''應改為:WHERE字段<>''

WHERE ISNULL(字段,'')=''不應修改

WHERE ISNULL(字段,'F') ='T'應改為: WHERE字段='T'

WHERE ISNULL(字段,'F')<>'T'不應修改

C、 不要對索引字段使用函數(shù)

WHERE LEFT(NAME, 3)='ABC' 或者WHERE SUBSTRING(NAME,1, 3)='ABC'

應改為: WHERE NAME LIKE 'ABC%'

日期查詢的例子:

WHERE DATEDIFF(DAY, 日期,'2010-06-30')=0

應改為:WHERE 日期>='2010-06-30' AND 日期 <'2010-07-01'

WHERE DATEDIFF(DAY, 日期,'2010-06-30')>0

應改為:WHERE 日期 <'2010-06-30'

WHERE DATEDIFF(DAY, 日期,'2010-06-30')>=0

應改為:WHERE 日期 <'2010-07-01'

WHERE DATEDIFF(DAY, 日期,'2010-06-30')<0

應改為:WHERE 日期>='2010-07-01'

WHERE DATEDIFF(DAY, 日期,'2010-06-30')<=0

應改為:WHERE 日期>='2010-06-30'

D、不要對索引字段進行多字段連接

比如:

WHERE FAME+ '. '+LNAME='HAIWEI.YANG'

應改為:

WHERE FNAME='HAIWEI' AND LNAME='YANG'

#p#

八:多表連接的連接條件對索引的選擇有著重要的意義,所以我們在寫連接條件條件的時候需要特別注意。

A、多表連接的時候,連接條件必須寫全,寧可重復,不要缺漏。

B、連接條件盡量使用聚集索引

C、注意ON、WHERE和HAVING部分條件的區(qū)別

ON是最先執(zhí)行, WHERE次之,HAVING最后,因為ON是先把不符合條件的記錄過濾后才進行統(tǒng)計,它就可以減少中間運算要處理的數(shù)據(jù),按理說應該速度是最快的,WHERE也應該比 HAVING快點的,因為它過濾數(shù)據(jù)后才進行SUM,在兩個表聯(lián)接時才用ON的,所以在一個表的時候,就剩下WHERE跟HAVING比較了

1考慮聯(lián)接優(yōu)先順序:

2INNER JOIN

3LEFT JOIN (注:RIGHT JOIN 用 LEFT JOIN 替代)

4CROSS JOIN

其它注意和了解的地方有:

A、在IN后面值的列表中,將出現(xiàn)最頻繁的值放在最前面,出現(xiàn)得最少的放在最后面,減少判斷的次數(shù)

B、注意UNION和UNION ALL的區(qū)別。--允許重復數(shù)據(jù)用UNION ALL好

C、注意使用DISTINCT,在沒有必要時不要用

D、TRUNCATE TABLE 與 DELETE 區(qū)別

E、減少訪問數(shù)據(jù)庫的次數(shù)

還有就是我們寫存儲過程,如果比較長的話,最后用標記符標開,因為這樣可讀性很好,即使語句寫的不怎么樣但是語句工整,C# 有region

sql我比較喜歡用的就是

  1. --startof 查詢在職人數(shù)  
  2.           sql語句  
  3. --end of 

正式機器上我們一般不能隨便調(diào)試程序,但是很多時候程序在我們本機上沒問題,但是進正式系統(tǒng)就有問題,但是我們又不能隨便在正式機器上操作,那么怎么辦呢?我們可以用回滾來調(diào)試我們的存儲過程或者是sql語句,從而排錯。

  1. BEGIN TRAN  
  2.    UPDATE a SET 字段='' 
  3. ROLLBACK 

作業(yè)存儲過程我一般會加上下面這段,這樣檢查錯誤可以放在存儲過程,如果執(zhí)行錯誤回滾操作,但是如果程序里面已經(jīng)有了事務回滾,那么存儲過程就不要寫事務了,這樣會導致事務回滾嵌套降低執(zhí)行效率,但是我們很多時候可以把檢查放在存儲過程里,這樣有利于我們解讀這個存儲過程,和排錯。

  1. BEGIN TRANSACTION 
  2. --事務回滾開始  
  3. --檢查報錯  
  4. IF ( @@ERROR > 0 )  
  5.         BEGIN 
  6.         --回滾操作  
  7.                 ROLLBACK TRANSACTION 
  8.                 RAISERROR('刪除工作報告錯誤', 16, 3)  
  9.                 RETURN 
  10.         END 
  11. --結(jié)束事務  
  12. COMMIT TRANSACTION 

好久沒有寫博文了,工作項目一個接一個,再加上公司人員流動,新人很多事情接不下來,加班成了家常便飯,倉促寫下這些希望對大家有幫助,不對的也歡迎指點,交流互相提高。

有錯誤的地方歡迎大家拍磚,希望交流和共享。

原文鏈接:http://www.cnblogs.com/MR_ke/archive/2011/05/29/2062085.html

【編者推薦】

  1. 思科推新數(shù)據(jù)中心解決方案支持SQL Server
  2. 數(shù)據(jù)庫日常維護常用的腳本部分收錄
  3. 云端數(shù)據(jù)庫:微軟SQL Azure及其應用場景
  4. SQL點滴之收集SQL Server線程等待信息
責任編輯:艾婧 來源: 博客園
相關(guān)推薦

2022-09-16 00:32:39

SQL數(shù)據(jù)庫習慣

2021-02-06 14:05:29

代碼語言bug

2020-11-26 06:29:20

代碼非業(yè)務程序員

2010-09-08 12:55:34

CSS

2020-11-02 13:03:28

MySQLSQL索引

2020-11-03 07:01:46

SQLMySQL

2024-02-26 08:13:51

MySQLSQL性能

2010-04-22 09:43:04

SQL Server

2011-04-19 10:20:09

數(shù)據(jù)庫

2022-04-08 14:38:43

程序員習慣終端

2016-04-26 09:42:27

歪評papi360

2015-03-04 10:22:16

程序員快樂的程序員好習慣

2011-07-07 15:26:28

PHP編程習慣

2011-03-29 12:41:49

編程

2020-08-04 18:23:37

戴爾

2017-04-12 09:34:30

數(shù)據(jù)科學家統(tǒng)計學家好習慣

2021-05-19 08:55:37

代碼程序員經(jīng)驗分享

2020-04-22 10:35:07

編程學習技術(shù)

2010-06-11 14:35:18

UML序列圖

2022-10-08 10:42:20

Linux虛擬機
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美在线综合 | 亚洲精品免费观看 | 成人美女免费网站视频 | 日韩一级电影免费观看 | 国产成人99久久亚洲综合精品 | 黄色一级视频 | 久久国产免费 | 一区二区三区在线播放 | 麻豆久久久久久久久久 | 国产高清免费 | 欧美美女被c | 一级毛片在线视频 | 欧美成人精品二区三区99精品 | 久久久久久免费毛片精品 | 在线观看亚洲专区 | www,黄色,com | 一级黄色片网站 | 青青草精品 | 日本一二三区在线观看 | 91精品国产日韩91久久久久久 | 日韩视频在线一区 | 一区二区三区回区在观看免费视频 | 亚洲成人一区 | 久久综合久 | 日韩精品视频网 | 日韩欧美字幕 | 国产精品美女一区二区 | 亚洲精品一区中文字幕乱码 | 欧美激情久久久久久 | 97精品国产97久久久久久免费 | 欧美久久精品 | 亚洲乱码国产乱码精品精的特点 | 国产视频黄色 | 亚洲综合色 | 精品婷婷 | 久久狼人天堂 | 国产精品日韩在线 | 久久久久久久综合 | 日韩高清国产一区在线 | 精品在线一区二区 | 成年人视频在线免费观看 |