高性能mysql(6)-查詢優(yōu)化

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

1.1優(yōu)化count()查詢

count(),是一個(gè)特殊的函數(shù),它可以統(tǒng)計(jì)列值得數(shù)量,也可以統(tǒng)計(jì)行數(shù)。在統(tǒng)計(jì)列值時(shí)要求列值不能為null。
當(dāng)我們想要統(tǒng)計(jì)結(jié)果集的行數(shù)的時(shí)候直接使用count(*),語(yǔ)義清晰,性能也更好。
在MyISAM引擎中在沒(méi)有任何條where件下的count( *)的速度是非常快的,它無(wú)需計(jì)算行數(shù),可以直接捕獲這個(gè)值。但是當(dāng)有where條件的時(shí)候就和其他引擎沒(méi)有任何的區(qū)別了。

  • 在MyISAM下的簡(jiǎn)單優(yōu)化
    例如,查詢所有film_id大于5的數(shù)據(jù)行數(shù)。
explain select count(*) from film where film_id>5;
圖片.png

此時(shí)掃面了30行數(shù)據(jù)。

EXPLAIN SELECT
    (SELECT count(*) FROM film) - count(*)
FROM
    film
WHERE
    film_id <= 5;

圖片.png

現(xiàn)在只掃描了6行?。。?/p>

  • 統(tǒng)計(jì)同一列中不同值得數(shù)量
select count(color='red' or null) as red ,count(color='blue' or null)as blue from testcolor;
select sum(color='red') as red ,sum(color='blue')as blue from testcolor;
  • 使用近似值
    有時(shí)候我們統(tǒng)計(jì)數(shù)量的時(shí)候沒(méi)有必要非常的精確,可以使用近似的值代替,但是卻要比精確查詢快很多。

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

  • 確保在on或者using子句的列上有索引,在創(chuàng)建索引的時(shí)候需要考慮到關(guān)聯(lián)的順序,當(dāng)表A和表B用列c關(guān)聯(lián)的時(shí)候,如果優(yōu)化器關(guān)聯(lián)的順序是B,A那么沒(méi)有必要在B表對(duì)應(yīng)的列上創(chuàng)建索引,一般來(lái)說(shuō),沒(méi)有其他的理由,只需要在關(guān)聯(lián)順序中的第二個(gè)表上相應(yīng)的列創(chuàng)建索引。
  • 確保分組和排序中的表達(dá)式只涉及到一個(gè)表中的列。

1.3優(yōu)化子查詢

在mysql5.6版本之前盡量使用關(guān)聯(lián)查詢代替子查詢,但是這并不是絕對(duì)的。

1.4優(yōu)化limit

對(duì)于limit,應(yīng)當(dāng)盡量使用“延遲關(guān)聯(lián)”,盡量掃描少的頁(yè)?;蛘咴诔绦蛑杏涗浬弦豁?yè),下一次分頁(yè)的時(shí)候從記錄開(kāi)始。

1.5優(yōu)化union

mysql總是通過(guò)創(chuàng)建并填充臨時(shí)表的方式執(zhí)行union查詢,除非確實(shí)要消除重復(fù)的行,否則一定要使用union all ,否則mysql會(huì)給臨時(shí)表加上distinct關(guān)鍵字,對(duì)臨時(shí)數(shù)據(jù)做唯一性檢查,這樣的代價(jià)是非常高的。

  • 特殊的union查詢
    一個(gè)union查詢,第一個(gè)子查詢先執(zhí)行,第二個(gè)子查詢后執(zhí)行,如果第一個(gè)查詢命中,則不執(zhí)行第二個(gè)子查詢,否則執(zhí)行第二個(gè)查詢。
select  greatest(@found :=-1,id) as id ,'users' as which_tab1
from users where id=1
union all 
select id from users_archived where id=1 and @found is NULL
union all 
select 1 from dual where (@found :=null) is null;

1.6自定義變量

  • 自定義變量做排名語(yǔ)句
select actor_id ,count(*) as cnt
from film
group by actor_id
order by cnt desc;
set @curr_cnt :=0,@prev_cnt :=0,@rank :=0;
select actor_id,
@curr_cnt :=cnt as cnt,
@rank :=if(@prev_cnt<>@curr_cnt ,@rank+1,@rank ) as rank,
@prev_cnt :=@curr_cnt as dummy
from (
select actor_id, count(*) as cnt from film
group by actor_id
order by cnt desc
)as der;

-避免重復(fù)查詢剛剛更新數(shù)據(jù)

update t1 set lastUpdate=now() where id=1;
select lastUpdate from t1 where id =1;

改寫(xiě)

update t1 set lastUpdate=now() where id=1 and @now :=now();
select @now;

無(wú)需訪問(wèn)表就可以拿到數(shù)據(jù)會(huì)快很多。
但是在使用用戶自定義變量的時(shí)候要注意取值的順序。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 國(guó)慶第二天,今天嗨翻模式的開(kāi)啟就等室友的同學(xué)來(lái)了再說(shuō)吧,在這之前,先來(lái)一波筆記 查詢真正重要的是響應(yīng)時(shí)間,查詢包含...
    小煉君閱讀 1,735評(píng)論 0 50
  • 一、MySQL 數(shù)據(jù)庫(kù)性能優(yōu)化之SQL優(yōu)化(載錄于:http://lib.csdn.net/article/mys...
    yuantao123434閱讀 4,545評(píng)論 1 24
  • 引子 對(duì)于一條SQL,開(kāi)發(fā)同學(xué)最先關(guān)心的啥? 我覺(jué)得還不到這個(gè)SQL在數(shù)據(jù)庫(kù)的執(zhí)行過(guò)程,而是這條SQL是否能盡快的...
    大頭8086閱讀 2,648評(píng)論 2 14
  • 轉(zhuǎn)自:http://blog.csdn.net/lemon89/article/details/50193891 ...
    ywhu閱讀 660評(píng)論 0 1
  • 觀察:9點(diǎn)通知10點(diǎn)召開(kāi)大公益YY討論會(huì),10點(diǎn)進(jìn)YY發(fā)現(xiàn)只有幾個(gè)人在YY、我觀注了三十分鐘,去忙手里的工作,11...
    陳誠(chéng)chen閱讀 139評(píng)論 0 0