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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql分页 disti_MySql查询性能优化

發(fā)布時間:2025/3/8 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql分页 disti_MySql查询性能优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

慢查詢判定

1.開啟慢查詢?nèi)罩居涗泩?zhí)行時間超過long_query_time 秒的sql語句

2.通過show processlist命令查看線程執(zhí)行狀態(tài)

3.通過explain解析sql了解執(zhí)行狀態(tài)

慢查詢優(yōu)化

是否向服務(wù)器請求列不必要的數(shù)據(jù)

查詢不需要的記錄(limit),多表關(guān)聯(lián)返回全部列,總是取出全部列和重復(fù)io等

是否走索引

建立索引的原則:

最左前綴匹配原則,mysql會一直向右匹配直到遇到范圍查詢(>、 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整

等值查詢(=和in)可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql查詢優(yōu)化器會優(yōu)化成索引為可識別的形式

模糊匹配like,“%”不能在第一個位置

選擇區(qū)分度高的列作為索引,區(qū)分度的公式是count(distinct col)/count(*),表示字段不重復(fù)的比例,比例越大掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是1

索引列不能是表達(dá)式的一部分或者是函數(shù)的參數(shù)

盡量的擴(kuò)展索引,不要新建索引。比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可

避免在where子句中對字段進(jìn)行NULL值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描

or改寫成in:or的效率是n級別,in的效率是log(n)級別,in的個數(shù)建議控制在200以內(nèi)

盡量避免在where子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描

對于連續(xù)數(shù)值,使用between不用in

查詢sql是否合理

切分查詢

分解關(guān)聯(lián)查詢

將一個大的查詢分解為多個小查詢是很有必要的。很多高性能的應(yīng)用都會對關(guān)聯(lián)查詢進(jìn)行分解,就是可以對每一個表進(jìn)行一次單表查詢,然后將查詢結(jié)果在應(yīng)用程序中進(jìn)行關(guān)聯(lián),很多場景下這樣會更高效

表結(jié)構(gòu)優(yōu)化

對于需要經(jīng)常聯(lián)合查詢的表,可以建立中間表以提高查詢效率

水平拆分

分區(qū)表

分庫分表

垂直拆分,將單個表字段分解為多個表字段(根據(jù)模塊的耦合度,拆分為分布式系統(tǒng))

查詢執(zhí)行路徑

客戶端/服務(wù)器通信

半雙工模式---- 任意時刻數(shù)據(jù)只能單向傳輸

查詢優(yōu)化器

mysql查詢優(yōu)化器會通過某種策略自動生成最優(yōu)的執(zhí)行計劃

重新定義關(guān)聯(lián)表的順序

數(shù)據(jù)表的關(guān)聯(lián)順序并不總是按照在查詢中指定的順序執(zhí)行

將外連接轉(zhuǎn)化為內(nèi)連接

并不是所有的OUTER JOIN操作都必須以外連接的方式執(zhí)行

使用等價變換規(guī)則

mysql會使用一些等價變換規(guī)則來優(yōu)化表達(dá)式

優(yōu)化COUNT()

MyISAM維護(hù)一個變量存放表的行數(shù), MIN() -- 查詢列對應(yīng)B+樹索引最左端記錄 ,MAX() -- 查詢列對應(yīng)B+樹索引最右端記錄

預(yù)估并轉(zhuǎn)化為常數(shù)表達(dá)式

覆蓋索引掃描

當(dāng)索引中的列包含列所有查詢需要返回的列時,mysql會自動使用覆蓋索引掃描而無需查詢對應(yīng)的數(shù)據(jù)行

子查詢優(yōu)化

提前終止查詢,如Limit

等值傳播

列表IN()的比較

在很多數(shù)據(jù)庫系統(tǒng)中,IN()完全等同于多個OR條件的子句,但是mysql會先將IN()列表中的數(shù)據(jù)進(jìn)行排序,然后通過二分查找來確定列表中的值是否滿足條件,O(log(n))復(fù)雜度操作,而如果轉(zhuǎn)換為OR則復(fù)雜度為O(n)

SQL執(zhí)行順序

FROM—>ON—>JOIN—>WHERE—>GROUP BY—>SUM(聚合函數(shù))—>HAVING—>SELECT—>DISTINCT—>UNION—>ORDER BY—>LIMIT

優(yōu)化特定類型查詢

優(yōu)化子查詢

MySql的子查詢實現(xiàn)非常糟糕,特別是where條件中包含IN()的子查詢性能通常會比較差,如

select * from film where film_id in (

select film_id from film_actor where film.film_id = 1

);

MySql查詢優(yōu)化器會將上面的查詢通過Exists改寫

select * from film where exists(

select * from film_actor where film.film_id = 1

and film.film_id = film_actor.film_id);

IN比較通過在內(nèi)存中遍歷,而exists走數(shù)據(jù)庫索引,所以當(dāng)子查詢中表的數(shù)據(jù)量比較大時exists效率優(yōu)于in

優(yōu)化子查詢最常見的建議就是盡可能使用關(guān)聯(lián)查詢代替

select film.* from film inner join film_actor using (film_id) where actor_id = 1;

優(yōu)化COUNT()

COUNT函數(shù)用于統(tǒng)計某個列值的數(shù)量或者行數(shù),統(tǒng)計列值時要求列值非空(不統(tǒng)計NULL)

優(yōu)化關(guān)聯(lián)查詢

確保ON或者USING子句的列上有索引。只需在關(guān)聯(lián)順序的第二個表上建立索引即可,如當(dāng)表A和表B用列c關(guān)聯(lián)的時候,如果優(yōu)化器的優(yōu)化順序為B,A,那么就不需要在表B上建立索引

確保任何的GROUP BY或者ORDER BY中的表達(dá)式只涉及到一個表中的列,這樣mysql才有可能使用索引來優(yōu)化這個過程

優(yōu)化GROUP BY和DISTINCT

當(dāng)無法使用索引時,GROUP BY會通過臨時表或者文件排序做排序

優(yōu)化limit分頁

limit操作在偏移量非常大的情況,mysql會掃描大量不需要的行然后拋棄掉導(dǎo)致效率降低

1.延遲關(guān)聯(lián):在關(guān)聯(lián)查詢中使用覆蓋索引掃描,獲取關(guān)聯(lián)字段后再根據(jù)關(guān)聯(lián)列回表查詢需要的所有列

SELECT film_id, description FROM film

INNER JOIN (

SELECT film_id

FROM film ORDER BY title LIMIT 10000, 10

) AS tmp USING (film_id);

2.取上次分頁查詢操作返回的主鍵ID作為下一次分頁查詢起始位置

SELECT film_id, description FROM film WHERE film_id > 10000 ORDER BY title LIMIT 10;

NULL值

空值是不占空間的,NULL是占空間的

聚合函數(shù),如COUNT(),MIN(),SUM()在進(jìn)行查詢時會忽略掉null值

查詢列不為NULL應(yīng)使用IS NOT NULL進(jìn)行查詢

條件查詢<>會過濾掉NULL值和空值

Explain

id:執(zhí)行編號,標(biāo)識select所屬的行。如果在語句中沒子查詢或關(guān)聯(lián)查詢,只有唯一的select,每行都將顯示1。否則,內(nèi)層的select語句一般會順序編號,對應(yīng)于其在原始語句中的位置

select_type: 顯示本行是簡單或復(fù)雜select。如果查詢有任何復(fù)雜的子查詢,則最外層標(biāo)記為PRIMARY(DERIVED、UNION、UNION RESUlT)

table: 訪問引用哪個表(引用某個查詢,如“derived3”)

type: 數(shù)據(jù)訪問讀取操作類型(ALL、index、range、ref、eq_ref、const/system、NULL)

possible_keys: 揭示哪一些索引可能有利于高效的查找

key: 顯示mysql決定采用哪個索引來優(yōu)化查詢

key_len: 顯示mysql在索引里使用的字節(jié)數(shù)

ref: 顯示了之前的表在key列記錄的索引中查找值所用的列或常量

rows: 為了找到所需的行而需要讀取的行數(shù),估算值,不精確。通過把所有rows列值相乘,可粗略估算整個查詢會檢查的行數(shù)

Extra: 額外信息,如using index、filesort等

select_type(查詢類型)

simple:簡單查詢,不包含子查詢和union

primary:查詢包含子查詢和union,最外層部分標(biāo)記為primary

derived:派生表,該臨時表是從子查詢中派生出來,位于from中的子查詢

union:union中第二個及以后的select,第一個union標(biāo)記為primary

union result:從匿名臨時表中檢索結(jié)果的select操作

dependent union:union中第二個或后面的select語句,取決于外層查詢

subquery:子查詢中第一個select

dependent subquery:子查詢中的第一個select,取決于外層查詢

type(訪問類型)

all:全表掃描

index:和全表掃描一樣,只是掃描表的順序是按照索引的順序,優(yōu)點(diǎn)是避免排序,但是開銷仍然非常大

range:范圍掃描,key列顯示使用哪個索引。當(dāng)使用如=,<>,>,>=,

ref:索引訪問,返回所有匹配的記錄,當(dāng)使用非唯一索引或者唯一索引非唯一前綴

eq_ref:最多只返回1條符合條件的記錄,使用唯一索引或者主鍵索引時

const/system:mysql能對查詢的某部分進(jìn)行優(yōu)化并將其轉(zhuǎn)化為一個常量

null:mysql能在優(yōu)化階段分解查詢語句,在執(zhí)行時不需訪問表或者索引

Extra

Using filesort: mysql會對結(jié)果使用外部索引排序,而不是按索引次序從表讀取行

Using temporary: mysql在對查詢結(jié)果排序時使用臨時表,常見于排序和分組查詢

Using index: 使用覆蓋索引掃描,直接從索引中過濾不需要的記錄并返回命中結(jié)果。這是在mysql服務(wù)器層完成的,但無需再回表查詢記錄

Using index condition:

Using where: mysql服務(wù)器將在存儲引擎檢索行后再進(jìn)行過濾

distinct: 優(yōu)化distinct操作,在找到第一匹配的元組后即停止找同樣值的動作

復(fù)制

主從復(fù)制

1.在主庫把數(shù)據(jù)更改記錄到二進(jìn)制文件中(Binary Log)

2.從庫將主庫上的日志復(fù)制到自己的中繼日志(Relay Log)上

3.從庫讀取中繼日志的事件,將其重放到從庫數(shù)據(jù)中

總結(jié)

以上是生活随笔為你收集整理的mysql分页 disti_MySql查询性能优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。