中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

南寧網(wǎng)站建設(shè) 南寧聯(lián)達(dá)億seo優(yōu)化網(wǎng)站源碼

南寧網(wǎng)站建設(shè) 南寧聯(lián)達(dá)億,seo優(yōu)化網(wǎng)站源碼,網(wǎng)絡(luò)營(yíng)銷模式的優(yōu)缺點(diǎn)分析,熊bear wordpress數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)的三范式是什么drop、delete、truncate 分別在什么場(chǎng)景之下使用char 和 varchar 的區(qū)別是什么數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖是什么SQL 約束有哪幾種mysql 的內(nèi)連接、左連接、右連接有什么區(qū)別MyIASM和Innodb兩種引擎所使用的索引的數(shù)據(jù)結(jié)構(gòu)是什么mysql 有關(guān)權(quán)限的表都有哪…

數(shù)據(jù)庫(kù)

  • 數(shù)據(jù)庫(kù)的三范式是什么
  • drop、delete、truncate 分別在什么場(chǎng)景之下使用
  • char 和 varchar 的區(qū)別是什么
  • 數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖是什么
  • SQL 約束有哪幾種
  • mysql 的內(nèi)連接、左連接、右連接有什么區(qū)別
  • MyIASM和Innodb兩種引擎所使用的索引的數(shù)據(jù)結(jié)構(gòu)是什么
  • mysql 有關(guān)權(quán)限的表都有哪幾個(gè)
  • MySQL中InnoDB引擎的行鎖是通過(guò)加在什么上完成
  • Oracle和Mysql的區(qū)別
  • MyISAM和InnoDB區(qū)別
  • 索引相關(guān)問(wèn)題
  • 事務(wù)相關(guān)問(wèn)題
  • SQL語(yǔ)句在MySQL中如何執(zhí)行
  • SQL 優(yōu)化

數(shù)據(jù)庫(kù)的三范式是什么

  • 第一范式:列不可再分
  • 第二范式:屬性完全依賴于主鍵
  • 第三范式:任何非主屬性不依賴于其它非主屬性

drop、delete、truncate 分別在什么場(chǎng)景之下使用

  • 不再需要一張表的時(shí)候,用drop
  • 想刪除部分?jǐn)?shù)據(jù)行時(shí)候,用delete,并且?guī)蟱here子句
  • 保留表而刪除所有數(shù)據(jù)的時(shí)候用truncate

char 和 varchar 的區(qū)別是什么

Char是一種固定長(zhǎng)度的類型,varchar是一種可變長(zhǎng)度的類型

數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖是什么

  • 悲觀鎖:假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作
    • 在查詢完數(shù)據(jù)的時(shí)候就把事務(wù)鎖起來(lái),直到提交事務(wù)
    • 實(shí)現(xiàn)方式:使用數(shù)據(jù)庫(kù)中的鎖機(jī)制

在這里插入圖片描述

  • 樂(lè)觀鎖:假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。
    • 在修改數(shù)據(jù)的時(shí)候把事務(wù)鎖起來(lái),通過(guò)version的方式來(lái)進(jìn)行鎖定
    • 實(shí)現(xiàn)方式:使用version版本或者時(shí)間戳

在這里插入圖片描述

SQL 約束有哪幾種

  • 主鍵約束(非空,唯一)
  • 外鍵約束(外鍵字段必須引用于主鍵字段,被引用的表稱為主表,引用的表稱為從表)
  • 唯一約束
  • 非空約束
  • 檢查約束

mysql 的內(nèi)連接、左連接、右連接有什么區(qū)別

  1. 內(nèi)連接:顯示兩個(gè)表中有聯(lián)系的所有數(shù)據(jù)
  2. 左鏈接:以左表為參照,顯示左邊所有數(shù)據(jù),右表中沒(méi)有則以null顯示
  3. 右鏈接:以右表為參照,顯示右邊所有數(shù)據(jù),左表中沒(méi)有則以null顯示

MyIASM和Innodb兩種引擎所使用的索引的數(shù)據(jù)結(jié)構(gòu)是什么

