黑馬程序員mysql優化面試(mysql優化 面試)

本文目錄一覽:

「春招系列」MySQL面試核心25問(附答案)

篇幅所限本文只寫了MySQL25題,像其他的Redis,SSM框架,演算法,計網等技術棧的面試題後面會持續更新,個人整理的1000餘道面試八股文會放在文末給大家白嫖,最近有面試需要刷題的同學可以直接翻到文末領取。

如果表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。如果使用非自增主鍵(如果身份證號或學號等),由於每次插入主鍵的值近似於隨機,因此每次新紀錄都要被插到現有索引頁得中間某個位置, 頻繁的移動、分頁操作造成了大量的碎片,得到了不夠緊湊的索引結構,後續不得不通過OPTIMIZE TABLE(optimize table)來重建表並優化填充頁面。

Server層按順序執行sql的步驟為:

簡單概括:

可以分為服務層和存儲引擎層兩部分,其中:

服務層包括連接器、查詢緩存、分析器、優化器、執行器等 ,涵蓋MySQL的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。

存儲引擎層負責數據的存儲和提取 。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認的存儲引擎。

Drop、Delete、Truncate都表示刪除,但是三者有一些差別:

Delete 用來刪除表的全部或者一部分數據行,執行Delete之後,用戶需要提交(commmit)或者回滾(rollback)來執行刪除或者撤銷刪除,會觸發這個表上所有的delete觸發器。

Truncate 刪除表中的所有數據,這個操作不能回滾,也不會觸發這個表上的觸發器,TRUNCATE比Delete更快,佔用的空間更小。

Drop 命令從資料庫中刪除表,所有的數據行,索引和許可權也會被刪除,所有的DML觸發器也不會被觸發,這個命令也不能回滾。

因此,在不再需要一張表的時候,用Drop;在想刪除部分數據行時候,用Delete;在保留表而刪除所有數據的時候用Truncate。

隔離級別臟讀不可重複讀幻影讀 READ-UNCOMMITTED 未提交讀 READ-COMMITTED 提交讀 REPEATABLE-READ 重複讀 SERIALIZABLE 可串列化讀

MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ (可重讀)

這裡需要注意的是 :與 SQL 標準不同的地方在於InnoDB 存儲引擎在 REPEATABLE-READ(可重讀)事務隔離級別 下使用的是 Next-Key Lock 鎖 演算法,因此可以避免幻讀的產生,這與其他資料庫系統(如 SQL Server)是不同的。所以 說InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀) 已經可以完全保證事務的隔離性要 求,即達到了 SQL標準的SERIALIZABLE(可串列化)隔離級別。

因為隔離級別越低,事務請求的鎖越少,所以大部分資料庫系統的隔離級別都是READ-COMMITTED(讀取提交內 容):,但是你要知道的是InnoDB 存儲引擎默認使用 REPEATABLE-READ(可重讀)並不會有任何性能損失 。

InnoDB 存儲引擎在分散式事務 的情況下一般會用到SERIALIZABLE(可串列化)隔離級別。

主要原因:B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而且在資料庫中基於範圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節點,效率太低。

文件與資料庫都是需要較大的存儲,也就是說,它們都不可能全部存儲在內存中,故需要存儲到磁碟上。而所謂索引,則為了數據的快速定位與查找,那麼索引的結構組織要盡量減少查找過程中磁碟I/O的存取次數,因此B+樹相比B樹更為合適。資料庫系統巧妙利用了局部性原理與磁碟預讀原理,將一個節點的大小設為等於一個頁,這樣每個節點只需要一次I/O就可以完全載入,而紅黑樹這種結構,高度明顯要深的多,並且由於邏輯上很近的節點(父子)物理上可能很遠,無法利用局部性。

最重要的是,B+樹還有一個最大的好處:方便掃庫。

B樹必須用中序遍歷的方法按序掃庫,而B+樹直接從葉子結點挨個掃一遍就完了,B+樹支持range-query非常方便,而B樹不支持,這是資料庫選用B+樹的最主要原因。

B+樹查找效率更加穩定,B樹有可能在中間節點找到數據,穩定性不夠。

