Mysql系列 (八) 編寫腳本

首要步驟(一般可省略):
開啟mysql服務(默認是開機時就自動運行了):
控制面板–>管理工具–>服務,在里面找到名稱為mysql的項,雙擊就可看它的服務狀態是啟動還是停止,把它設為啟動

連接mysql:
在命令行下輸入 mysql -h localhost -u root -p回車,然后輸入密碼即可;或直接運行mysql自帶的連接工具,然后輸入密碼即可.

1.編寫sql腳本,假設內容如下:

create?database?dearabao;  ??use?dearabao;  ??create?table?niuzi?(name?varchar(20));

? 保存腳本文件,假設我把它保存在F盤的hello world目錄下,于是該文件的路徑為:F:/hello world/niuzi.sql

2.執行sql腳本,可以有2種方法:
? 第一種方法:
?在命令行下(未連接數據庫),輸入 mysql -h localhost -u root -p123456 ? 第二種方法:
?在命令行下(已連接數據庫,此時的提示符為 mysql> ),輸入 source F:/hello world/niuzi.sql (注意路徑不用加引號的) 或者 /. F:/hello world/niuzi.sql (注意路徑不用加引號的) 回車即可

?

SQL編寫規范

1.書寫格式
示例代碼:

存儲過程SQL文書寫格式例

select?  ????????c.dealerCode,  ????????round(sum(c.submitSubletAmountDLR?+?c.submitPartsAmountDLR?+?c.submitLaborAmountDLR)?/?count(*),?2)?as?avg,?  ????????decode(null,?'x',?'xx',?'CNY')?  from?(?  ????????select?  ????????????????a.dealerCode,  ????????????????a.submitSubletAmountDLR,?  ????????????????a.submitPartsAmountDLR,?  ????????????????a.submitLaborAmountDLR?  ????????from?SRV_TWC_F?a  ????????where?(to_char(a.ORIGSUBMITTIME,?'yyyy/mm/dd')?>=?'Date?Range(start)'?  ????????and?to_char(a.ORIGSUBMITTIME,?'yyyy/mm/dd')??'1')?  ????????union?all?  ????????select?  ????????????????b.dealerCode,  ????????????????b.submitSubletAmountDLR,?  ????????????????b.submitPartsAmountDLR,?  ????????????????b.submitLaborAmountDLR?  ????????from?SRV_TWCHistory_F?b  ????????where?(to_char(b.ORIGSUBMITTIME,?'yyyy/mm/dd')?>=?'Date?Range(start)'?  ????????and?to_char(b.ORIGSUBMITTIME,'yyyy/mm/dd')??'1')  )?c  group?by?c.dealerCode?  order?by?avg?desc;

Java?source里的SQL字符串書寫格式例

strSQL?=?"insert?into?Snd_FinanceHistory_Tb?"????  +?"(DEALERCODE,?"???  ?+?"REQUESTSEQUECE,?"???  ??+?"HANDLETIME,?"????  ??+?"JOBFLAG,?"????  ??+?"FRAMENO,?"????  ??+?"INMONEY,?"???  ???+?"REMAINMONEY,?"???  ???+?"DELETEFLAG,?"???  ????+?"UPDATECOUNT,?"???  ?????+?"CREUSER,?"????  ?????+?"CREDATE,?"????  ?????+?"HONORCHECKNO,?"????  ?????+?"SEQ)?"????  ?????+?"values?('"?+?draftInputDetail.dealerCode?+?"',?"???  ??????+?"'"?+?draftInputDetail.requestsequece?+?"',?"????  ??????+?"sysdate,?"????+?"'07',?"????+?"'"?+?frameNO?+?"',?"????  ??????+?requestMoney?+?",?"????+?remainMoney?+?",?"????+?"'0',?"????+?"0,?"???  ???????+?"'"?+?draftStruct.employeeCode?+?"',?"????+?"sysdate,?"????  ???????+?"'"?+?draftInputDetail.honorCheckNo?+?"',?"????+?index?+?")";

? 1).縮進
??? 對于存儲過程文件,縮進為8個空格
??? 對于Java?source里的SQL字符串,不可有縮進,即每一行字符串不可以空格開頭