都是B+樹(shù)

MyIASM引擎,B+樹(shù)的數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)的內(nèi)容實(shí)際上是實(shí)際數(shù)據(jù)的地址值。也就是說(shuō)它的索引和實(shí)際數(shù)據(jù)是分開(kāi)的,只不過(guò)使用索引指向了實(shí)際數(shù)據(jù)。這種索引的模式被稱為非聚集索引。

Innodb引擎的索引的數(shù)據(jù)結(jié)構(gòu)也是B+樹(shù),只不過(guò)數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)的都是實(shí)際的數(shù)據(jù),這種索引有被稱為聚集索引。

mysql 有關(guān)權(quán)限的表都有哪幾個(gè)

  • user權(quán)限表:記錄允許連接到服務(wù)器的用戶帳號(hào)信息,里面的權(quán)限是全局級(jí)的。
  • db權(quán)限表:記錄各個(gè)帳號(hào)在各個(gè)數(shù)據(jù)庫(kù)上的操作權(quán)限。
  • table_priv權(quán)限表:記錄數(shù)據(jù)表級(jí)的操作權(quán)限。
  • columns_priv權(quán)限表:記錄數(shù)據(jù)列級(jí)的操作權(quán)限。
  • host權(quán)限表:配合db權(quán)限表對(duì)給定主機(jī)上數(shù)據(jù)庫(kù)級(jí)操作權(quán)限作更細(xì)致的控制。這個(gè)權(quán)限表不受GRANT和REVOKE語(yǔ)句的影響。

MySQL中InnoDB引擎的行鎖是通過(guò)加在什么上完成

InnoDB是基于索引來(lái)完成行鎖

Oracle和Mysql的區(qū)別

在Mysql中,一個(gè)用戶下可以創(chuàng)建多個(gè)庫(kù):

在這里插入圖片描述
而在Oracle中,Oracle服務(wù)器是由兩部分組成

  • 數(shù)據(jù)庫(kù)實(shí)例【理解為對(duì)象,看不見(jiàn)的】
  • 數(shù)據(jù)庫(kù)【理解為類,看得見(jiàn)的】

一個(gè)數(shù)據(jù)庫(kù)實(shí)例可擁有多個(gè)用戶,一個(gè)用戶默認(rèn)擁有一個(gè)表空間。表空間是存儲(chǔ)我們數(shù)據(jù)庫(kù)表的地方,表空間內(nèi)可以有多個(gè)文件。

在這里插入圖片描述

當(dāng)我們使用Oracle作為我們數(shù)據(jù)庫(kù)時(shí),我們需要指定用戶、表空間來(lái)存儲(chǔ)我們所需要的數(shù)據(jù)!

MyISAM和InnoDB區(qū)別

MyISAM是MySQL的默認(rèn)數(shù)據(jù)庫(kù)引擎(5.5版之前)。5.5版本之后,MySQL引入了InnoDB(事務(wù)性數(shù)據(jù)庫(kù)引擎),MySQL5.5版本后默認(rèn)的存儲(chǔ)引擎為InnoDB。

  1. 是否支持行級(jí)鎖: MyISAM 只有表級(jí)鎖,InnoDB 支持行級(jí)鎖和表級(jí)鎖,默認(rèn)為行級(jí)鎖。
  2. 是否支持事務(wù)和崩潰后的安全恢復(fù): MyISAM 強(qiáng)調(diào)的是性能,每次查詢具有原子性,其執(zhí)行速度比InnoDB類型更快,但是不提供事務(wù)支持。但是InnoDB 提供事務(wù)支持事務(wù),外部鍵等高級(jí)數(shù)據(jù)庫(kù)能。 是具有事務(wù)、回滾和崩潰修復(fù)能力的事務(wù)安全型表。
  3. 是否支持外鍵: MyISAM不支持,InnoDB支持。
  4. 是否支持MVCC :僅 InnoDB 支持。MVCC意思為多版本并發(fā)控制,應(yīng)對(duì)高并發(fā)事務(wù),MVCC比單純的加鎖更?效,MVCC只在讀已提交(RC) 和 可重復(fù)讀(RR) 兩個(gè)隔離級(jí)別下工作。用更好的方式去處理讀寫沖突。

