淺談SQL優化

SQL優化方案

在咱們書寫SQL語句的時候,其實書寫的順序、策略會影響到SQL的性能,雖然實現的功能是同樣的,可是它們的性能會有些許差異。mysql

所以,下面就講解在書寫SQL的時候,怎麼寫比較好。sql

選擇最有效率的表名順序

數據庫的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表將被最早處理數據庫

在FROM子句中包含多個表的狀況下:服務器

  • 若是三個表是徹底無關係的話,將記錄和列名最少的表,寫在最後,而後依次類推
  • 也就是說:選擇記錄條數最少的表放在最後

若是有3個以上的錶鏈接查詢:markdown

  • 若是三個表是有關係的話,將引用最多的表,放在最後,而後依次類推
  • 也就是說:被其餘表所引用的表放在最後

例如:查詢員工的編號,姓名,工資,工資等級,部門名mysql優化

emp表被引用得最多,記錄數也是最多,所以放在form字句的最後面ide

select emp.empno,emp.ename,emp.sal,salgrade.grade,dept.dname from salgrade,dept,emp where (emp.deptno = dept.deptno) and (emp.sal between salgrade.losal and salgrade.hisal) 

WHERE子句中的鏈接順序

數據庫採用自右而左的順序解析WHERE子句,根據這個原理,表之間的鏈接必須寫在其餘WHERE條件之左,那些能夠過濾掉最大數量記錄的條件必須寫在WHERE子句的之右函數

emp.sal能夠過濾多條記錄,寫在WHERE字句的最右邊性能

select emp.empno,emp.ename,emp.sal,dept.dname from dept,emp where (emp.deptno = dept.deptno) and (emp.sal > 1500) 

SELECT子句中避免使用*號

咱們當時學習的時候,「*」號是能夠獲取表中所有的字段數據的。學習

  • 可是它要經過查詢數據字典完成的,這意味着將耗費更多的時間
  • 使用*號寫出來的SQL語句也不夠直觀。

用TRUNCATE替代DELETE

這裏僅僅是:刪除表的所有記錄,除了表結構才這樣作

DELETE是一條一條記錄的刪除,而Truncate是將整個表刪除,保留表結構,這樣比DELETE快

多使用內部函數提升SQL效率

例如使用mysql的concat()函數會比使用||來進行拼接快,由於concat()函數已經被mysql優化過了。

使用表或列的別名

若是表或列的名稱太長了,使用一些簡短的別名也能稍微提升一些SQL的性能。畢竟要掃描的字符長度就變少了。。。

多使用commit

comiit會釋放回滾點…

善用索引

索引就是爲了提升咱們的查詢數據的,當表的記錄量很是大的時候,咱們就可使用索引了。

SQL寫大寫

咱們在編寫SQL 的時候,官方推薦的是使用大寫來寫關鍵字,由於Oracle服務器老是先將小寫字母轉成大寫後,才執行

避免在索引列上使用NOT

由於Oracle服務器遇到NOT後,他就會中止目前的工做,轉而執行全表掃描

避免在索引列上使用計算

WHERE子句中,若是索引列是函數的一部分,優化器將不使用索引而使用全表掃描,這樣會變得變慢

>= 替代 >

低效:
      SELECT * FROM EMP WHERE DEPTNO > 3 首先定位到DEPTNO=3的記錄而且掃描到第一個DEPT大於3的記錄 高效: SELECT * FROM EMP WHERE DEPTNO >= 4 直接跳到第一個DEPT等於4的記錄 

用IN替代OR

select * from emp where sal = 1500 or sal = 3000 or sal = 800;
      select * from emp where sal in (1500,3000,800);

老是使用索引的第一個列

若是索引是創建在多個列上,只有在它的第一個列被WHERE子句引用時,優化器纔會選擇使用該索引。 當只引用索引的第二個列時,不引用索引的第一個列時,優化器使用了全表掃描而忽略了索引

create index emp_sal_job_idex on emp(sal,job);
      ----------------------------------
      select * from emp where job != 'SALES';
相關文章
相關標籤/搜索