? 2).換行
??? 1>.Select/From/Where/Order by/Group by等子句必須另其一行寫
??? 2>.Select子句內容如果只有一項,與Select同行寫
??? 3>.Select子句內容如果多于一項,每一項單獨占一行,在對應Select的基礎上向右縮進8個空格(Java source無縮進)
??? 4>.From子句內容如果只有一項,與From同行寫
??? 5>.From子句內容如果多于一項,每一項單獨占一行,在對應From的基礎上向右縮進8個空格(Java source無縮進)
??? 6>.Where子句的條件如果有多項,每一個條件占一行,以AND開頭,且無縮進
??? 7>.(Update)Set子句內容每一項單獨占一行,無縮進
??? 8>.Insert子句內容每個表字段單獨占一行,無縮進;values每一項單獨占一行,無縮進
??? 9>.SQL文中間不允許出現空行
??? 10>.Java source里單引號必須跟所屬的SQL子句處在同一行,連接符(”+”)必須在行首

? 3).空格
??? 1>.SQL內算數運算符、邏輯運算符連接的兩個元素之間必須用空格分隔
??? 2>.逗號之后必須接一個空格
??? 3>.關鍵字、保留字和左括號之間必須有一個空格

2.不等于統一使用””
??Oracle認為”!=”和””是等價的,都代表不等于的意義。為了統一,不等于一律使用””表示

3.使用表的別名
? 數據庫查詢,必須使用表的別名

4.SQL文對表字段擴展的兼容性
? 在Java source里使用Select *時,嚴禁通過getString(1)的形式得到查詢結果,必須使用getString(“字段名”)的形式
? 使用Insert時,必須指定插入的字段名,嚴禁不指定字段名直接插入values

5.減少子查詢的使用
? 子查詢除了可讀性差之外,還在一定程度上影響了SQL運行效率
? 請盡量減少使用子查詢的使用,用其他效率更高、可讀性更好的方式替代

6.適當添加索引以提高查詢效率
? 適當添加索引可以大幅度的提高檢索速度
? 請參看ORACLE SQL性能優化系列

7.對數據庫表操作的特殊要求
? 本項目對數據庫表的操作還有以下特殊要求:

? 1).以邏輯刪除替代物理刪除
??? 注意:現在數據庫表中數據沒有物理刪除,只有邏輯刪除
??? 以deleteflag字段作為刪除標志,deleteflag=’1’代表此記錄被邏輯刪除,因此在查詢數據時必須考慮deleteflag的因素
??? deleteflag的標準查詢條件:NVL(deleteflag, ‘0’) ‘1’

? 2).增加記錄狀態字段
??? 數據庫中的每張表基本都有以下字段:DELETEFLAG、UPDATECOUNT、CREDATE、CREUSER、UPDATETIME、UPDATEUSER
??? 要注意在對標進行操作時必須考慮以下字段

??? 插入一條記錄時要置DELETEFLAG=’0′, UPDATECOUNT=0, CREDATE=sysdate, CREUSER=登錄User
??? 查詢一條記錄時要考慮DELETEFLAG,如果有可能對此記錄作更新時還要取得UPDATECOUNT作同步檢查
??? 修改一條記錄時要置UPDATETIME=sysdate, UPDATEUSER=登錄User, UPDATECOUNT=(UPDATECOUNT+1) mod 1000,?
??? 刪除一條記錄時要置DELETEFLAG=’1′

? 3).歷史表
??? 數據庫里部分表還存在相應的歷史表,比如srv_twc_f和srv_twchistory_f
??? 在查詢數據時除了檢索所在表之外,還必須檢索相應的歷史表,對二者的結果做Union(或Union All)

8.用執行計劃分析SQL性能
? EXPLAIN PLAN是一個很好的分析SQL語句的工具,它可以在不執行SQL的情況下分析語句
? 通過分析,我們就可以知道ORACLE是怎樣連接表,使用什么方式掃描表(索引掃描或全表掃描),以及使用到的索引名稱

? 按照從里到外,從上到下的次序解讀分析的結果
? EXPLAIN PLAN的分析結果是用縮進的格式排列的,最內部的操作將最先被解讀,如果兩個操作處于同一層中,帶有最小操作號的將首先被執行

? 目前許多第三方的工具如PLSQL Developer和TOAD等都提供了極其方便的EXPLAIN PLAN工具
? PG需要將自己添加的查詢SQL文記入log,然后在EXPLAIN PLAN中進行分析,盡量減少全表掃描