索引相關(guān)問(wèn)題

https://blog.csdn.net/yy139926/article/details/124443946

事務(wù)相關(guān)問(wèn)題

https://blog.csdn.net/yy139926/article/details/124582264

SQL語(yǔ)句在MySQL中如何執(zhí)行

請(qǐng)?zhí)砑訄D片描述

  1. 連接器

主要負(fù)責(zé)用戶登錄數(shù)據(jù)庫(kù),進(jìn)行用戶的身份認(rèn)證,包括校驗(yàn)賬戶密碼,權(quán)限等操作,如果用戶賬戶密碼已通過(guò),連接器會(huì)到權(quán)限表中查詢?cè)撚脩舻乃袡?quán)限,之后在這個(gè)連接里的權(quán)限邏輯判斷都是會(huì)依賴此時(shí)讀取到的權(quán)限數(shù)據(jù),也就是說(shuō),后續(xù)只要這個(gè)連接不斷開(kāi),即時(shí)管理員修改了該用戶的權(quán)限,該用戶也是不受影響的。

  1. 查詢緩存(MySQL 8.0 版本后移除)

查詢緩存主要用來(lái)緩存我們所執(zhí)行的 SELECT 語(yǔ)句以及該語(yǔ)句的結(jié)果集。

連接建立后,執(zhí)行查詢語(yǔ)句的時(shí)候,會(huì)先查詢緩存,MySQL 會(huì)先校驗(yàn)這個(gè) sql 是否執(zhí)行過(guò),以 Key-Value 的形式緩存在內(nèi)存中,Key 是查詢預(yù)計(jì),Value 是結(jié)果集。如果緩存 key 被命中,就會(huì)直接返回給客戶端,如果沒(méi)有命中,就會(huì)執(zhí)行后續(xù)的操作,完成后也會(huì)把結(jié)果緩存起來(lái),方便下一次調(diào)用。當(dāng)然在真正執(zhí)行緩存查詢的時(shí)候還是會(huì)校驗(yàn)用戶的權(quán)限,是否有該表的查詢條件。

MySQL 查詢不建議使用緩存,因?yàn)椴樵兙彺媸г趯?shí)際業(yè)務(wù)場(chǎng)景中可能會(huì)非常頻繁,假如你對(duì)一個(gè)表更新的話,這個(gè)表上的所有的查詢緩存都會(huì)被清空。對(duì)于不經(jīng)常更新的數(shù)據(jù)來(lái)說(shuō),使用緩存還是可以的。所以,一般在大多數(shù)情況下我們都是不推薦去使用查詢緩存的。

  1. 分析器

MySQL 沒(méi)有命中緩存,那么就會(huì)進(jìn)入分析器,分析器主要是用來(lái)分析 SQL 語(yǔ)句是來(lái)干嘛的,分析器也會(huì)分為幾步:

第一步,詞法分析,一條 SQL 語(yǔ)句有多個(gè)字符串組成,首先要提取關(guān)鍵字,比如 select,提出查詢的表,提出字段名,提出查詢條件等等。做完這些操作后,就會(huì)進(jìn)入第二步。

第二步,語(yǔ)法分析,主要就是判斷你輸入的 sql 是否正確,是否符合 MySQL 的語(yǔ)法。

完成這 2 步之后,MySQL 就準(zhǔn)備開(kāi)始執(zhí)行了,但是如何執(zhí)行,怎么執(zhí)行是最好的結(jié)果呢?這個(gè)時(shí)候就需要優(yōu)化器上場(chǎng)了。

  1. 優(yōu)化器