B+tree的磁碟讀寫代價更低:B+tree的內部結點並沒有指向關鍵字具體信息的指針(紅色部分),因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一塊盤中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多,相對來說IO讀寫次數也就降低了;

B+tree的查詢效率更加穩定:由於內部結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引,所以,任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當;

視圖是一種虛擬的表,通常是有一個表或者多個表的行或列的子集,具有和物理表相同的功能 游標是對查詢出來的結果集作為一個單元來有效的處理。一般不使用游標,但是需要逐條處理數據的時候,游標顯得十分重要。

而在 MySQL 中,恢復機制是通過回滾日誌(undo log)實現的,所有事務進行的修改都會先記錄到這個回滾日誌中,然後在對資料庫中的對應行進行寫入。當事務已經被提交之後,就無法再次回滾了。

回滾日誌作用:1)能夠在發生錯誤或者用戶執行 ROLLBACK 時提供回滾相關的信息 2) 在整個系統發生崩潰、資料庫進程直接被殺死後,當用戶再次啟動資料庫進程時,還能夠立刻通過查詢回滾日誌將之前未完成的事務進行回滾,這也就需要回滾日誌必須先於數據持久化到磁碟上,是我們需要先寫日誌後寫資料庫的主要原因。

InnoDB

MyISAM

總結

資料庫並發會帶來臟讀、幻讀、丟棄更改、不可重複讀這四個常見問題,其中:

臟讀 :在第一個修改事務和讀取事務進行的時候,讀取事務讀到的數據為100,這是修改之後的數據,但是之後該事務滿足一致性等特性而做了回滾操作,那麼讀取事務得到的結果就是臟數據了。

幻讀 :一般是T1在某個範圍內進行修改操作(增加或者刪除),而T2讀取該範圍導致讀到的數據是修改之間的了,強調範圍。

丟棄修改 :兩個寫事務T1 T2同時對A=0進行遞增操作,結果T2覆蓋T1,導致最終結果是1 而不是2,事務被覆蓋

不可重複讀 :T2 讀取一個數據,然後T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

第一個事務首先讀取var變數為50,接著準備更新為100的時,並未提交,第二個事務已經讀取var為100,此時第一個事務做了回滾。最終第二個事務讀取的var和資料庫的var不一樣。

T1 讀取某個範圍的數據,T2 在這個範圍內插入新的數據,T1 再次讀取這個範圍的數據,此時讀取的結果和和第一次讀取的結果不同。

T1 和 T2 兩個事務都對一個數據進行修改,T1 先修改,T2 隨後修改,T2 的修改覆蓋了 T1 的修改。例如:事務1讀取某表中的數據A=50,事務2也讀取A=50,事務1修改A=A+50,事務2也修改A=A+50,最終結果A=100,事務1的修改被丟失。

T2 讀取一個數據,T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

悲觀鎖,先獲取鎖,再進行業務操作,一般就是利用類似 SELECT … FOR UPDATE 這樣的語句,對數據加鎖,避免其他事務意外修改數據。當資料庫執行SELECT … FOR UPDATE時會獲取被select中的數據行的行鎖,select for update獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。

樂觀鎖,先進行業務操作,只在最後實際更新數據時進行檢查數據是否被更新過。Java 並發包中的 AtomicFieldUpdater 類似,也是利用 CAS 機制,並不會對數據加鎖,而是通過對比數據的時間戳或者版本號,來實現樂觀鎖需要的版本判斷。

分庫與分表的目的在於,減小資料庫的單庫單表負擔,提高查詢性能,縮短查詢時間。

通過分表 ,可以減少資料庫的單表負擔,將壓力分散到不同的表上,同時因為不同的表上的數據量少了,起到提高查詢性能,縮短查詢時間的作用,此外,可以很大的緩解表鎖的問題。分表策略可以歸納為垂直拆分和水平拆分:

水平分表 :取模分表就屬於隨機分表,而時間維度分表則屬於連續分表。如何設計好垂直拆分,我的建議:將不常用的欄位單獨拆分到另外一張擴展表. 將大文本的欄位單獨拆分到另外一張擴展表, 將不經常修改的欄位放在同一張表中,將經常改變的欄位放在另一張表中。對於海量用戶場景,可以考慮取模分表,數據相對比較均勻,不容易出現熱點和並發訪問的瓶頸。

