最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于MySQL查詢語句的優(yōu)化詳解

 更新時間:2023年04月20日 10:57:58   作者:EzreaLwj  
這篇文章主要介紹了MySQL查詢語句的優(yōu)化方法,分別介紹了子查詢優(yōu)化,分頁查詢優(yōu)化以及排序查詢優(yōu)化,對學(xué)習(xí)有一定的幫助,需要的小伙伴可以參考一下

MySQL 優(yōu)化

子查詢優(yōu)化

  • 將子查詢改變?yōu)楸磉B接,尤其是在子查詢的結(jié)果集較大的情況下;
  • 添加復(fù)合索引,其中復(fù)合索引的包含的字段應(yīng)該包括 where 字段與關(guān)聯(lián)字段;
  • 復(fù)合索引中的字段順序要遵守最左匹配原則;
  • MySQL 8 中自動對子查詢進(jìn)行優(yōu)化;

現(xiàn)有兩個表

create table Orders
(
    id         integer AUTO_INCREMENT PRIMARY KEY,
    name       varchar(255) not null,
    order_date datetime     NOT NULL
) comment '訂單表';

create table OrderDetails
(
    id           integer AUTO_INCREMENT PRIMARY KEY,
    order_id     integer     not null,
    product_code varchar(20) not null,
    quantity     integer     not null
) comment '訂單詳情表';

子查詢

select * from orders where id in (select order_id from OrderDetails where product_code = 'PC50');

優(yōu)化1:改為表連接

select * from orders as t1 inner join orderdetails o on t1.id = o.order_id where product_code='PC50';

優(yōu)化2:給 order_id 字段添加索引

優(yōu)化3:給 product_code 字段添加索引

結(jié)果證明:給 product_code 字段添加索引 的效果優(yōu)于給 order_id 字段添加索引,因為不用對索引列進(jìn)行全表掃描

優(yōu)化4:給 order_id 和 product_code 添加復(fù)合索引

優(yōu)化5:給 product_code 和 order_id 添加復(fù)合索引

對于復(fù)合索引 idx(order_id, product_code),因為查詢中需要判斷 product_code 的值是否為 PC51,所以要對 order_id 該列進(jìn)行全索引掃描,性能較低 [ 因為 product_code 不是有序的,先根據(jù) order_id 進(jìn)行排序,再根據(jù) product_code 進(jìn)行排序 ];

對于復(fù)合索引 idx(product_code, order_id) ,因為 product_code 本身是有序的,所以可以快速定位到該 product_code 然后快速獲取該 order_id,性能較高;

待排序的分頁查詢的優(yōu)化

現(xiàn)有一個電影表

create table film
(
    id           integer auto_increment primary key,
    score        decimal(2, 1) not null,
    release_date date          not null,
    film_name    varchar(255)  not null,
    introduction varchar(255)  not null
) comment '電影表';

對于淺分頁

select score, release_date, film_name from film order by score limit 0, 20;

耗時 825ms

對于深分頁

select score, release_date, film_name, introduction from film order by score limit 1500000, 20;

耗時 1s 247ms

若不加處理,淺分頁的速度快,limit 的深度越深,查詢的效率越慢

給排序字段添加索引

給 score 字段添加索引

create index idx_score on film(score);

結(jié)果

淺分頁的速度為 60 ms,深分頁的速度為 1s 134ms

淺分頁的情況得到了優(yōu)化,而深分頁依然很慢

查看深分頁的執(zhí)行情況

其并沒有走 score 索引,走的是全表的掃描,所以給排序字段添加索引只能優(yōu)化淺分頁的情況

解釋

只給 score 添加索引,會造成回表的情況

對于淺分頁,回表的性能消耗小于全表掃描,故走 score 索引;

對于深分頁,回表的性能消耗大于全表掃描,故走 全表掃描;

給排序字段跟 select 字段添加復(fù)合索引

給 score, release_date, film_name 添加復(fù)合索引

create index idx_score_date_name on film(score, release_date, film_name);

淺分頁的速度為 58 ms,深分頁的速度為 357 ms,兩者的速度都得到了提升