優(yōu)化器的作用就是它認(rèn)為的最優(yōu)的執(zhí)行方案去執(zhí)行,比如多個(gè)索引的時(shí)候該如何選擇索引,多表查詢的時(shí)候如何選擇關(guān)聯(lián)順序等。可以說(shuō),經(jīng)過(guò)了優(yōu)化器之后可以說(shuō)這個(gè)語(yǔ)句具體該如何執(zhí)行就已經(jīng)定下來(lái)。

  1. 執(zhí)行器

當(dāng)選擇了執(zhí)行方案后,MySQL 就準(zhǔn)備開(kāi)始執(zhí)行了,首先執(zhí)行前會(huì)校驗(yàn)該用戶有沒(méi)有權(quán)限,如果沒(méi)有權(quán)限,就會(huì)返回錯(cuò)誤信息,如果有權(quán)限,就會(huì)去調(diào)用引擎的接口,返回接口執(zhí)行的結(jié)果。

SQL 優(yōu)化

避免使用select *

很多時(shí)候,我們寫sql語(yǔ)句時(shí),為了方便,喜歡直接使用select *,一次性查出表中所有列的數(shù)據(jù)。

反例:

select * from user where id=1;

在實(shí)際業(yè)務(wù)場(chǎng)景中,可能我們真正需要使用的只有其中一兩列。查了很多數(shù)據(jù),但是不用,白白浪費(fèi)了數(shù)據(jù)庫(kù)資源,比如:內(nèi)存或者cpu。

此外,多查出來(lái)的數(shù)據(jù),通過(guò)網(wǎng)絡(luò)IO傳輸?shù)倪^(guò)程中,也會(huì)增加數(shù)據(jù)傳輸?shù)臅r(shí)間。

還有一個(gè)最重要的問(wèn)題是:select *不會(huì)走覆蓋索引,會(huì)出現(xiàn)大量的回表操作,而從導(dǎo)致查詢sql的性能很低。

那么,如何優(yōu)化呢?

正例:

select name,age from user where id=1;

用union all代替union

我們都知道sql語(yǔ)句使用union關(guān)鍵字后,可以獲取排重后的數(shù)據(jù)。

而如果使用union all關(guān)鍵字,可以獲取所有數(shù)據(jù),包含重復(fù)的數(shù)據(jù)。

反例:

(select * from user where id=1) 
union 
(select * from user where id=2);

排重的過(guò)程需要遍歷、排序和比較,它更耗時(shí),更消耗cpu資源。

所以如果能用union all的時(shí)候,盡量不用union。

正例:

(select * from user where id=1) 
union all
(select * from user where id=2);

除非是有些特殊的場(chǎng)景,比如union all之后,結(jié)果集中出現(xiàn)了重復(fù)數(shù)據(jù),而業(yè)務(wù)場(chǎng)景中是不允許產(chǎn)生重復(fù)數(shù)據(jù)的,這時(shí)可以使用union。

小表驅(qū)動(dòng)大表,也就是說(shuō)用小表的數(shù)據(jù)集驅(qū)動(dòng)大表的數(shù)據(jù)集

假如有order和user兩張表,其中order表有10000條數(shù)據(jù),而user表有100條數(shù)據(jù)。

這時(shí)如果想查一下,所有有效的用戶下過(guò)的訂單列表。

可以使用in關(guān)鍵字實(shí)現(xiàn):

select * from order
where user_id in (select id from user where status=1)

也可以使用exists關(guān)鍵字實(shí)現(xiàn):

select * from order
where exists (select 1 from user where order.user_id = user.id and status=1)

前面提到的這種業(yè)務(wù)場(chǎng)景,使用in關(guān)鍵字去實(shí)現(xiàn)業(yè)務(wù)需求,更加合適。

為什么呢?

因?yàn)槿绻鹲ql語(yǔ)句中包含了in關(guān)鍵字,則它會(huì)優(yōu)先執(zhí)行in里面的子查詢語(yǔ)句,然后再執(zhí)行in外面的語(yǔ)句。如果in里面的數(shù)據(jù)量很少,作為條件查詢速度更快。

