慢查詢實操

2021-10-25 03:58:46 字數 3099 閱讀 2078

面試的時候問的多了,實操經驗太少了,沒有底氣,這裡具體的做一次

在my.ini中新增幾行

//定義查詢多少秒的查詢算是慢查詢

long_query_time=2

//配置慢查詢記錄檔案

slow-query-log=on

slow_query_log_file=「msql_slow_query_log」

//記錄下沒有使用索引的query

log-query-not-using-indexes

或者通過mysql資料庫開啟慢查詢

直接分析mysql慢查詢日誌 ,利用explain關鍵字可以模擬優化器執行sql查詢語句,來分析sql慢查詢語句

select_type:所使用的的查詢型別

(1)dependent subquery:子查詢內層的第乙個select,依賴於外部查詢的結果集。

(2)dependent union:子查詢中的union,且為union中從第二個select開始的後面所有select,同樣依賴於外部查詢的結果集。

(3)primary:子查詢中的最外層查詢,注意並不是主鍵查詢。

(4)******:除子查詢或union之外的其他查詢。

(5)subquery:子查詢內層查詢的第乙個select,結果不依賴於外部查詢結果集。

(6)uncacheable subquery:結果集無法快取的子查詢。

(7)union:union語句中第二個select開始後面的所有select,第乙個select為primary。

(8)union result:union 中的合併結果。

table:顯示這一步所訪問的資料庫中的表的名稱

partitions:分割槽表命中的分割槽情況。非分割槽表該字段為空(null)。

type:對錶使用的訪問方式

1)all:全表掃瞄。

(2)const:讀常量,最多隻會有一條記錄匹配,由於是常量,實際上只須要讀一次。

(3)eq_ref:最多隻會有一條匹配結果,一般是通過主鍵或唯一鍵索引來訪問。

(4)fulltext:進行全文索引檢索。

(5)index:全索引掃瞄。

(6)index_merge:查詢中同時使用兩個(或更多)索引,然後對索引結果進行合併(merge),再讀取表資料。

(7)index_subquery:子查詢中的返回結果字段組合是乙個索引(或索引組合),但不是乙個主鍵或唯一索引。

(8)rang:索引範圍掃瞄。

(9)ref:join語句中被驅動表索引引用的查詢。

(10)ref_or_null:與ref的唯一區別就是在使用索引引用的查詢之外再增加乙個空值的查詢。

(11)system:系統表,表中只有一行資料。

(12)unique_subquery:子查詢中的返回結果字段組合是主鍵或唯一約束。

possible_keys:該查詢可以利用的索引,用來優化很重要!!!

key:選擇使用的索引

key_len:被選中使用索引的索引鍵長度

ref:列出是通過常量(const),還是某個表的某個字段(如果是join)來過濾(通過key)的。

rows:通過系統收集的統計資訊估算出來的結果集記錄條數。

filtered:表示儲存引擎返回的資料在server層過濾後,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數。

extra:查詢中每一步實現的額外細節

索引沒起作用的情況

優化資料庫結構

分解關聯查詢

將乙個大的查詢分解為多個小查詢是很有必要的。很多高效能的應用都會對關聯查詢進行分解,就是可以對每乙個表進行一次單錶查詢,然後將查詢結果在應用程式中進行關聯,很多場景下這樣會更高效

select * from tag

join tag_post on tag_id = tag.id

join post on tag_post.post_id = post.id

where tag.tag = 『mysql』;

分解為:

select * from tag where tag = 『mysql』;

select * from tag_post where tag_id = 1234;

select * from post where post.id in (123,456,567);

優化limit分頁

在系統中需要分頁的操作通常會使用limit加上偏移量的方法實現,同時加上合適的order by 子句。如果有對應的索引,通常效率會不錯,否則mysql需要做大量的檔案排序操作。

偏移量太大的話,查詢100020條記錄,但是只要20條,前面的都不要,代價太高,優化方法最簡單的就是盡可能使用索引覆蓋,而不是查詢所有的列

對於下列的查詢: select id,title from collect limit 90000,10;

該語句存在的最大問題在於limit m,n中偏移量m太大(我們暫不考慮篩選欄位上要不要新增索引的影響),導致每次查詢都要先從整個表中找到滿足條件 的前m條記錄,之後捨棄這m條記錄並從第m+1條記錄開始再依次找到n條滿足條件的記錄。如果表非常大,且篩選字段沒有合適的索引,且m特別大那麼這樣的代價是非常高的。 試想,如我們下一次的查詢能從前一次查詢結束後標記的位置開始查詢,找到滿足條件的100條記錄,並記下下一次查詢應該開始的位置,以便於下一次查詢能直接從該位置 開始,這樣就不必每次查詢都先從整個表中先找到滿足條件的前m條記錄,捨棄,在從m+1開始再找到100條滿足條件的記錄了。

我覺得比較好的方法有

關聯延遲: select news.id, news.description from news inner join (select id from news order by title limit 50000,5) as mynew using(id);

建立復合索引:select * from acct_trans_log where acct_id = 3095 order by create_time desc limit 0,10

分析具體的sql語句

Ubuntu 18 04 啟動慢處理 小白實操記錄

檢查誰在搞鬼 systemd analyze blame第一項為開機動畫,用 mask 乾掉 要恢復使用 unmask sudo systemctl mask plymouth quit wait.service第二項,延遲 apt daily 服務 sudo systemctl edit apt ...

mysql分割槽實操

分成2步 2.將原表資料插入新錶 insert into 目標表 select from 表 create table met shopv2 order copy1 id int 11 not null auto increment,orderid varchar 20 character set ...

redis備份實操

終於發布了個人的第乙個課程 redis備份實操,位址 1 不能搞出問題 虛擬機器測試環境不擔心這個啊 2 任務得在夜間進行 白天業務高峰期,不適合做維護 3 必須考慮可用性,得把資料備份到其他的系統上。我的搞法是 1 準備乙個資料校驗環境,安裝上redis,用於備份檔案匯入。通過對比生產環境redi...