ORACLE SQL性能優化系列

1.選擇最有效率的表名順序(只在基于規則的優化器中有效)
?? ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最后的表(基礎表driving table)將被最先處理
?? 在FROM子句中包含多個表的情況下,必須選擇記錄條數最少的表作為基礎表
?? 當ORACLE處理多個表時,會運用排序及合并的方式連接它們
?? 首先,掃描第一個表(FROM子句中最后的那個表)并對記錄進行排序;
?? 然后掃描第二個表(FROM子句中最后第二個表);
?? 最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并
?? 例如:
???? 表 TAB1 16,384 條記錄
???? 表 TAB2 5 條記錄
???? 選擇TAB2作為基礎表 (最好的方法)
???? select count(*) from tab1,tab2 執行時間0.96秒?
???? 選擇TAB2作為基礎表 (不佳的方法)
???? select count(*) from tab2,tab1 執行時間26.09秒

?? 如果有3個以上的表連接查詢,那就需要選擇交叉表(intersection table)作為基礎表,交叉表是指那個被其他表所引用的表
?? 例如:
???? EMP表描述了LOCATION表和CATEGORY表的交集
?????

??SELECT?*?  ???????FROM?LOCATION?L,  ???????CATEGORY?C,  ???????EMP?E  ???????WHERE?E.EMP_NO?BETWEEN?1000?AND?2000  ???????AND?E.CAT_NO?=?C.CAT_NO  ???????AND?E.LOCN?=?L.LOCN

???? 將比下列SQL更有效率
?????

??SELECT?*?  ???????FROM?EMP?E?,  ???????LOCATION?L?,  ???????CATEGORY?C  ???????WHERE?E.CAT_NO?=?C.CAT_NO  ???????AND?E.LOCN?=?L.LOCN  ???????AND?E.EMP_NO?BETWEEN?1000?AND?2000

2.WHERE子句中的連接順序
? ORACLE采用自下而上的順序解析WHERE子句
? 根據這個原理,表之間的連接必須寫在其他WHERE條件之前,那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾
? 例如:
???? (低效,執行時間156.3秒)
???

????SELECT?*  ???????FROM?EMP?E  ???????WHERE?SAL?&gt;?50000  ???????AND?JOB?=?'MANAGER'  ???????AND?25?<p>???? (高效,執行時間10.6秒)<br>??</p><pre class="brush:php;toolbar:false">?????SELECT?*  ???????FROM?EMP?E  ???????WHERE?25??50000  ???????AND?JOB?=?'MANAGER';

3.SELECT子句中避免使用’*’
? 當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用’*’是一個方便的方法,不幸的是,這是一個非常低效的方法
? 實際上,ORACLE在解析的過程中,會將’*’依次轉換成所有的列名
? 這個工作是通過查詢數據字典完成的,這意味著將耗費更多的時間

4.減少訪問數據庫的次數?
? 當執行每條SQL語句時,ORACLE在內部執行了許多工作:解析SQL語句,估算索引的利用率,綁定變量,讀數據塊等等
? 由此可見,減少訪問數據庫的次數,就能實際上減少ORACLE的工作量
? 例如:
??? 以下有三種方法可以檢索出雇員號等于0342或0291的職員
??? 方法1 (最低效)
???

???SELECT?EMP_NAME,?SALARY,?GRADE??????FROM?EMP??????WHERE?EMP_NO?=?342;  ??????SELECT?EMP_NAME,?SALARY,?GRADE??????FROM?EMP??????WHERE?EMP_NO?=?291;

??? 方法2 (次低效)
???

???DECLARE  ??????CURSOR?C1?(E_NO?NUMBER)?IS  ??????SELECT?EMP_NAME,SALARY,GRADE  ??????FROM?EMP  ??????WHERE?EMP_NO?=?E_NO;  ??????BEGIN  ??????OPEN?C1(342);  ??????FETCH?C1?INTO?…,…,…;  ??????…  ??????OPEN?C1(291);  ??????FETCH?C1?INTO?…,…,…;  ??????…  ??????CLOSE?C1;  ??????END;

??? 方法2 (高效)
????