而如果sql語(yǔ)句中包含了exists關(guān)鍵字,它優(yōu)先執(zhí)行exists左邊的語(yǔ)句(即主查詢語(yǔ)句)。然后把它作為條件,去跟右邊的語(yǔ)句匹配。如果匹配上,則可以查詢出數(shù)據(jù)。如果匹配不上,數(shù)據(jù)就被過(guò)濾掉了。

這個(gè)需求中,order表有10000條數(shù)據(jù),而user表有100條數(shù)據(jù)。order表是大表,user表是小表。如果order表在左邊,則用in關(guān)鍵字性能更好。

總結(jié)一下:

  • in 適用于左邊大表,右邊小表。
  • exists 適用于左邊小表,右邊大表。

不管是用in,還是exists關(guān)鍵字,其核心思想都是用小表驅(qū)動(dòng)大表。

批量操作

如果你有一批數(shù)據(jù)經(jīng)過(guò)業(yè)務(wù)處理之后,需要插入數(shù)據(jù),該怎么辦?

反例:

for(Order order: list){orderMapper.insert(order):
}

在循環(huán)中逐條插入數(shù)據(jù)。

insert into order(id,code,user_id) 
values(123,'001',100);

該操作需要多次請(qǐng)求數(shù)據(jù)庫(kù),才能完成這批數(shù)據(jù)的插入。

但眾所周知,我們?cè)诖a中,每次遠(yuǎn)程請(qǐng)求數(shù)據(jù)庫(kù),是會(huì)消耗一定性能的。而如果我們的代碼需要請(qǐng)求多次數(shù)據(jù)庫(kù),才能完成本次業(yè)務(wù)功能,勢(shì)必會(huì)消耗更多的性能。

那么如何優(yōu)化呢?

正例:

orderMapper.insertBatch(list):

提供一個(gè)批量插入數(shù)據(jù)的方法。

insert into order(id,code,user_id) 
values(123,'001',100),(124,'002',100),(125,'003',101);

這樣只需要遠(yuǎn)程請(qǐng)求一次數(shù)據(jù)庫(kù),sql性能會(huì)得到提升,數(shù)據(jù)量越多,提升越大。

但需要注意的是,不建議一次批量操作太多的數(shù)據(jù),如果數(shù)據(jù)太多數(shù)據(jù)庫(kù)響應(yīng)也會(huì)很慢。批量操作需要把握一個(gè)度,建議每批數(shù)據(jù)盡量控制在500以內(nèi)。如果數(shù)據(jù)多于500,則分多批次處理。

多用limit

有時(shí)候,我們需要查詢某些數(shù)據(jù)中的第一條,比如:查詢某個(gè)用戶下的第一個(gè)訂單,想看看他第一次的首單時(shí)間。

select id, create_date from order 
where user_id=123 
order by create_date asc;

根據(jù)用戶id查詢訂單,按下單時(shí)間排序,先查出該用戶所有的訂單數(shù)據(jù),得到一個(gè)訂單集合。然后在代碼中,獲取第一個(gè)元素的數(shù)據(jù),即首單的數(shù)據(jù),就能獲取首單時(shí)間。

List<Order> list = orderMapper.getOrderList();
Order order = list.get(0);

雖說(shuō)這種做法在功能上沒(méi)有問(wèn)題,但它的效率非常不高,需要先查詢出所有的數(shù)據(jù),有點(diǎn)浪費(fèi)資源。

那么,如何優(yōu)化呢?

正例:

select id, create_date from order 
where user_id=123 
order by create_date asc 
limit 1;

使用limit 1,只返回該用戶下單時(shí)間最小的那一條數(shù)據(jù)即可。此外,在刪除或者修改數(shù)據(jù)時(shí),為了防止誤操作,導(dǎo)致刪除或修改了不相干的數(shù)據(jù),也可以在sql語(yǔ)句最后加上limit。

例如:

update order set status=0,edit_time=now(3) 
where id>=100 and id<200 limit 100;

這樣即使誤操作,比如把id搞錯(cuò)了,也不會(huì)對(duì)太多的數(shù)據(jù)造成影響。