庫內分表 ,僅僅是解決了單表數據過大的問題,但並沒有把單表的數據分散到不同的物理機上,因此並不能減輕 MySQL 伺服器的壓力,仍然存在同一個物理機上的資源競爭和瓶頸,包括 CPU、內存、磁碟 IO、網路帶寬等。

分庫與分錶帶來的分散式困境與應對之策 數據遷移與擴容問題—-一般做法是通過程序先讀出數據,然後按照指定的分表策略再將數據寫入到各個分表中。分頁與排序問題—-需要在不同的分表中將數據進行排序並返回,並將不同分表返回的結果集進行匯總和再次排序,最後再返回給用戶。

不可重複讀的重點是修改,幻讀的重點在於新增或者刪除。

視圖是虛擬的表,與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢;不包含任何列或數據。使用視圖可以簡化複雜的 sql 操作,隱藏具體的細節,保護數據;視圖創建後,可以使用與表相同的方式利用它們。

視圖不能被索引,也不能有關聯的觸發器或默認值,如果視圖本身內有order by 則對視圖再次order by將被覆蓋。

創建視圖:create view xxx as xxxx

對於某些視圖比如未使用聯結子查詢分組聚集函數Distinct Union等,是可以對其更新的,對視圖的更新將對基表進行更新;但是視圖主要用於簡化檢索,保護數據,並不用於更新,而且大部分視圖都不可以更新。

B+tree的磁碟讀寫代價更低,B+tree的查詢效率更加穩定 資料庫索引採用B+樹而不是B樹的主要原因:B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而且在資料庫中基於範圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節點,效率太低。

B+樹的特點

在最頻繁使用的、用以縮小查詢範圍的欄位,需要排序的欄位上建立索引。不宜:1)對於查詢中很少涉及的列或者重複值比較多的列 2)對於一些特殊的數據類型,不宜建立索引,比如文本欄位(text)等。

如果一個索引包含(或者說覆蓋)所有需要查詢的欄位的值,我們就稱 之為「覆蓋索引」。

我們知道在InnoDB存儲引 擎中,如果不是主鍵索引,葉子節點存儲的是主鍵+列值。最終還是要「回表」,也就是要通過主鍵再查找一次,這樣就 會比較慢。覆蓋索引就是把要查詢出的列和索引是對應的,不做回表操作!

舉例 :

學號姓名性別年齡系別專業 20020612李輝男20計算機軟體開發 20060613張明男18計算機軟體開發 20060614王小玉女19物理力學 20060615李淑華女17生物動物學 20060616趙靜男21化學食品化學 20060617趙靜女20生物植物學

主鍵為候選鍵的子集,候選鍵為超鍵的子集,而外鍵的確定是相對於主鍵的。

面試中常問:mysql資料庫做哪些優化也提高mysql性能

在開始演示之前,我們先介紹下兩個概念。

概念一,數據的可選擇性基數,也就是常說的cardinality值。

查詢優化器在生成各種執行計劃之前,得先從統計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個欄位中的唯一值分布狀態。

比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這裡唯一值越的多少,就是這個列的可選擇基數。

那看到這裡我們就明白了,為什麼要在基數高的欄位上建立索引,而基數低的的欄位建立索引反而沒有全表掃描來的快。當然這個只是一方面,至於更深入的探討就不在我這篇探討的範圍了。

概念二,關於HINT的使用。

這裡我來說下HINT是什麼,在什麼時候用。

HINT簡單來說就是在某些特定的場景下人工協助MySQL優化器的工作,使她生成最優的執行計劃。一般來說,優化器的執行計劃都是最優化的,不過在某些特定場景下,執行計劃可能不是最優化。

比如:表t1經過大量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執行了一條SQL,那麼有可能這條SQL的執行計劃就不是最優的。為什麼說有可能呢?

來看下具體演示

譬如,以下兩條SQL,

A:

select * from t1 where f1 = 20;

B:

select * from t1 where f1 = 30;

如果f1的值剛好頻繁更新的值為30,並且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那麼對這兩條語句來說,可能不準確的就是B了。

這裡順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。

那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。

示例表結構:

mysql desc t1;+————+————–+——+—–+———+—————-+| Field      | Type         | Null | Key | Default | Extra          |+————+————–+——+—–+———+—————-+| id         | int(11)      | NO   | PRI | NULL    | auto_increment || rank1      | int(11)      | YES  | MUL | NULL    |                || rank2      | int(11)      | YES  | MUL | NULL    |                || log_time   | datetime     | YES  | MUL | NULL    |                || prefix_uid | varchar(100) | YES  |     | NULL    |                || desc1      | text         | YES  |     | NULL    |                || rank3      | int(11)      | YES  | MUL | NULL    |                |+————+————–+——+—–+———+—————-+7 rows in set (0.00 sec)

表記錄數:

mysql select count(*) from t1;+———-+| count(*) |+———-+|    32768 |+———-+1 row in set (0.01 sec)

這裡我們兩條經典的SQL:

SQL C:

select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;

SQL D:

select * from t1 where rank1 =100  and rank2 =100  and rank3 =100;

表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。

那我們來看SQL C的查詢計劃。

顯然,沒有用到任何索引,掃描的行數為32034,cost為3243.65。

mysql explain  format=json select * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “3243.65”    },    “table”: {      “table_name”: “t1”,      “access_type”: “ALL”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “rows_examined_per_scan”: 32034,      “rows_produced_per_join”: 115,      “filtered”: “0.36”,      “cost_info”: {        “read_cost”: “3232.07”,        “eval_cost”: “11.58”,        “prefix_cost”: “3243.65”,        “data_read_per_join”: “49K”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))”    }  }}1 row in set, 1 warning (0.00 sec)

我們加上hint給相同的查詢,再次看看查詢計劃。

這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。

mysql explain  format=json select /*+ index_merge(t1) */ * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “441.09”    },    “table”: {      “table_name”: “t1”,      “access_type”: “index_merge”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “union(idx_rank1,idx_rank2,idx_rank3)”,      “key_length”: “5,5,5”,      “rows_examined_per_scan”: 1103,      “rows_produced_per_join”: 1103,      “filtered”: “100.00”,      “cost_info”: {        “read_cost”: “330.79”,        “eval_cost”: “110.30”,        “prefix_cost”: “441.09”,        “data_read_per_join”: “473K”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))”    }  }}1 row in set, 1 warning (0.00 sec)

我們再看下SQL D的計劃:

不加HINT,

mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “534.34”    },    “table”: {      “table_name”: “t1”,      “access_type”: “ref”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “idx_rank1”,      “used_key_parts”: [        “rank1”      ],      “key_length”: “5”,      “ref”: [        “const”      ],      “rows_examined_per_scan”: 555,      “rows_produced_per_join”: 0,      “filtered”: “0.07”,      “cost_info”: {        “read_cost”: “478.84”,        “eval_cost”: “0.04”,        “prefix_cost”: “534.34”,        “data_read_per_join”: “176”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))”    }  }}1 row in set, 1 warning (0.00 sec)

加了HINT,

mysql explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “5.23”    },    “table”: {      “table_name”: “t1”,      “access_type”: “index_merge”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “intersect(idx_rank1,idx_rank2,idx_rank3)”,      “key_length”: “5,5,5”,      “rows_examined_per_scan”: 1,      “rows_produced_per_join”: 1,      “filtered”: “100.00”,      “cost_info”: {        “read_cost”: “5.13”,        “eval_cost”: “0.10”,        “prefix_cost”: “5.23”,        “data_read_per_join”: “440”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))”    }  }}1 row in set, 1 warning (0.00 sec)

對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。

總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。

什麼是Mysql優化?

優化資料庫的方法

1、選取最適用的欄位屬性

MySQL可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得儘可能小。