查看深分頁的執(zhí)行情況

可見其走了復(fù)合索引

解釋

對于該復(fù)合索引,排序的值和查詢的值都在索引上,沒有進(jìn)行回表的操作,效率很高。唯一的不足是:若要添加新的查詢列,就要更改該索引的列,不夠靈活

給排序字段加索引 + 手動回表

改進(jìn)SQL語句,給 score 字段添加索引

# 給排序字段添加索引 + 手動回表
select score, release_date, film_name,introduction from  film a
join (select id from film order by score limit 1500000, 20) b
on  a.id = b.id;

思路:先把 limit 字段的 id 找出來,這里走了 score 索引,效率高。然后再走主鍵索引根據(jù) id 去尋找;

該語句的執(zhí)行情況

可見子查詢中走了 score 索引,而外查詢走了主鍵索引,效率非常高,執(zhí)行速度為 297 ms

缺點

由上面的執(zhí)行計劃可見,它創(chuàng)建了一張中間表 ,走的是全表掃描,也就是說,中間表中的記錄越多,該執(zhí)行效率就越慢,觀察以下語句,從500000開始查,查找 1500000 條數(shù)據(jù);

select score, release_date, film_name,introduction from  film a
join (select id from film order by score limit  500000, 1500000) b
on  a.id = b.id;

消耗的時間為:911ms,接近一秒

所以我們可以通過業(yè)務(wù)的方法,限制每次查詢的條數(shù)即可

解決辦法

  • 給排序的字段 + select 的字段添加復(fù)合索引
  • 給排序的字段加索引 + 手動回表
  • 深分頁的性能問題可以通過業(yè)務(wù)方法解決:限制每次查詢的數(shù)量等

排序優(yōu)化

索引的字段要根據(jù)排序的字段走,且要滿足最左匹配原則

create table t_order (
    id integer primary key auto_increment,
    col_1 int not null ,
    col_2 int not null ,
    col_3 int not null 
)

select * from t_order order by col_1, col_2, col_3, 需要創(chuàng)建聯(lián)合索引 col_1,col_2,col_3

select * from t_order order by col_1, col_2,需要創(chuàng)建聯(lián)合索引 col_1, col_2, col_3

select * from t_order order by col_1 asc, col_2 desc ,需要創(chuàng)建聯(lián)合索引 col_1 asc, col_2 desc ,指定索引的排序規(guī)則,只有在 MySQL 8 中才支持

索引失效的情況(避免出現(xiàn) using filesort)

  • 沒有遵守最左匹配原則

select * from t_order order by col_1, col_3

select * from t_order order by col_2, col_3

可見都使用到了 ****using filesort

以第一條為例

最左匹配原則的實質(zhì)是:先根據(jù)第一列排序,若第一列的值相同就根據(jù)第二列來排序,若第二列的值相同就根據(jù)第三列來排序,以此類推;

第一條 SQL 中,排序的字段為 col_2 和 col_3 明顯 在拋開 col_1 的情況下,col_2 和 col_3 的順序是無序的,故要使用 using filesort,不能依靠索引來進(jìn)行排序;

  • 使用了范圍查詢

select * from t_order where col1 >= 1 and col1 <= 4 order by col_2

select * from t_order where col1 in(1,2,4) order by col_2

若走該復(fù)合索引 (col_1, col_2, col_3) ,可以發(fā)現(xiàn)查詢計劃中使用到了 using filesort

解釋

經(jīng)過 col_1 的篩選后,col_2 的數(shù)據(jù)都是無序的

所以要使用 using filesort 再次根據(jù) col_2 排序

若使用等值查詢,則不會出現(xiàn) using filesort,前提是要滿足最左匹配原則

select col_1, col_2 from t_order where col_1 = 2 order by col_2;

若不滿足 最左匹配原則

select col_1, col_3 from t_order where col_1 = 2 order by col_3;

則使用到了 using filesort

