mysql 語句優化例項 MySQL 語句優化例項

2021-10-17 21:50:04 字數 2584 閱讀 5368

優化 limit 分頁

-- 執行耗時:1.379s

select * from vio_basic_domain_info limit 1000000,10;

處理分頁慢查詢的方式一般有以下幾種:

思路一:構造覆蓋索引

思路二:優化 offset

無法用上覆蓋索引,那麼重點是想辦法快速過濾掉前 100w 條資料。我們可以利用自增主鍵有序的條件,先查詢出第 1000001 條資料的 id 值,再往後查 10 行。

原理:先基於索引查詢出第 1000001 條資料對應的主鍵 id 的值,然後直接通過該 id 的值直接查詢該 id 後面的 10 條資料。

適用於主鍵 id 自增的場景,耗時:0.471s。

select * from vio_basic_domain_info where id >=(select id from vio_basic_domain_info order by id limit 1000000,1) limit 10;

方法三:「延遲關聯」

耗時:0.439s,延遲關聯適用於數量級較大的表。

這裡我們利用到了覆蓋索引+延遲關聯查詢,相當於先只查詢 id 列,利用覆蓋索引快速查到該頁的 10 條資料 id,然後再把返回的 10 條 id 拿到表中通過主鍵索引二次查詢。(表資料增速快的情況對該方法影響較小)

select * from vio_basic_domain_info inner join (select id from vio_basic_domain_info order by id limit 1000000,10) as mynew using(id);

排查索引沒起作用的情況

模糊查詢盡量避免用萬用字元'%'開頭,會導致資料庫引擎放棄索引進行全表掃瞄

-- 不走索引

select * from t where username like '%陳%'

-- 走索引

select * from t where username like '陳%'

盡量避免使用 not in,會導致引擎走全表掃瞄。建議用 not exists 代替

-- 不走索引

select * from t where name not in ('提莫','隊長');

-- 走索引

select * from t as t1 where not exists (select * from t as t2 where name in ('提莫','隊長') and t1.id = t2.id);

盡量避免使用 or,會導致資料庫引擎放棄索引進行全表掃瞄

select * from t where id = 1 or id = 3

-- 優化方式:可以用 union 代替 or。如下:

select * from t where id = 1

union

select * from t where id = 3

盡量避免進行 null 值的判斷,會導致資料庫引擎放棄索引進行全表掃瞄

select * from t where score is null

-- 優化方式:可以給字段新增預設值 0,對 0 值進行判斷。如下:

select * from t where score = 0

盡量避免在 where 條件中等號的左側進行表示式、函式操作,會導致資料庫引擎放棄索引進行全表掃瞄

可以將表示式、函式操作移動到等號右側。如下:

-- 全表掃瞄

select * from t where score/10 = 9

-- 走索引

select * from t where score = 10*9

當資料量大時,避免使用 where 1=1 的條件。通常為了方便拼裝查詢條件,我們會預設使用該條件,資料庫引擎會放棄索引進行全表掃瞄

select username, age, *** from t where 1=1

-- 優化方式:用**拼裝 sql 時進行判斷,沒 where 條件就去掉 where,有 where 條件就加 and。

查詢條件不能用 <> 或者 !=

使用索引列作為條件進行查詢時,需要避免使用<>或者!=等判斷條件。

如確實業務需要,使用到不等於符號,需要在重新評估索引建立,避免在此字段上建立索引,改由查詢條件中其他索引字段代替

where 條件僅包含復合索引非前導列

如:復合(聯合)索引包含 key_part1,key_part2,key_part3 三列,但 sql 語句沒有包含索引前置列"key_part1",按照 mysql 聯合索引的最左匹配原則,不會走聯合索引。

-- 不走索引

select col1 from table where key_part2=1 and key_part3=2

-- 走索引

select col1 from table where key_part1 =1 and key_part2=1 and key_part3=2

隱式型別轉換造成不使用索引

如下 sql 語句由於索引對列型別為 varchar,但給定的值為數值,涉及隱式型別轉換,造成不能正確走索引。

select col1 from table where col_varchar=123;

if語句例項優化

輸入兩個實數a b,按數值由小到大的順序輸出這三個數。以下為我初次編寫的 include intmain 聽過猴博士課程解析後了解了其實只需用1個if語句就可以搞定,而無需使用else語句補充,基本思路為先將兩個實數比較大小,若a大,則將a與b的數值交換 從而保證a總是最小的實數,故輸出時先輸出a,...

mysql語句優化原則 MySQL語句優化的原則

1 使用索引來更快地遍歷表。預設情況下建立的索引是非群集索引,但有時它並不是最佳的。在非群集索引下,資料在物理上隨機存放在資料頁上。合理的索引設計要建立在對各種查詢的分析和 上。一般來說 a.有大量重複值 且經常有範圍查詢 和order by group by發生的列,可考慮建立群集索引 b.經常同...

mysql語句優化原則 mysql語句優化原則

有時候發現資料量大的時候查詢起來效率就比較慢了,學習一下mysql語句優化的原則,自己在正常寫sql的時候還沒注意到這些,先記錄下來,慢慢一點一點的學,加油!這幾篇部落格寫的都可以 使用索引的原則 1.最左字首匹配原則。mysql會一直向右匹配直到遇到範圍查詢 不會用到b的索引 where a 1 ...