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

歡迎訪問 生活随笔!

生活随笔

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

数据库

MySQL 优化 —— WHERE 子句优化

發布時間:2025/3/12 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL 优化 —— WHERE 子句优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

本文翻譯自 MySQL 官網:WHERE Clause Optimization

WHERE 子句優化

這一部分我們來討論對 WHERE 子句的優化處理。本部分的案例都是以 SELECT 語句為例,但這些優化同樣適用于 DELETE 和 UPDATE 語句中的 WHERE 子句。

注意

因為對 MySQL 優化器的工作一直在進行,因此并不是全部的MySQL執行優化都在本文檔中說明。

你可能想重寫你的查詢以使它在算法操作上執行的更快,同時犧牲一定的可讀性。但你通??梢圆槐剡@么費勁,因為MySQL 會自動進行類似的優化,同時保留查詢的可讀性和可維護性。下面一些是MySQL自己的優化:

  • 移除不必要的圓括號
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
  • 常量合并
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
  • 常量條件刪除
(b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=7 AND 5=6) -> b=5 OR b=6
  • 被索引使用的常量表達式只會計算一次
  • 單表的 COUNT(*) ,在沒有 WHERE 子句的情況下可以直接從表信息中獲得,但只針對 MyISAM 和 MEMORY 存儲引擎。對于僅與一個表一起使用的任何NOT NULL表達式,也可以這樣做。
  • 早期檢測無效的常量表達式。MySQL 會快速地檢測到一些根本不可能的 SELECT 語句,并直接返回空的結果集。
  • 如果你不使用 GROUP BY 或聚合函數(COUNT(),MIN()等),HAVING 子句會被合并到 WHERE 中。
  • 對于連接中的每張表,MySQL會構建更簡單的 WHERE ,以此來獲取每張表的快捷 WHERE 子句處理,同時盡可能快的跳過記錄。
  • 所有的常量表會先于其他表的查詢。下面所列都是常量表(其實博主認為這里應該翻譯為“常量查詢”更恰當一些):
  • 空表或只有一條記錄的表。
  • 使用了 primary key?或者 unique key 作為 WHERE 查詢條件的查詢,并且條件都是等值判斷,且所有索引列都是定義為非空的。(博主:因為主鍵、唯一鍵都可能是多列復合,所以這里要求每個索引列都必須的非空)。下面的表都被視為常量表:
  • SELECT * FROM t WHERE primary_key=1; SELECT * FROM t1,t2WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
    • 通過嘗試所有可能性,可以找到連接表的最佳連接組合。如果所有的 ORDER BY 和 GROUP BY子句中的字段都來自同一個表,那么這個表在連接時就作為第一張表。
    • 如果有一個 ORDER BY 子句和一個不同的 GROUP BY 子句,或者?ORDER BY 或 GROUP BY 包含的列不屬于連接隊列中的第一張表,那么MySQL就會建立一張臨時表。
    • 如果你使用 SQL_SMALL_RESULT 修飾符,MySQL 會使用一張內存中的臨時表。
    • 每張表的索引都會被查詢,并會使用最優索引,除非MySQL優化器認為全表掃描比用索引更高效。曾經,掃描的使用基于是否最優索引覆蓋超過了表數據的 30 % ,但是,固定的百分比不再作為使用索引或掃描的決定因素。如今的優化器更加復雜,它對優化的計算基于更多額外的因素,比如表的大小,記錄的數量,以及 IO 塊的大小。?
    • 有些情況,MySQL 甚至不需要訪問數據文件就可以從索引中讀取記錄。如果索引中所有的列都是數值型的,那么只用索引樹就可以完成查詢。
    • 每條記錄輸出之前,那些不匹配 HAVING 子句條件的記錄會被跳過。

    下面一些查詢例子都是非??焖俚?#xff1a;

    SELECT COUNT(*) FROM tbl_name;SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;SELECT MAX(key_part2) FROM tbl_nameWHERE key_part1=constant;SELECT ... FROM tbl_nameORDER BY key_part1,key_part2,... LIMIT 10;SELECT ... FROM tbl_nameORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;

    下面的查詢,MySQL只會用到索引樹,假設創建了索引的列都是數值型的:

    SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;SELECT COUNT(*) FROM tbl_nameWHERE key_part1=val1 AND key_part2=val2;SELECT key_part2 FROM tbl_name GROUP BY key_part1;

    以下查詢使用索引來檢索排序的行,而不需要單獨的排序傳遞:

    SELECT ... FROM tbl_nameORDER BY key_part1,key_part2,... ;SELECT ... FROM tbl_nameORDER BY key_part1 DESC, key_part2 DESC, ... ;

    總結

    從本文可以看出,MySQL官方給出了一些 MySQL 優化器內部對于查詢的優化處理,對于開發者的優化建議雖然沒有明確指出,但是我們可以通過分析這些來自優化器內部的操作來定制我們的SQL查詢。這些知識可以作為我們日后采取更具體優化措施的原理基礎。

    總結

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

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