例如,在定義郵政編碼這個欄位時,如果將其設置為CHAR(255),顯然給資料庫增加了不必要的空間,甚至使用VARCHAR這種類型也是多餘的,因為CHAR(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用MEDIUMINT而不是BIGIN來定義整型欄位。

另外一個提高效率的方法是在可能的情況下,應該盡量把欄位設置為NOT NULL,這樣在將來執行查詢的時候,資料庫不用去比較NULL值。

對於某些文本欄位,例如「省份」或者「性別」,我們可以將它們定義為ENUM類型。因為在MySQL中,ENUM類型被當作數值型數據來處理,而數值型數據被處理起來的速度要比文本類型快得多。這樣,我們又可以提高資料庫的性能。

2、使用連接(JOIN)來代替子查詢(Sub-Queries)

MySQL從4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。例如,我們要將客戶基本信息表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售信息表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查詢,如下所示:

DELETEFROMcustomerinfo

WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)

使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死,並且寫起來也很容易。但是,有些情況下,子查詢可以被更有效率的連接(JOIN)..替代。例如,假設我們要將所有沒有訂單記錄的用戶取出來,可以用下面這個查詢完成:

SELECT*FROMcustomerinfo

WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)

如果使用連接(JOIN)..來完成這個查詢工作,速度將會快很多。尤其是當salesinfo表中對CustomerID建有索引的話,性能將會更好,

原創文章,作者:SI6N4,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/130123.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
SI6N4的頭像SI6N4
上一篇 2024-10-03 23:27
下一篇 2024-10-03 23:27

相關推薦

  • 如何修改mysql的埠號

    本文將介紹如何修改mysql的埠號,方便開發者根據實際需求配置對應埠號。 一、為什麼需要修改mysql埠號 默認情況下,mysql使用的埠號是3306。在某些情況下,我們需…

    編程 2025-04-29
  • 兼職程序員能掙錢嗎?

    可以。不過,兼職程序員賺錢的關鍵就在於如何找到並利用合適的機會。 一、掌握技能 作為程序員,掌握必要的技能是兼職掙錢的前提。除了紮實的編程技能,了解相關工具和平台也非常重要。常見的…

    編程 2025-04-29
  • Python操作MySQL

    本文將從以下幾個方面對Python操作MySQL進行詳細闡述: 一、連接MySQL資料庫 在使用Python操作MySQL之前,我們需要先連接MySQL資料庫。在Python中,我…

    編程 2025-04-29
  • MySQL遞歸函數的用法

    本文將從多個方面對MySQL遞歸函數的用法做詳細的闡述,包括函數的定義、使用方法、示例及注意事項。 一、遞歸函數的定義 遞歸函數是指在函數內部調用自身的函數。MySQL提供了CRE…

    編程 2025-04-29
  • MySQL bigint與long的區別

    本文將從數據類型定義、存儲空間、數據範圍、計算效率、應用場景五個方面詳細闡述MySQL bigint與long的區別。 一、數據類型定義 bigint在MySQL中是一種有符號的整…

    編程 2025-04-28
  • 兼職程序員外包平台的開發與實現

    隨著社會經濟和科技的快速發展,更多人選擇通過互聯網進入編程行業。兼職開發已成為一種新型就業方式,並且這種方式在新冠肺炎疫情襲來、大規模遠程辦公的背景下更為普遍。本文將從多個方面詳細…

    編程 2025-04-28
  • MySQL左連接索引不生效問題解決

    在MySQL資料庫中,經常會使用左連接查詢操作,但是左連接查詢中索引不生效的情況也比較常見。本文將從多個方面探討MySQL左連接索引不生效問題,並給出相應的解決方法。 一、索引的作…

    編程 2025-04-28
  • CentOS 7在線安裝MySQL 8

    在本文中,我們將介紹如何在CentOS 7操作系統中在線安裝MySQL 8。我們會從安裝環境的準備開始,到安裝MySQL 8的過程進行詳細的闡述。 一、環境準備 在進行MySQL …

    編程 2025-04-27
  • 如何使用MySQL欄位去重

    本文將從多個方面為您詳細介紹如何使用MySQL欄位去重並給出相應的代碼示例。 一、SELECT DISTINCT語句去重 MySQL提供了SELECT DISTINCT語句,通過在…

    編程 2025-04-27
  • MySQL正則表達式替換

    MySQL正則表達式替換是指通過正則表達式對MySQL中的字元串進行替換。在文本處理方面,正則表達式是一種強大的工具,可以方便快捷地進行字元串處理和匹配。在MySQL中,可以使用正…

    編程 2025-04-27

發表回復

登錄後才能評論