??SELECT?A.EMP_NAME,?A.SALARY,?A.GRADE,  ?????????????B.EMP_NAME,?B.SALARY,?B.GRADE  ??????FROM?EMP?A,?EMP?B  ??????WHERE?A.EMP_NO?=?342  ??????AND?B.EMP_NO?=?291;

5.使用DECODE函數來減少處理時間
? 使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表
? 例如:

????SELECT?COUNT(*),?SUM(SAL)????FROM?EMP????WHERE?DEPT_NO?=?'0020'????AND?ENAME?LIKE?'SMITH%';  ????SELECT?COUNT(*),?SUM(SAL)????FROM?EMP????WHERE?DEPT_NO?=?'0030'????AND?ENAME?LIKE?'SMITH%';

??? 你可以用DECODE函數高效地得到相同結果
???

SELECT?COUNT(DECODE(DEPT_NO,?'0020',?'X',?NULL))?D0020_COUNT,  ????COUNT(DECODE(DEPT_NO,?'0030',?'X',?NULL))?D0030_COUNT,  ????SUM(DECODE(DEPT_NO,?'0020',?SAL,?NULL))?D0020_SAL,?  ????SUM(DECODE(DEPT_NO,?0030,?SAL,?NULL))?D0030_SAL  ????FROM?EMP  ????WHERE?ENAME?LIKE?'SMITH%';

? ‘X’表示任何一個字段
? 類似的,DECODE函數也可以運用于GROUP BY和ORDER BY子句中

6.用Where子句替換HAVING子句
? 避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結果集進行過濾,這個處理需要排序、統計等操作
? 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷
? 例如:
??? 低效
???

SELECT?REGION,?AVG(LOG_SIZE)  ????FROM?LOCATION  ????GROUP?BY?REGION  ????HAVING?REGION?REGION?!=?'SYDNEY'  ????AND?REGION?!=?'PERTH'

??? 高效
???

SELECT?REGION,?AVG(LOG_SIZE)  ????FROM?LOCATION  ????WHERE?REGION?REGION?!=?'SYDNEY'  ????AND?REGION?!=?'PERTH'  ????GROUP?BY?REGION

7.減少對表的查詢
? 在含有子查詢的SQL語句中,要特別注意減少對表的查詢
? 例如:
??? 低效
?

???SELECT?TAB_NAME  ????FROM?TABLES  ????WHERE?TAB_NAME?=?(SELECT?TAB_NAME?  ??????????????????????FROM?TAB_COLUMNS  ??????????????????????WHERE?VERSION?=?604)  ????AND?DB_VER?=?(SELECT?DB_VER  ??????????????????FROM?TAB_COLUMNS  ??????????????????WHERE?VERSION?=?604)

??? 高效
???

SELECT?TAB_NAME  ????FROM?TABLES  ????WHERE?(TAB_NAME,?DB_VER)?=?(SELECT?TAB_NAME,?DB_VER  ????????????????????????????????FROM?TAB_COLUMNS  ????????????????????????????????WHERE?VERSION?=?604)

? Update多個Column例子:
??? 低效

????UPDATE?EMP????SET?EMP_CAT?=?(SELECT?MAX(CATEGORY)???????????  ?????????????FROM?EMP_CATEGORIES),?????  ?????????????SAL_RANGE?=?(SELECT?MAX(SAL_RANGE)?????????????????  ??????????????FROM?EMP_CATEGORIES)????  ??????????????WHERE?EMP_DEPT?=?0020;

??? 高效
???

?UPDATE?EMP  ????SET?(EMP_CAT,?SAL_RANGE)?=?(SELECT?MAX(CATEGORY),?MAX(SAL_RANGE)  ????????????????????????????????FROM?EMP_CATEGORIES)  ????WHERE?EMP_DEPT?=?0020;

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

9.用EXISTS替代IN????????????????????????????????????
? 在許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接
? 在這種情況下,使用EXISTS(或NOT EXISTS)通常將提高查詢的效率
??? 低效
??

??SELECT?*  ????FROM?EMP?(基礎表)  ????WHERE?EMPNO?&gt;?0  ????AND?DEPTNO?IN?(SELECT?DEPTNO  ???????????????????FROM?DEPT  ???????????????????WHERE?LOC?=?'MELB')

??? 高效

????SELECT?*  ????FROM?EMP?(基礎表)  ????WHERE?EMPNO?&gt;?0  ????AND?EXISTS?(SELECT?'X'  ????FROM?DEPT  ????WHERE?DEPT.DEPTNO?=?EMP.DEPTNO  ????AND?LOC?=?'MELB')