以上就是關(guān)于MySQL查詢語句的優(yōu)化詳解的詳細(xì)內(nèi)容,更多關(guān)于MySQL查詢語句優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL按年/月/周/日/小時分組查詢、排序、limit及判空用法實例

    MySQL按年/月/周/日/小時分組查詢、排序、limit及判空用法實例

    我們在用Mysql抽取數(shù)據(jù)時候,經(jīng)常需要按照天、周、月等不同的粒度對數(shù)據(jù)進(jìn)行分組統(tǒng)計,下面這篇文章主要給大家介紹了關(guān)于MySQL按年/月/周/日/小時分組查詢、排序、limit及判空用法的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • 詳解Navicat遠(yuǎn)程連接mysql很慢

    詳解Navicat遠(yuǎn)程連接mysql很慢

    這篇文章主要介紹了詳解Navicat遠(yuǎn)程連接mysql很慢(以及數(shù)據(jù)庫連接報錯"Too many connections")解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • MySQL函數(shù)大全及用法示例分享

    MySQL函數(shù)大全及用法示例分享

    這篇文章主要介紹了MySQL的一些函數(shù)及用法示例,需要的朋友可以參考下
    2014-03-03
  • 淺談mysql一張表到底能存多少數(shù)據(jù)

    淺談mysql一張表到底能存多少數(shù)據(jù)

    這篇文章主要介紹了淺談mysql一張表到底能存多少數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 如何修改MYSQL5.7.17數(shù)據(jù)庫存儲文件的路徑

    如何修改MYSQL5.7.17數(shù)據(jù)庫存儲文件的路徑

    在搭建華為云服務(wù)器的時候遇到點問題,查看了網(wǎng)上好多的帖子都沒能解決,不知道有沒有跟我遇到一樣問題的老鐵,我就把我的解決辦法分享給大家,希望能夠幫助各位老鐵
    2023-05-05
  • 淺析一個MYSQL語法(在查詢中使用count)的兼容性問題

    淺析一個MYSQL語法(在查詢中使用count)的兼容性問題

    本篇文章是對MYSQL語法(在查詢中使用count)的兼容性問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • mysql安裝忘記初始密碼簡單有效的解決方法

    mysql安裝忘記初始密碼簡單有效的解決方法

    在本篇文章里小編給大家整理的是一篇關(guān)于mysql安裝忘記初始密碼簡單有效的解決方法,有需要的朋友們參考學(xué)習(xí)下。
    2020-01-01
  • mysql修改密碼的三方法和忘記root密碼的解決方法

    mysql修改密碼的三方法和忘記root密碼的解決方法

    這篇文章主要介紹了mysql修改密碼的三方法和忘記root密碼的解決方法,需要的朋友可以參考下
    2014-02-02
  • 區(qū)分MySQL中的空值(null)和空字符('''')

    區(qū)分MySQL中的空值(null)和空字符('''')

    這篇文章主要介紹了如何區(qū)分MySQL中的空值(null)和空字符(''),幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2020-09-09
  • MySQL 數(shù)據(jù)類型 詳解

    MySQL 數(shù)據(jù)類型 詳解

    MySQL 的數(shù)值數(shù)據(jù)類型可以大致劃分為兩個類別,一個是整數(shù),另一個是浮點數(shù)或小數(shù)。許多不同的子類型對這些類別中的每一個都是可用的,每個子類型支持不同大小的數(shù)據(jù),并且 MySQL 允許我們指定數(shù)值字段中的值是否有正負(fù)之分或者用零填補(bǔ)。
    2009-10-10

最新評論

秭归县| 鄂托克前旗| 博兴县| 乡城县| 新沂市| 钟山县| 博乐市| 德令哈市| 台中县| 轮台县| 札达县| 岐山县| 福泉市| 北海市| 重庆市| 拉萨市| 康保县| 洛扎县| 连云港市| 嘉定区| 金塔县| 广水市| 焉耆| 东光县| 贡觉县| 如东县| 从江县| 兴化市| 大邑县| 辽阳市| 岳阳县| 博湖县| 嫩江县| 邵阳县| 留坝县| 泰宁县| 平塘县| 澄城县| 大宁县| 芜湖县| 株洲市|