SQL查找是否"存在",別再count了

根據(jù)某一條件從數(shù)據(jù)庫(kù)表中查詢 『有』與『沒(méi)有』,只有兩種狀態(tài),那為什么在寫SQL的時(shí)候,還要SELECT count(*) 呢?

無(wú)論是剛?cè)氲赖某绦騿T新星,還是精湛沙場(chǎng)多年的程序員老白,都是一如既往的count

反例:目前多數(shù)人的寫法

多次REVIEW代碼時(shí),發(fā)現(xiàn)如現(xiàn)現(xiàn)象:

業(yè)務(wù)代碼中,需要根據(jù)一個(gè)或多個(gè)條件,查詢是否存在記錄,不關(guān)心有多少條記錄。普遍的SQL及代碼寫法如下

#### SQL寫法:
SELECT count(*) FROM table WHERE a = 1 AND b = 2#### Java寫法:
int nums = xxDao.countXxxxByXxx(params);
if ( nums > 0 ) {//當(dāng)存在時(shí),執(zhí)行這里的代碼
} else {//當(dāng)不存在時(shí),執(zhí)行這里的代碼
}

推薦寫法如下:

#### SQL寫法:
SELECT 1 FROM table WHERE a = 1 AND b = 2 LIMIT 1#### Java寫法:
Integer exist = xxDao.existXxxxByXxx(params);
if ( exist != NULL ) {//當(dāng)存在時(shí),執(zhí)行這里的代碼
} else {//當(dāng)不存在時(shí),執(zhí)行這里的代碼
}

根據(jù)查詢條件查出來(lái)的條數(shù)越多,性能提升的越明顯,在某些情況下,還可以減少聯(lián)合索引的創(chuàng)建。

in中值太多

對(duì)于批量查詢接口,我們通常會(huì)使用in關(guān)鍵字過(guò)濾出數(shù)據(jù)。比如:想通過(guò)指定的一些id,批量查詢出用戶信息。

sql語(yǔ)句如下:

select id,name from category
where id in (1,2,3...100000000);

如果我們不做任何限制,該查詢語(yǔ)句一次性可能會(huì)查詢出非常多的數(shù)據(jù),很容易導(dǎo)致接口超時(shí)。

這時(shí)該怎么辦呢?

select id,name from category
where id in (1,2,3...100)
limit 500;

可以在sql中對(duì)數(shù)據(jù)用limit做限制。

不過(guò)我們更多的是要在業(yè)務(wù)代碼中加限制,偽代碼如下:

public List<Category> getCategory(List<Long> ids) {if(CollectionUtils.isEmpty(ids)) {return null;}if(ids.size() > 500) {throw new BusinessException("一次最多允許查詢500條記錄")}return mapper.getCategoryList(ids);
}

還有一個(gè)方案就是:如果ids超過(guò)500條記錄,可以分批用多線程去查詢數(shù)據(jù)。每批只查500條記錄,最后把查詢到的數(shù)據(jù)匯總到一起返回。

不過(guò)這只是一個(gè)臨時(shí)方案,不適合于ids實(shí)在太多的場(chǎng)景。因?yàn)閕ds太多,即使能快速查出數(shù)據(jù),但如果返回的數(shù)據(jù)量太大了,網(wǎng)絡(luò)傳輸也是非常消耗性能的,接口性能始終好不到哪里去。

高效的分頁(yè)

有時(shí)候,列表頁(yè)在查詢數(shù)據(jù)時(shí),為了避免一次性返回過(guò)多的數(shù)據(jù)影響接口性能,我們一般會(huì)對(duì)查詢接口做分頁(yè)處理。

在mysql中分頁(yè)一般用的limit關(guān)鍵字:

select id,name,age 
from user limit 10,20;

如果表中數(shù)據(jù)量少,用limit關(guān)鍵字做分頁(yè),沒(méi)啥問(wèn)題。但如果表中數(shù)據(jù)量很多,用它就會(huì)出現(xiàn)性能問(wèn)題。

比如現(xiàn)在分頁(yè)參數(shù)變成了:

select id,name,age 
from user limit 1000000,20;

mysql會(huì)查到1000020條數(shù)據(jù),然后丟棄前面的1000000條,只查后面的20條數(shù)據(jù),這個(gè)是非常浪費(fèi)資源的。

那么,這種海量數(shù)據(jù)該怎么分頁(yè)呢?

優(yōu)化sql:

select id,name,age 
from user where id > 1000000 limit 20;

先找到上次分頁(yè)最大的id,然后利用id上的索引查詢。不過(guò)該方案,要求id是連續(xù)的,并且有序的。

還能使用between優(yōu)化分頁(yè)。

select id,name,age 
from user where id between 1000000 and 1000020;

需要注意的是between要在唯一索引上分頁(yè),不然會(huì)出現(xiàn)每頁(yè)大小不一致的問(wèn)題。

用連接查詢代替子查詢

mysql中如果需要從兩張以上的表中查詢出數(shù)據(jù)的話,一般有兩種實(shí)現(xiàn)方式:子查詢 和 連接查詢。

子查詢的例子如下:

select * from order
where user_id in (select id from user where status=1)

子查詢語(yǔ)句可以通過(guò)in關(guān)鍵字實(shí)現(xiàn),一個(gè)查詢語(yǔ)句的條件落在另一個(gè)select語(yǔ)句的查詢結(jié)果中。程序先運(yùn)行在嵌套在最內(nèi)層的語(yǔ)句,再運(yùn)行外層的語(yǔ)句。

子查詢語(yǔ)句的優(yōu)點(diǎn)是簡(jiǎn)單,結(jié)構(gòu)化,如果涉及的表數(shù)量不多的話。

但缺點(diǎn)是mysql執(zhí)行子查詢時(shí),需要?jiǎng)?chuàng)建臨時(shí)表,查詢完畢后,需要再刪除這些臨時(shí)表,有一些額外的性能消耗。

這時(shí)可以改成連接查詢。具體例子如下:

select o.* from order o
inner join user u on o.user_id = u.id
where u.status=1

join時(shí)要注意

我們?cè)谏婕暗蕉鄰埍砺?lián)合查詢的時(shí)候,一般會(huì)使用join關(guān)鍵字。

而join使用最多的是left join和inner join。

left join:求兩個(gè)表的交集外加左表剩下的數(shù)據(jù)。

inner join:求兩個(gè)表交集的數(shù)據(jù)。

使用inner join的示例如下:

select o.id,o.code,u.name 
from order o 
inner join user u on o.user_id = u.id
where u.status=1;

如果兩張表使用inner join關(guān)聯(lián),mysql會(huì)自動(dòng)選擇兩張表中的小表,去驅(qū)動(dòng)大表,所以性能上不會(huì)有太大的問(wèn)題。

使用left join的示例如下:

select o.id,o.code,u.name 
from order o 
left join user u on o.user_id = u.id
where u.status=1;

如果兩張表使用left join關(guān)聯(lián),mysql會(huì)默認(rèn)用left join關(guān)鍵字左邊的表,去驅(qū)動(dòng)它右邊的表。如果左邊的表數(shù)據(jù)很多時(shí),就會(huì)出現(xiàn)性能問(wèn)題。

要特別注意的是在用left join關(guān)聯(lián)查詢時(shí),左邊要用小表,右邊可以用大表。如果能用inner join的地方,盡量少用left join。

提升group by的效率

我們有很多業(yè)務(wù)場(chǎng)景需要使用group by關(guān)鍵字,它主要的功能是去重和分組。

通常它會(huì)跟having一起配合使用,表示分組后再根據(jù)一定的條件過(guò)濾數(shù)據(jù)。

反例:

select user_id,user_name from order
group by user_id
having user_id <= 200;

這種寫法性能不好,它先把所有的訂單根據(jù)用戶id分組之后,再去過(guò)濾用戶id大于等于200的用戶。