10.用NOT EXISTS替代NOT IN
? 在子查詢中,NOT IN子句將執行一個內部的排序和合并
? 無論在哪種情況下,NOT IN都是最低效的,因為它對子查詢中的表執行了一個全表遍歷
? 為了避免使用NOT IN,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS
? 例如:
???

SELECT?…  ????FROM?EMP  ????WHERE?DEPT_NO?NOT?IN?(SELECT?DEPT_NO  ??????????????????????????FROM?DEPT  ??????????????????????????WHERE?DEPT_CAT?=?'A');

??? 為了提高效率改寫為
??? 高效
??

??SELECT?…  ????FROM?EMP?A,?DEPT?B  ????WHERE?A.DEPT_NO?=?B.DEPT(+)  ????AND?B.DEPT_NO?IS?NULL  ????AND?B.DEPT_CAT(+)?=?'A'

??? 最高效
???

SELECT?…  ????FROM?EMP?E  ????WHERE?NOT?EXISTS?(SELECT?'X'  ??????????????????????FROM?DEPT?D  ??????????????????????WHERE?D.DEPT_NO?=?E.DEPT_NO  ??????????????????????AND?DEPT_CAT?=?'A');

11.用表連接替換EXISTS
? 通常來說,采用表連接的方式比EXISTS更有效率
? 例如:
???

SELECT?ENAME  ????FROM?EMP?E  ????WHERE?EXISTS?(SELECT?'X'  ??????????????????FROM?DEPT  ??????????????????WHERE?DEPT_NO?=?E.DEPT_NO  ??????????????????AND?DEPT_CAT?=?'A');

??? 更高效
???

?SELECT?ENAME  ????FROM?DEPT?D,?EMP?E  ????WHERE?E.DEPT_NO?=?D.DEPT_NO  ????AND?DEPT_CAT?=?'A';

12.用EXISTS替換DISTINCT?
? 當提交一個包含多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT,一般可以考慮用EXIST替換
? 例如:
??? 低效
???

?SELECT?DISTINCT?DEPT_NO,?DEPT_NAME  ????FROM?DEPT?D,?EMP?E  ????WHERE?D.DEPT_NO?=?E.DEPT_NO

??? 高效
???

SELECT?DEPT_NO,?DEPT_NAME  ????FROM?DEPT?D  ????WHERE?EXISTS?(SELECT?'X'  ??????????????????FROM?EMP?E  ??????????????????WHERE?E.DEPT_NO?=?D.DEPT_NO);

? EXISTS使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果

13.用索引提高效率
? 索引是表的一個概念部分,用來提高檢索數據的效率。實際上,ORACLE使用了一個復雜的自平衡B-tree結構
? 通常,通過索引查詢數據比全表掃描要快。當ORACLE找出執行查詢和Update語句的最佳路徑時,ORACLE優化器將使用索引
? 同樣,在聯結多個表時使用索引也可以提高效率。另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證

? 除了那些LONG或LONG RAW數據類型,你可以索引幾乎所有的列
? 通常在大型表中使用索引特別有效,當然,在掃描小表時,使用索引同樣能提高效率

? 雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價
? 索引需要空間來存儲,也需要定期維護,每當有記錄在表中增減或索引列被修改時,索引本身也會被修改
? 這意味著每條記錄的INSERT、DELETE、UPDATE將為此多付出4、5次的磁盤I/O
? 因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢

? ORACLE對索引有兩種訪問模式:
? 1).索引唯一掃描(INDEX UNIQUE SCAN)
??? 大多數情況下, 優化器通過WHERE子句訪問INDEX
??? 例如:
????? 表LODGING有兩個索引:建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER
???

???SELECT?*  ??????FROM?LODGING  ??????WHERE?LODGING?=?'ROSE?HILL';

????? 在內部,上述SQL將被分成兩步執行:
????? 首先,LODGING_PK索引將通過索引唯一掃描的方式被訪問,獲得相對應的ROWID;然后通過ROWID訪問表的方式執行下一步檢索
????? 如果被檢索返回的列包括在INDEX列中,ORACLE將不執行第二步的處理(通過ROWID訪問表)
????? 因為檢索數據保存在索引中,單單訪問索引就可以完全滿足查詢結果

