今天,我就來和你們講講要怎麼回答這道問題。首先,咱們要穩住不要慌,本身是本身親手作的項目,第一個問題應該都不大,第二個問題就須要在面試以前作好充分的準備啦…面試
在回答問題以前先要了解查詢的流程:查詢是由一系列的子任務組成的,包括從客戶端,到服務器,而後在服務器上進行解析,生成執行計劃,執行,並返回結果給客戶端。其中「執行」能夠認爲是整個生命週期中最重要的階段,這其中包括了大量爲了檢索數據到存儲引擎的調用以及調用後的數據處理,包括排序、分組。爲了完成這些任務,查詢須要在不一樣的地方花費時間,包括網絡,CPU計算,生成統計信息和執行計劃、鎖等待操做。進行一些沒必要要的額外操做時或者某些重複執行某些額外操做會消耗大量的時間。數據庫
查詢性能低下最基本的緣由是訪問的數據太多。某些查詢可能不可避免地須要篩選大量的數據,大部分性能低下的查詢均可以經過減小訪問的數據量的方式進行優化。對於低效的查詢,能夠經過如下兩個步驟來分析:緩存
上面的都是理論,在實踐中,MySQL的優化主要涉及SQL語句及索引的優化、數據表結構的優化這三個方面。服務器
一、少用子查詢
儘可能少用子查詢,由於子查詢會產生臨時表;除非像count(*)臨時表很小的。網絡
二、少用SELECT *
每次看到SELECT *都須要用懷疑的眼光審視,是否真的須要返回所有的列?取出所有的列,會讓優化器沒法完成索引覆蓋掃描這類優化,還會爲服務器帶來額外的I/O、內存和CPU的消耗。函數
三、查詢必要的記錄
一個常見的錯誤是經常會誤覺得MySQL只會返回須要的數據,實際上MySQL倒是先返回所有結果集再進行計算,建議在查詢後面加上LIMIT。性能
四、不要重複查詢相同的數據
不斷執行相同的查詢,而後每次都會返回徹底相同的數據。能夠採用的方案是初次查詢的時候將這個數據緩存起來,須要的時候從緩存中取出,這樣性能顯然會更好。優化
五、COUNT查詢優化
COUNT()聚合函數的做用:統計某一個列值的數量,也能夠統計行數。須要注意的是統計列值時要求列值是非空的(不統計NULL),COUNT()查詢儘量少的行。設計
舉個例子:若是咱們直接查 id>100 的記錄,涉及到的有兩千多萬行記錄掃描。可是因爲COUNT()特性,咱們能夠用 count() - (id<100)的作法,這樣掃描的行就只有100行了。排序
六、Where子句中,where表之間的鏈接必須寫在其餘Where條件以前,那些能夠過濾掉最大數量記錄的條件必須寫在Where子句的末尾.HAVING最後。
七、用EXISTS替代IN、用NOT EXISTS替代NOT IN。
八、避免在索引列上使用計算。
九、避免在索引列上使用IS NULL和IS NOT NULL。
十、對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。
十一、應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描。
十二、應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。
一、關聯查詢優化
確保ON 或則USING 子句的列上有索引。建立索引時就要考慮關聯的順序,當表A和表B用列c關聯的時候,若是優化器關聯順序是B、A,就只須要在表A上創建索引,沒用的索引會佔用存儲。
二、GROUP BY 和 DISTINCT優化
GROUP BY 和 DISTINCT的優化最有效的就是使用索引。全部對於分組的列必定要創建索引。好比:
select product, count(*) from orders group by product;
這樣的一個查詢,對product要創建索引。
三、LIMIT分頁優化
進行分頁操做時,一般都會經過偏移量來查詢某些數據。而後再加上解釋的order by,性能通常都不錯。對於order by的列 必定要加上索引。可是對於limit 10000,10 這樣檢索目標10條記錄必須先先查詢前面的10000條記錄。代價很高,這種時候優化最簡單辦法就是使用覆蓋索引。
注意索引失效的狀況,
1)以「%」開頭的LIKE語句,模糊匹配
2)OR語句先後沒有同時使用索引
3)數據類型出現隱式轉化(如varchar不加單引號的話可能會自動轉換爲int型)
選擇優化數據類型的幾條建議: