1. 程式人生 > 資料庫 >資料庫優化以及常用的語句

資料庫優化以及常用的語句

(部分摘自 https://www.cnblogs.com/kkxwze/p/10791719.html)

1、DDL和DML

 DML:資料操縱語言:比如insert,delete,update 

 DQL:資料查詢語言:Select 查詢語句不存在提交問題

 DDL:資料定義語言:如Create,Alter和Drop 

 

2、oracle 分頁

select c.* from (

  select a.*, row_number() over (order by a.id) idx from table a where 1=1 order by a.id

)  c where c.idx > (pageNum-1) * pageSize and c.idx <= pageNum * pageSize

 

3 、mysql 分頁

資料量小時:select * from table limit (pageNum-1) ,pageSize

資料量大時:1、主鍵建立索索引 2、select * from table where id>(pageNum-1) * pageSize order by id  limit pageSize

 

4、 索引 

  1、索引應該經常建在Where 子句經常用到的列上

  2、對於聯表查詢的欄位,應該建立索引。

  3、如果經常在某表的一個欄位進行Order By 則也經過進行索引。

  4、不在小表上建設索引。

  5、索引可以提高查詢速度,但是DML語句會更新索引,造成DML語句執行變慢

  6、建立索引:create index indexName on table(columnName1,columnName2,。。。。。)

  7、如果在where 子句中有OR 操作符或單獨引用Job 列(索引列的後面列) 則將不會走索引,將會進行全表掃描。

 

5、oeacle的Sql 優化:

當Oracle資料庫拿到SQL語句時,其會根據查詢優化器分析該語句,並根據分析結果生成查詢執行計劃。
也就是說,資料庫是執行的查詢計劃,而不是Sql語句。
查詢優化器有rule-based-optimizer(基於規則的查詢優化器) 和Cost-Based-optimizer(基於成本的查詢優化器)。

其中基於規則的查詢優化器在10g版本中消失。
對於規則查詢,其最後查詢的是全表掃描。而CBO則會根據統計資訊進行最後的選擇。


1、先執行From ->Where ->Group By->Order By

2、執行From 字句是從右往左進行執行。因此必須選擇記錄條數最少的表放在右邊。這是為什麼呢?  

3、對於Where字句其執行順序是從後向前執行、因此可以過濾最大數量記錄的條件必須寫在Where子句的末尾,而對於多表之間的連線,則寫在之前。
因為這樣進行連線時,可以去掉大多不重複的項。  

4. SELECT子句中避免使用(*)ORACLE在解析的過程中, 會將’*’ 依次轉換成所有的列名, 這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間

5、索引失效的情況:
 ① Not Null/Null 如果某列建立索引,當進行Select * from emp where depto is not null/is null。 則會是索引失效。
 ② 索引列上不要使用函式,SELECT Col FROM tbl WHERE substr(name ,1 ,3 ) = 'ABC' 
或者SELECT Col FROM tbl WHERE name LIKE '%ABC%' 而SELECT Col FROM tbl WHERE name LIKE 'ABC%' 會使用索引。

 ③ 索引列上不能進行計算SELECT Col FROM tbl WHERE col / 10 > 10 則會使索引失效,應該改成
SELECT Col FROM tbl WHERE col > 10 * 10

 ④ 索引列上不要使用NOT ( != 、 <> )如:SELECT Col FROM tbl WHERE col ! = 10 
應該 改成:SELECT Col FROM tbl WHERE col > 10 OR col < 10 。

6、用UNION替換OR(適用於索引列)
  union:是將兩個查詢的結果集進行追加在一起,它不會引起列的變化。 由於是追加操作,需要兩個結果集的列數應該是相關的,
並且相應列的資料型別也應該相當的。union 返回兩個結果集,同時將兩個結果集重複的項進行消除。 如果不進行消除,用UNOIN ALL.

通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規則只針對多個索引列有效. 
如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.

  高效:
  SELECT LOC_ID , LOC_DESC , REGION
  FROM LOCATION
  WHERE LOC_ID = 10
  UNION
  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”
  如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.

7. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在許多基於基礎表的查詢中, 為了滿足一個條件, 往往需要對另一個表進行聯接. 在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 
在子查詢中, NOT IN子句將執行一個內部的排序和合並. 無論在哪種情況下, NOT IN都是最低效的(因為它對子查詢中的表執行了一個全表遍歷). 
為了避免使用NOT IN, 我們可以把它改寫成外連線(Outer Joins)或NOT EXISTS.

例子:

高效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)

低效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)