MYSQL優化查詢

當數據量上百萬級別的時候,查詢將會變得愈來愈慢,咱們必需要對咱們的查詢進行優化,這樣才能避免慢查詢,首先是語句優化,其次是建立索引,其中建立索引是個很麻煩的事情。一般在不創建索引的狀況下,數據庫會對全表進行檢索,雖然創建索引會使修改跟新增記錄慢一點,但其實影響數據庫性能的基本仍是查詢。索引是一種特殊的文件,咱們只須要知道對某個字段,或者某個字段列創建索引就好了,不必過多的關心他是如何工做的數據庫

1、索引的建立刪除查看方法
數據庫設計

建立索引有兩種方法,一種是用CREATE INDEX,一種是ALTER TABLE語句
函數

1.ALTER TABLE
ALTER TABLE用來建立普通索引、UNIQUE索引或PRIMARY KEY索引。
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)
其中table_name是要增長索引的表名,column_list指出對哪些列進行索引,多列時各列之間用逗號分隔。索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE容許在單個語句中更改多個表,所以能夠在同時建立多個索引。
2.CREATE INDEX
CREATE INDEX可對錶增長普通索引或UNIQUE索引。
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)post

一樣,刪除索引也有兩種方法,用drop就能夠徹底能夠了,搞多了也不必性能

DROP INDEX index_name ON table_name優化

查看索引spa

show index from table_name;設計

2、索引的建立code

理論上來講,MYSQL支持一個表每一個列都建立索引,只要不大於16個就好了,可是創建這麼多索引也不必,咱們只對咱們常常進行查詢的語句進行優化,對於常常檢索的字段創建索引排序

3、索引失效的狀況

一、若是WEHERE子句的查詢條件裏有不等號(WHEREcoloum != …),MySQL將沒法使用索引。

避免使用!=或<>、IS NULL或IS NOT NULL、IN ,NOT IN等這樣的操做符,由於這會使系統沒法使用索引,而只能直接搜索表中的數據。例如:  SELECT id FROM employee WHERE id != "B%" 優化器將沒法經過索引來肯定將要命中的行數,所以須要搜索該表的全部行。

二、相似地,若是WHERE子句的查詢條件裏使用了函數(WHEREDAY(column) = …),MySQL也將沒法使用索引。

三、在JOIN操做中(須要從多個數據表提取數據時),MySQL只有在主鍵和外鍵的數據類型相同時才能使用索引

若是WHERE子句的查詢條件裏使用比較操做符LIKE和REGEXP,MySQL只有在搜索模板的第一個字符不是通配符的狀況下才能使用索引。好比說,若是查詢條件是LIKE ‘abc%’,MySQL將使用索引;若是查詢條件是LIKE ‘%c’,MySQL將不使用索引。

四、在ORDERBY操做中,MySQL只有在排序條件不是一個查詢條件表達式的狀況下才使用索引。(雖然如此,在涉及多個數據表查詢裏,即便有索引可用,那些索引在加快ORDERBY方面也沒什麼做用)

五、若是某個數據列裏包含許多重複的值,就算爲它創建了索引也不會有很好的效果。好比說,若是某個數據列裏包含的淨是些諸如」0/1″或」Y/N」等值,就沒有必要爲它建立一個索引。

六、索引不會包含有NULL值的列
  只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此複合索引就是無效的。因此咱們在數據庫設計時不要讓字段的默認值爲NULL。

七、不要在列上進行運算
   select * from users whereYEAR(adddate)<2007;將在每一個行上進行運算,這將致使索引失效而進行全表掃描,所以咱們能夠改爲select* from users where adddate<‘2007-01-01’;

八、不使用NOT IN和<>操做
  NOT IN和<>操做都不會使用索引將進行全表掃描。NOTIN能夠NOTEXISTS代替,id<>3則可以使用id>3or id<3來代替。

九、 可以用BETWEEN的就不要用IN
SELECT * FROM T1 WHERE ID IN (10,11,12,13,14)改爲:SELECT * FROM T1 WHERE ID BETWEEN 10 AND 14
由於IN會使系統沒法使用索引,而只能直接搜索表中的數據。

十、 DISTINCT的就不用GROUP BY
  SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID 可改成:SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10 

十一、使用視圖加速查詢 把表的一個子集進行排序並建立視圖,有時能加速查詢。它有助於避免多重排序 操做,並且在其餘方面還能簡化優化器的工做。例如: SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 AND cust.postcode>「98000」 ORDER BY cust.name 若是這個查詢要被執行屢次而不止一次,能夠把全部未付款的客戶找出來放在一個視圖中,並按客戶的名字進行排序: CREATE VIEW DBO.V_CUST_RCVLBES AS SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 ORDER BY cust.name 而後如下面的方式在視圖中查詢: SELECT * FROM V_CUST_RCVLBES WHERE postcode>「98000」 視圖中的行要比主表中的行少,並且物理順序就是所要求的順序,減小了磁盤I/O,因此查詢工做量能夠獲得大幅減小。

相關文章
相關標籤/搜索