SQL的開發建議(MySQL和Oracle)

MYSQL 開發建議

關於建表sql

一、儘可能使用INNODB存儲引擎。數據庫

二、建議使用UNSIGNED存儲非負數值。ide

三、建議使用INT UNSIGNED存儲IPV4。函數

四、強烈建議使用TINYINT來代替ENUM類型。優化

五、使用VARBINARY存儲大小寫敏感的變長字符串或二進制內容。排序

七、區分使用DATETIME和TIMESTAMP。存儲年使用YEAR類型。存儲日期使用DATE類型。 存儲時間(精確到秒)建議使用TIMESTAMP類型。索引

八、將大字段、訪問頻率低的字段拆分到單獨的表中存儲,分離冷熱數據。事務

九、禁止在數據庫表中存儲明文密碼。資源

10.表必須有主鍵,推薦使用UNSIGNED自增列做爲主鍵。開發

十一、表字符集使用UTF8,必要時可申請使用UTF8MB4字符集。

a)UTF8字符集存儲漢字佔用3個字節,存儲英文字符佔用一個字節。

b)UTF8統一併且通用,不會出現轉碼出現亂碼風險。

c)若是遇到EMOJ等表情符號的存儲需求,可申請使用UTF8MB4字符集。

十二、採用合適的分庫分表策略。例如千庫十表、十庫百表等。

 

關於索引

一、禁止冗餘索引。

二、禁止重複索引。

三、不在低基數列上創建索引,例如「性別」。

四、合理使用覆蓋索引減小IO,避免排序。

 

關於SQL

一、 無論數據庫隔離級別是什麼狀態或者事務大小,養成COMMIT習慣,避免事務鎖的長期持有。

二、 更新(update)sql語句儘可能使用主鍵條件

三、用IN代替OR。SQL語句中IN包含的值不該過多。

四、用UNION ALL代替UNION。UNION ALL不須要對結果集再進行排序。

五、儘可能不使用order by rand()。

六、建議使用合理的分頁方式以提升分頁效率。

七、SELECT只獲取必要的字段,儘可能少使用SELECT *。

八、SQL中避免出現now()、rand()、sysdate()、current_user()等不肯定結果的函數。

九、減小與數據庫交互次數,儘可能採用批量SQL語句。

使用下面的語句來減小和db的交互次數:

a)INSERT ... ON DUPLICATE KEY UPDATE

b)REPLACE INTO

c)INSERT IGNORE

d)INSERT INTO VALUES()

十、拆分複雜SQL爲多個小SQL,避免大事務。

十一、對同一個表的屢次alter操做必須合併爲一次操做。

Oracle 開發建議

使用索引須要注意的地方:

一、避免在索引列上使用NOT, 

二、避免在索引列上使用計算.  

低效:SELECT … FROM DEPT WHERE SAL * 12 > 25000;

高效:SELECT … FROM DEPT WHERE SAL > 25000/12;

三、避免在索引列上使用IS NULL和IS NOT NULL

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

高效:(索引有效) SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

四、避免改變索引列的類型.

 

關於SQL

一、用EXISTS替換DISTINCT:  

(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E

WHERE D.DEPT_NO = E.DEPT_NO

And E.sex =man

(高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D

WHERE EXISTS

( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO

And E.sex =man

);

二、用(UNION)UNION ALL替換OR (適用於索引列)

高效: SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 UNION ALL

SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = 「MELBOURNE」

低效: SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = 「MELBOURNE」

三、用UNION-ALL 替換UNION ( 若是有可能的話)。

四、Order By語句加在索引列,最好是主鍵PK上。

SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE(低效)

SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_CODE (高效)

五、避免使用耗費資源的操做:

帶有DISTINCT,UNION,MINUS,INTERSECT的SQL語句會啓動SQL引擎 執行耗費資源的排序(SORT)功能.

六、使用Where替代Having(若是能夠的話)

低效:

SELECT JOB , AVG(SAL)

FROM EMP GROUP JOB HAVING JOB = ‘PRESIDENT'AND AVG(SAL)>XXX

高效:

SELECT JOB , AVG(SAL)

FROM EMP

WHERE JOB = ‘PRESIDENT'

OR JOB = ‘MANAGER' GROUP JOB Having AND AVG(SAL)>XXX

七、一般來講,若是語句可以避免子查詢的使用,就儘可能不用子查詢。由於子查詢的開銷是至關昂貴的。具體的例子在後面的案例「一條SQL的優化過程」中。

八、注意WHERE子句中的鏈接順序。合理選擇驅動表。

九、SELECT子句中避免使用 *。ORACLE在解析的過程當中, 會將'*' 依次轉換成全部的列名, 這個工做是經過查詢數據字典完成的, 這意味着將耗費更多的時間 。

相關文章
相關標籤/搜索