? 2).索引范圍查詢(INDEX RANGE SCAN)
??? 適用于兩種情況:?
??? 1>.基于唯一性索引的一個范圍的檢索
??? 2>.基于非唯一性索引的檢索
??? 例1
????

??SELECT?LODGING  ??????FROM?LODGING  ??????WHERE?LODGING?LIKE?'M%';

????? WHERE子句條件包括一系列值,ORACLE將通過索引范圍查詢的方式查詢LODGING_PK
????? 由于索引范圍查詢將返回一組值,它的效率就要比索引唯一掃描低一些

??? 例2
?????

SELECT?LODGING  ??????FROM?LODGING  ??????WHERE?MANAGER?=?'BILL?GATES';

????? 這個SQL的執行分兩步,LODGINGMANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID),通過ROWID訪問表得到LODGING列的值由于LODGINGMANAGER的索引范圍查詢(得到所有符合條件記錄的ROWID),通過ROWID訪問表得到LODGING列的值由于LODGINGMANAGER是一個非唯一性的索引,數據庫不能對它執行索引唯一掃描

? WHERE子句中,如果索引列所對應的值的第一個字符由通配符(WILDCARD)開始,索引將不被采用

????SELECT?LODGING  ????FROM?LODGING  ????WHERE?MANAGER?LIKE?'%HANMAN';

? 在這種情況下,ORACLE將使用全表掃描

14.避免在索引列上使用計算
? WHERE子句中,如果索引列是函數的一部分,優化器將不使用索引而使用全表掃描
? 例如:
??? 低效
?

???SELECT?…  ????FROM?DEPT  ????WHERE?SAL?*?12?&gt;?25000;

??? 高效
???

SELECT?…  ????FROM?DEPT  ????WHERE?SAL?&gt;?25000/12;

? 請務必注意,檢索中不要對索引列進行處理,如:TRIM,TO_DATE,類型轉換等操作,破壞索引,使用全表掃描,影響SQL執行效率

15.避免在索引列上使用IS NULL和IS NOT NULL
? 避免在索引中使用任何可以為空的列,ORACLE將無法使用該索引
? 對于單列索引,如果列包含空值,索引中將不存在此記錄;
? 對于復合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為空,則記錄存在于索引中

? 如果唯一性索引建立在表的A列和B列上,并且表中存在一條記錄的A,B值為(123,null),
? ORACLE將不接受下一條具有相同A,B值(123,null)的記錄插入
? 如果所有的索引列都為空,ORACLE將認為整個鍵值為空,而空不可能等于空,因此你可以插入1000條具有相同鍵值的記錄,當然它們都是空!
? 因為空值不存在于索引列中,所以WHERE子句中對索引列進行空值比較將使ORACLE停用該索引

? 低效(索引失效)
? SELECT …
? FROM DEPARTMENT
? WHERE DEPT_CODE IS NOT NULL

16.使用UNION-ALL和UNION
? 當SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合并,然后在輸出最終結果前進行排序
? 如果用UNION ALL替代UNION,這樣排序就不是必要了,效率就會因此得到提高

? 需要注意的是,UNION ALL將重復輸出兩個結果集合中相同記錄,因此還是要從業務需求分析使用UNION ALL的可行性

關于索引下列經驗請參考:?
1).如果檢索數據量超過30%的表中記錄數,使用索引將沒有顯著的效率提高
2).在特定情況下,使用索引也許會比全表掃描慢,但這是同一個數量級上的差距;而通常情況下,使用索引比全表掃描要快幾倍乃至幾千倍!

其他具體內容請參考《ORACLE SQL性能優化系列》

17.使用PrepareStatement
在同一個方法中,當循環使用SQL文時,為了提高性能,
請使用PreparedStatement。注意,
僅限使用于少數的模塊。
方法如下:

??PreparedStatement?stmt   =?conn.prepareStatement("select?a?from?TABLE_A?where?b=??c=?");   for(???){?????stmt.setInt(1,?varB);     ?????stmt.setString(2,?varC);   ?    ?? ?ResultSet?rst?=?stmt.executeQuery();   }

以上就是Mysql系列 (八) 編寫腳本的內容,更多相關內容請關注PHP中文網(www.php.cn)!

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享