分組是一個(gè)相對(duì)耗時(shí)的操作,為什么我們不先縮小數(shù)據(jù)的范圍之后,再分組呢?

正例:

select user_id,user_name from order
where user_id <= 200
group by user_id

使用where條件在分組前,就把多余的數(shù)據(jù)過(guò)濾掉了,這樣分組時(shí)效率就會(huì)更高一些。

其實(shí)這是一種思路,不僅限于group by的優(yōu)化。我們的sql語(yǔ)句在做一些耗時(shí)的操作之前,應(yīng)盡可能縮小數(shù)據(jù)范圍,這樣能提升sql整體的性能。

http://www.risenshineclean.com/news/4472.html

相關(guān)文章:

  • 現(xiàn)在怎么做網(wǎng)絡(luò)營(yíng)銷推廣方法網(wǎng)站的優(yōu)化seo
  • 北京 做網(wǎng)站 公司微信公眾號(hào)小程序怎么做
  • 注重網(wǎng)站內(nèi)容維護(hù)百度推廣賬號(hào)怎么申請(qǐng)
  • 電子產(chǎn)品營(yíng)銷策劃書(shū)seo優(yōu)化易下拉霸屏
  • 重慶網(wǎng)絡(luò)網(wǎng)站推廣網(wǎng)絡(luò)營(yíng)銷公司排行榜
  • 開(kāi)通網(wǎng)站必須做域名空間營(yíng)銷方法有哪些方式
  • 怎么更改網(wǎng)站域名搜索引擎推廣實(shí)訓(xùn)
  • 瀏陽(yáng)做網(wǎng)站報(bào)價(jià)簡(jiǎn)述如何優(yōu)化網(wǎng)站的方法
  • 網(wǎng)站越來(lái)越難做班級(jí)優(yōu)化大師免費(fèi)下載
  • 常德投訴網(wǎng)站經(jīng)典品牌推廣文案
  • 做網(wǎng)站的語(yǔ)言智慧營(yíng)銷系統(tǒng)平臺(tái)
  • 17zwd一起做業(yè)網(wǎng)站做網(wǎng)站的公司有哪些
  • 公明網(wǎng)站建設(shè)seo網(wǎng)站有優(yōu)化培訓(xùn)班嗎
  • c 做的網(wǎng)站怎么上傳圖片廣告公司網(wǎng)站
  • 現(xiàn)在個(gè)人做網(wǎng)站還能盈利嗎百度400電話
  • 網(wǎng)站建設(shè)北京貴武安百度seo
  • 騰訊 微商 網(wǎng)站 建設(shè)青島神馬排名優(yōu)化
  • 一個(gè)人做商城網(wǎng)站網(wǎng)頁(yè)開(kāi)發(fā)培訓(xùn)網(wǎng)
  • 專業(yè)制作彩鈴網(wǎng)站排名軟件
  • 電子商務(wù)網(wǎng)站服務(wù)器百度站長(zhǎng)平臺(tái)網(wǎng)站提交
  • 做視頻播放網(wǎng)站百度問(wèn)答庫(kù)
  • 為什么網(wǎng)站有不同的擴(kuò)展名全國(guó)最新的疫情數(shù)據(jù)
  • 鄒城手機(jī)網(wǎng)站建設(shè)重慶網(wǎng)
  • 煙臺(tái)網(wǎng)站排名優(yōu)化報(bào)價(jià)seo排名優(yōu)化課程
  • 購(gòu)物網(wǎng)站開(kāi)發(fā)費(fèi)用武漢百度信息流廣告
  • wordpress后臺(tái)亂了是怎么回事專業(yè)網(wǎng)站優(yōu)化公司
  • 建立讀音seo研究中心vip教程
  • dw怎么做網(wǎng)站教程廣告推廣網(wǎng)站
  • seo的網(wǎng)站建設(shè)湖南企業(yè)競(jìng)價(jià)優(yōu)化公司
  • 云技術(shù)在網(wǎng)站建設(shè)中的應(yīng)用免費(fèi)網(wǎng)絡(luò)推廣軟件