日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

高性能MySQL——查询性能优化

發布時間:2023/12/15 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高性能MySQL——查询性能优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在數據庫設計中,如果查詢寫得很糟糕,即使庫表結構設計再合理,索引再合理也無法實現高性能。

1、優化數據訪問

查詢性能低下最基本的原因是訪問的數據太多。對于低效的查詢,通過以下兩步來分析總是很有效:

  • 確認應用程序是否在檢索大量超過需要的數據。這通常意味著訪問了太多行或者太多列;
  • 確認MySQL服務器層是否在分析大量超過需要的數據行。
  •   是否向數據庫請求了不需要的數據

    有些查詢會請求超過實際需要的數據,然后被應用程序丟棄,這會增加MySQL服務器的額外負擔,也會增加網絡開銷。

    典型案例:

  • 查詢不需要的記錄。例如:查詢表中所有數據,只顯示了前10條。最簡單有效的辦法——在這樣的查詢后面加上LIMIT;
  • 多表關聯時返回全部列。例如:SETECT * FROM actor INNER JOIN film_actor USING(actor_id) ...; 改進:SELCET actor.* FROM?actor INNER JOIN film_actor USING(actor_id) ...;只取出需要的列;
  • 總是取出全部列。取出全部列,會讓優化器無法優化器無法完成索引覆蓋掃描這類優化,還會為服務器帶來額外的I/O、CPU和內存消耗。因此一些DBA甚至嚴格禁止SELECT *這種寫法;
  • 重復查詢相同的數據。
  •   MySQL是否掃描額外的記錄

    對于MySQL,最簡單的衡量查詢開銷的三個指標:響應時間;掃描行數;返回行數。

    一般MySQL能夠使用三種方式應用where條件,從優到劣依次為:

  • 在索引中使用where條件來過濾不匹配的記錄,這在存儲引擎層完成;
  • 使用索引覆蓋掃描來返回記錄,直接從索引中過濾不需要的記錄,并返回命中結果。這在MySQL服務器層完成,但無需回表查詢;
  • 從數據表中返回數據,然后過濾不滿足條件的記錄。這在MySQL服務器層完成,需要從數據表讀出所有記錄然后過濾。
  • 如果發現查詢需要掃描大量數據,但是只返回少量數據時,可以嘗試如下方法去優化它:

  • 使用索引覆蓋掃描,把所有需要用到的列都放到索引中,這樣存儲引擎無需回表獲取對應行數據;
  • 改變庫表結構。例如:使用單獨的匯總表;
  • 重寫次復雜查詢,讓MySQL優化器能夠以更優的方式去執行它。
  • 2、重構查詢的方式

  • 一個復雜查詢還是多個簡單查詢。設計查詢的時候,是否需要將一個復雜查詢分成多個簡單查詢,這是一個需要考慮的重要問題;
  • 切分查詢——將一個大查詢切分成多個小查詢,每個查詢完全一樣,每次只返回一部分結果。例如:一次需要刪除1000w條數據,如果切分為每次刪除1w條,分多次刪除,這樣會大大減輕MySQL服務器的負擔。DELETE FROM messages WHERE ...;
  • 分解關聯查詢——用分解關聯查詢的方式重構查詢有如下優勢:
    • 讓緩存的效率更高。許多引用程序可以方便的緩存單表查詢對應的結果對象;
    • 將查詢分解后,執行單個查詢可以減少鎖的爭用;
    • 在應用層做關聯,可以更容易對數據庫做拆分,更容易做到高性能和可擴展;
    • 查詢本身效率也可能會有所提升。例如:使用IN()代替關聯查詢,可以讓MySQL按照ID順序進行查詢,這可能比隨機關聯更高效;
    • 可以減少冗余記錄的查詢。
  • 3、查詢執行的基礎(略)

    4、MySQL查詢優化器的局限性

      關聯子查詢

    例如:SELECT * FROM film WHERE film_id IN(SELECT film_id FROM film_actor WHERE actor_id = 1); MySQL優化器優化后:SELECT * FROM film WHERE EXISTS(SELECT film_id FROM film_actor WHERE actor_id = 1 AND film_actor.film_id = film.film_id);

    從優化器優化后的結果可以看出,MySQL會將相關外層表壓到子查詢中,此時子查詢需要根據“film_id”來關聯外部表film,因為需要“film_id”字段,MySQL認為無法執行子查詢,所以會對film表執行全表掃描,如此性能就非常低了。

    優化方案:通過關聯查詢來改寫關聯子查詢。例如:SELECT film.* FROM film INNER JOIN film_actor USING(film_id) WHERE actor_id = 1;

      UNION的限制

    有時候MySQL不能將限制條件從外層下到內層。例如:希望UNION的各個子句能夠根據LIMIT只取部分結果集,或希望先排序再合并結果集,就需要在UNION的各個子句分別使用這些子句。

    如:(SELECT first_name, last_name FROM actor ) UNION (SELECT first_name, last_name FROM customer) ORDER BY last_name LIMIT 20;

    優化方案:(SELECT first_name, last_name FROM actor?ORDER BY last_name?LIMIT 20) UNION (SELECT first_name, last_name FROM customer?ORDER BY last_name?LIMIT 20) LIMIT 20;

      松散索引掃描

    由于歷史原因,MySQL不支持松散索引掃描,也就無法按照不連續的方式掃描一個索引。

    例如:存在索引key(a, b);執行查詢SELECT * FROM table WHERE b BETWEEN 2 AND 5;?因為索引的前導字段是列a,但查詢中只指定了b,顧MySQL無法使用這個索引;

    優化方案:給前導列加上可能的常數值。SELECT * FROM table WHERE a IN (2, 3, 5, ...) AND b BETWEEN 2 AND 5;

      在同一張表上查詢和更新

    MySQL不允許對同一張表同時進行查詢和更新。可以通過生成臨時表的形式來繞過此限制。

    例如:UPDATE tbl AS outer_tbl SET cnt = (SELECT count(*) FROM tbl AS inner_tbl WHERE inner_tbl.type = outer_tbl.type);

    優化方案:UPDATE tbl INNER JOIN(SELECT type, count(*) AS cnt FROM tbl GROUP BY type) SET tbl.cnt = der.cnt;

    5、查詢優化器的提示

    如果對優化器選擇的執行計劃不滿意,可以使用優化器提供的幾個提示(hint)來控制最終執行計劃。具體用法可查閱MySQL官方手冊。

    6、優化特定類型的查詢

      優化count()查詢

    count()的作用:count()是一個特殊的聚合函數,有兩種非常不同的用法:統計某列值的數量;統計行數。在統計列值時,要求列值時非空的(不統計null)。如果count()括號中時某列或某列的表達式,則統計的是這個表達式有值的結果數。

    ?  優化關聯查詢

    • 確保ON或者USING子句中的列上有索引;
    • 確保任何GROUP BY 和 ORDER BY 中的表達式只涉及到一個表中的列,這樣MySQL才有可能利用索引來優化此過程;
    • 當升級MySQL的時候需要注意:關聯語法、運算符優先級等其他可能會發生變化的地方。

      優化子查詢

    子查詢盡可能使用關聯查詢代替。但如果時MySQL5.6或更新版本或MariaDB,可忽略關于子查詢的這些優化建議。

      優化GROUP BY 和DISTINCT

      優化LIMIT分頁

      優化UNION查詢

    MySQL總是通過創建并填充臨時表的方式來執行UNION查詢。因此很多優化策略在UNION中都沒法很好的使用,經常需要手動將WHERE、LIMIT、GROUP BY 等子句下推到UNION的各個子查詢中。

    注意:除非確實需要服務器消除重復行,否則一定要使用UNION All。因為如果沒有ALL關鍵字,MySQL會給臨時表加上DISTINCT選項,這會導致對臨時表的數據做唯一性檢查。

    ?

    轉載于:https://www.cnblogs.com/zhuxiong/p/8268504.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的高性能MySQL——查询性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。