Java筆試面試-MySQL 彙總

1.說一下 MySQL 執行一條查詢語句的內部執行過程?

答:MySQL 執行一條查詢的流程如下:

  • 客戶端先通過連接器連接到 MySQL 服務器;
  • 連接器權限驗證通過之後,先查詢是否有查詢緩存,如果有緩存(之前執行過此語句)則直接返回緩存數據,如果沒有緩存則進入分析器;
  • 分析器會對查詢語句進行語法分析和詞法分析,判斷 SQL 語法是否正確,如果查詢語法錯誤會直接返回給客戶端錯誤信息,如果語法正確則進入優化器;
  • 優化器是對查詢語句進行優化處理,例如一個表裏面有多個索引,優化器會判別哪個索引性能更好;
  • 優化器執行完就進入執行器,執行器則開始執行語句進行查詢比對了,直到查詢到滿足條件的所有數據,然後進行返回。

2.MySQL 查詢緩存有什麼優缺點?

答:MySQL 查詢緩存功能是在連接器之後發生的,它的優點是效率高,如果已經有緩存則會直接返回結果。查詢緩存的缺點是失效太頻繁導致緩存命中率比較低,任何更新表操作都會清空查詢緩存,因此導致查詢緩存非常容易失效。

3.MySQL 的常用引擎都有哪些?

答:MySQL 的常用引擎有 InnoDB、MyISAM、Memory 等,從 MySQL 5.5.5 版本開始 InnoDB 就成爲了默認的存儲引擎。

4.常用的存儲引擎 InnoDB 和 MyISAM 有什麼區別?

答:InnoDB 和 MyISAM 最大的區別是 InnoDB 支持事務,而 MyISAM 不支持事務,它們其他主要區別如下:

  • InnoDB 支持崩潰後安全恢復,MyISAM 不支持崩潰後安全恢復;
  • InnoDB 支持行級鎖,MyISAM 不支持行級鎖,只支持到表鎖;
  • InnoDB 支持外鍵,MyISAM 不支持外鍵;
  • MyISAM 性能比 InnoDB 高;
  • MyISAM 支持 FULLTEXT 類型的全文索引,InnoDB 不支持 FULLTEXT 類型的全文索引,但是 InnoDB 可以使用 sphinx 插件支持全文索引,並且效果更好;
  • InnoDB 主鍵查詢性能高於 MyISAM。

5.什麼叫回表查詢?

答:普通索引查詢到主鍵索引後,回到主鍵索引樹搜索的過程,我們稱爲回表查詢。

6.如果把一個 InnoDB 表的主鍵刪掉,是不是就沒有主鍵,就沒辦法進行回表查詢了?

答:不是,如果把主鍵刪掉了,那麼 InnoDB 會自己生成一個長度爲 6 字節的 rowid 作爲主鍵。

7.一張自增表中有三條數據,刪除兩條數據之後重啓數據庫,再新增一條數據,此時這條數據的 ID 是幾?

答:如果這張表的引擎是 MyISAM,那麼 ID=4,如果是 InnoDB 那麼 ID=2(MySQL 8 之前的版本)。

8.什麼是獨立表空間和共享表空間?它們的區別是什麼?

答:共享表空間指的是數據庫的所有表數據,索引文件全部放在一個文件中,默認這個共享表空間的文件路徑在 data 目錄下。獨立表空間指每一個表都將會生成以獨立的文件方式來進行存儲。

共享表空間和獨立表空間最大的區別是如果把表放再共享表空間,即使表刪除了空間也不會刪除,因此表依然很大,而獨立表空間如果刪除表就會清除空間。

9.清空表的所有數據性能最好的語句是?

A:delete from t
B:delete t
C:drop table t
D:truncate table t

答:D

題目解析:truncate 清除表數據不會寫日誌,delete 要寫日誌,因此 truncate 的效率要高於 delete。

10.唯一索引和普通索引哪個性能更好?

答:唯一索引和普通索引的性能對比分爲以下兩種情況:

  • 對於查詢來說兩者都是從索引數進行查詢,性能幾乎沒有任何區別;
  • 對於更新操作來說,因爲主鍵索引需要先將數據讀取到內存,然後需要判斷是否有衝突,因此比唯一索引要多了判斷操作,從而性能就比普通索引性能要低。

11.left join 和 right join 的區別是什麼?

答:left join 和 right join 的區別如下:

  • left join(左聯結),返回左表全部記錄和右表聯結字段相等的記錄;
  • right join(右聯結),返回右表全部記錄和左表聯結字段相等的記錄。

12.什麼是最左匹配原則?它的生效原則有哪些?

答:最左匹配原則也叫最左前綴原則,是 MySQL 中的一個重要原則,指的是索引以最左邊爲起點任何連續的索引都能匹配上,當遇到範圍查詢(>、<、between、like)就會停止匹配。 生效原則來看以下示例,比如表中有一個聯合索引字段 index(a,b,c):

where a=1 只使用了索引 a;
where a=1 and b=2 只使用了索引 a,b;
where a=1 and b=2 and c=3 使用a,b,c;
where b=1 or where c=1 不使用索引;
where a=1 and c=3 只使用了索引 a;
where a=3 and b like 'xx%' and c=3 只使用了索引 a,b。

13.以下 or 查詢有什麼問題嗎?該如何優化?

select * from t where num=10 or num=20;

答:如果使用 or 查詢會使 MySQL 放棄索引而全表掃描,可以改爲:

select * from t where num=10

union

select * from t where num=20;

14.事務是什麼?它有什麼特性?

答:事務是一系列的數據庫操作,是數據庫應用的基本單位。在 MySQL 中只有 InnDB 引擎支持事務,它的四個特性如下:

  • 原子性(Atomic),要麼全部執行,要麼全部不執行;
  • 一致性(Consistency),事務的執行使得數據庫從一種正確狀態轉化爲另一種正確狀態;
  • 隔離性(Isolation),在事務正確提交之前,不允許把該事務對數據的任何改變提供給其他事務;
  • 持久性(Durability),事務提交後,其結果永久保存在數據庫中。

15.MySQL 中有幾種事務隔離級別?分別是什麼?
答:MySQL 中有四種事務隔離級別,分別是:

  • read uncommited,未提交讀,讀到未提交數據;
  • read committed,讀已提交,也叫不可重複讀,兩次讀取到的數據不一致;
  • repetable read,可重複讀;
  • serializable,串行化,讀寫數據都會鎖住整張表,數據操作不會出錯,但併發性能極低,開發中很少用到。

MySQL 默認使用 repetable read 的事務隔離級別。

16.如何設置 MySQL 的事務隔離級別?

答:MySQL 事務隔離級別 mysql.cnf 文件裏設置的(默認目錄 /etc/my.cnf),在文件的文末添加配置:

transaction-isolation = REPEATABLE-READ

可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE

17.MySQL 出現了中文亂碼該如何解決?

答:解決 MySQL 中文亂碼的問題,可以設置全局編碼或設置某個數據庫或表的編碼爲 utf8。 設置全局編碼:

set character_set_client='utf8';
set character_set_connection='utf8';
set character_set_results='utf8';

設置數據庫的編碼:

alter database db character set utf8;

設置表的編碼:

alter table t character set utf8;

18.InnoDB 爲什麼要使用 B+ 樹,而不是 B 樹、Hash、紅黑樹或二叉樹?

答:因爲 B 樹、Hash、紅黑樹或二叉樹存在以下問題。

  • B 樹:不管葉子節點還是非葉子節點,都會保存數據,這樣導致在非葉子節點中能保存的指針數量變少(有些資料也稱爲扇出),指針少的情況下要保存大量數據,只能增加樹的高度,導致 IO 操作變多,查詢性能變低。
  • Hash:雖然可以快速定位,但是沒有順序,IO 複雜度高。
  • 二叉樹:樹的高度不均勻,不能自平衡,查找效率跟數據有關(樹的高度),並且 IO 代價高。
  • 紅黑樹:樹的高度隨着數據量增加而增加,IO 代價高。

19.MySQL 是如何處理死鎖?

答:MySQL 對待死鎖常見的兩種策略:

  • 通過 innodb_lock_wait_timeout 來設置超時時間,一直等待直到超時;
  • 發起死鎖檢測,發現死鎖之後,主動回滾死鎖中的某一個事務,讓其他事務繼續執行。

20.什麼是全局鎖?它的應用場景有哪些?

答:全局鎖就是對整個數據庫實例加鎖,它的典型使用場景就是做全款邏輯備份,這個時候整個庫會處於完全的只讀狀態。

21.使用全局鎖會導致什麼問題?

答:使用全局鎖會使整個系統不能執行更新操作,所有的更新業務會出於等待狀態;如果你是在從庫進行備份,則會導致主從同步嚴重延遲。

22.InnoDB 存儲引擎有幾種鎖算法?

答:InnoDB 的鎖算法包括以下三種:

  • Record Lock — 單個行記錄上的鎖;
  • Gap Lock — 間隙鎖,鎖定一個範圍,不包括記錄本身;
  • Next-Key Lock — 鎖定一個範圍,包括記錄本身。

23.InnoDB 如何實現行鎖?

答:只有通過索引條件檢索數據,InnoDB 才使用行級鎖,否則 InnoDB 將使用表鎖。使用 for update 來實現行鎖,具體腳本如下:

select * from t where id=1 for update

其中 id 字段必須有索引。

24.MySQL 性能指標都有哪些?如何得到這些指標?

答:MySQL 最重要的性能指標有以下兩個:

  • QPS(Queries Per Second),每秒查詢數,一臺數據庫每秒能夠處理的查詢次數;
  • TPS(Transactions Per Second),每秒處理事務數。

這些性能指標可以通過 show status 來查詢當前數據庫狀態的結果信息中估算出來,show status 會有 300 多條狀態信息記錄,其中以下這些信息 QPS 和 TPS 有關係:

  • Uptime,服務器已經運行的時間,單位秒;
  • Questions,已經發送給數據庫查詢數;
  • Com_select,查詢次數,實際查詢次數;
  • Com_insert,插入次數;
  • Com_delete,刪除次數;
  • Com_update,更新次數;
  • Com_commit,事務次數;
  • Com_rollback,回滾次數。

25.MySQL 中的重要日誌分爲哪幾個?

① 錯誤日誌:用來記錄 MySQL 服務器運行過程中的錯誤信息,比如,無法加載 MySQL 數據庫的數據文件,或權限不正確等都會被記錄在此,還有複製環境下,從服務器進程的信息也會被記錄進錯誤日誌。默認情況下,錯誤日誌是開啓的,且無法被禁止。默認情況下,錯誤日誌是存儲在數據庫的數據文件目錄中,名稱爲 hostname.err,其中 hostname 爲服務器主機名。在 MySQL 5.5.7 之前,數據庫管理員可以刪除很長時間之前的錯誤日誌,以節省服務器上的硬盤空間, MySQL 5.5.7 之後,服務器將關閉此項功能,只能使用重命名原來的錯誤日誌文件,手動沖洗日誌創建一個新的,命令爲:

mv hostname.err hostname.err.old

mysqladmin flush-logs

② 查詢日誌:查詢日誌在 MySQL 中被稱爲 general log(通用日誌),查詢日誌裏的內容不要被“查詢日誌”誤導,認爲裏面只存儲 select 語句,其實不然,查詢日誌裏面記錄了數據庫執行的所有命令,不管語句是否正確,都會被記錄,具體原因如下:

  • insert 查詢爲了避免數據衝突,如果此前插入過數據,則當前插入的數據如果跟主鍵或唯一鍵的數據重複那肯定會報錯;
  • update 時也會查詢因爲更新的時候很可能會更新某一塊數據;
  • delete 查詢,只刪除符合條件的數據;

因此都會產生日誌,在併發操作非常多的場景下,查詢信息會非常多,那麼如果都記錄下來會導致 IO 非常大,影響 MySQL 性能。因此如果不是在調試環境下,是不建議開啓查詢日誌功能的。

查詢日誌的開啓有助於幫助我們分析哪些語句執行密集,執行密集的 select 語句對應的數據是否能夠被緩存,同時也可以幫助我們分析問題,因此,可以根據自己的實際情況來決定是否開啓查詢日誌。

查詢日誌模式是關閉的,可以通過以下命令開啓查詢日誌:

set global general_log=1

set global log_output='table';

general_log=1 爲開啓查詢日誌,0 爲關閉查詢日誌,這個設置命令即時生效,不用重啓 MySQL 服務器。

③ 慢日誌:慢查詢會導致 CPU、IOPS、內存消耗過高,當數據庫遇到性能瓶頸時,大部分時間都是由於慢查詢導致的。開啓慢查詢日誌,可以讓 MySQL 記錄下查詢超過指定時間的語句,之後運維人員通過定位分析,能夠很好的優化數據庫性能。默認情況下,慢查詢日誌是不開啓的,只有手動開啓了,慢查詢纔會被記錄到慢查詢日誌中。使用如下命令記錄當前數據庫的慢查詢語句:

set global slow_query_log='ON';

使用 set global slow_query_log=‘ON’ 開啓慢查詢日誌,只是對當前數據庫有效,如果 MySQL 數據庫重啓後就會失效。因此如果要永久生效,就要修改配置文件 my.cnf,設置 slow_query_log=1 並重啓 MySQL 服務器。

④ redo log(重做日誌):爲了最大程度的避免數據寫入時,因爲 IO 瓶頸造成的性能問題,MySQL 採用了這樣一種緩存機制,先將數據寫入內存中,再批量把內存中的數據統一刷回磁盤。爲了避免將數據刷回磁盤過程中,因爲掉電或系統故障帶來的數據丟失問題,InnoDB 採用 redo log 來解決此問題。

⑤ undo log(回滾日誌):用於存儲日誌被修改前的值,從而保證如果修改出現異常,可以使用 undo log 日誌來實現回滾操作。

undo log 和 redo log 記錄物理日誌不一樣,它是邏輯日誌,可以認爲當 delete 一條記錄時,undo log 中會記錄一條對應的 insert 記錄,反之亦然,當 update 一條記錄時,它記錄一條對應相反的 update 記錄,當執行 rollback 時,就可以從 undo log 中的邏輯記錄讀取到相應的內容並進行回滾。undo log 默認存放在共享表空間中,在 ySQL 5.6 中,undo log 的存放位置還可以通過變量 innodb_undo_directory 來自定義存放目錄,默認值爲“.”表示 datadir 目錄。

⑥ bin log(二進制日誌):是一個二進制文件,主要記錄所有數據庫表結構變更,比如,CREATE、ALTER TABLE 等,以及表數據修改,比如,INSERT、UPDATE、DELETE 的所有操作,bin log 中記錄了對 MySQL 數據庫執行更改的所有操作,並且記錄了語句發生時間、執行時長、操作數據等其他額外信息,但是它不記錄 SELECT、SHOW 等那些不修改數據的 SQL 語句。 binlog 的作用如下:

恢復(recovery):某些數據的恢復需要二進制日誌。比如,在一個數據庫全備文件恢復後,用戶可以通過二進制日誌進行 point-in-time 的恢復;
複製(replication):其原理與恢復類似,通過複製和執行二進制日誌使一臺遠程的 MySQL 數據庫(一般稱爲 slave 或者 standby)與一臺 MySQL 數據庫(一般稱爲 master 或者 primary)進行實時同步;
審計(audit):用戶可以通過二進制日誌中的信息來進行審計,判斷是否有對數據庫進行注入攻擊。
除了上面介紹的幾個作用外,binlog 對於事務存儲引擎的崩潰恢復也有非常重要的作用,在開啓 binlog 的情況下,爲了保證 binlog 與 redo 的一致性,MySQL 將採用事務的兩階段提交協議。當 MySQL 系統發生崩潰時,事務在存儲引擎內部的狀態可能爲 prepared(準備狀態)和 commit(提交狀態)兩種,對於 prepared 狀態的事務,是進行提交操作還是進行回滾操作,這時需要參考 binlog,如果事務在 binlog 中存在,那麼將其提交;如果不在 binlog 中存在,那麼將其回滾,這樣就保證了數據在主庫和從庫之間的一致性。

binlog 默認是關閉狀態,可以在 MySQL 配置文件(my.cnf)中通過配置參數 log-bin = [base-name] 開啓記錄 binlog 日誌,如果不指定 base-name,則默認二進制日誌文件名爲主機名,並以自增的數字作爲後綴,比如:mysql-bin.000001,所在目錄爲數據庫所在目錄(datadir)。

通過以下命令來查詢 binlog 是否開啓:

show variables like ‘log_%’;
在這裏插入圖片描述
binlog 格式分爲 STATEMENT、ROW 和 MIXED 三種。

  • STATEMENT 格式的 binlog 記錄的是數據庫上執行的原生 SQL 語句。這種格式的優點是簡單,簡單地記錄和執行這些語句,能夠讓主備保持同步,在主服務器上執行的 SQL 語句,在從服務器上執行同樣的語句。另一個好處是二進制日誌裏的時間更加緊湊,因此相對而言,基於語句的複製模式不會使用太多帶寬,同時也節約磁盤空間,並且通過 mysqlbinlog 工具容易讀懂其中的內容。缺點就是同一條 SQL 在主庫和從庫上執行的時間可能稍微或很大不相同,因此在傳輸的二進制日誌中,除了查詢語句,還包括了一些元數據信息,如當前的時間戳。即便如此,還存在着一些無法被正確複製的 SQL,比如,使用 INSERT INTO TB1 VALUE(CUURENT_DATE()) 這一條使用函數的語句插入的數據複製到當前從服務器上來就會發生變化,存儲過程和觸發器在使用基於語句的複製模式時也可能存在問題;另外一個問題就是基於語句的複製必須是串行化的,比如,InnoDB 的 next-key 鎖等,並不是所有的存儲引擎都支持基於語句的複製。
  • ROW 格式是從 MySQL 5.1 開始支持基於行的複製,也就是基於數據的複製,基於行的更改。這種方式會將實際數據記錄在二進制日誌中,它有其自身的一些優點和缺點,最大的好處是可以正確地複製每一行數據,一些語句可以被更加有效地複製,另外就是幾乎沒有基於行的複製模式無法處理的場景,對於所有的 SQL 構造、觸發器、存儲過程等都能正確執行;它的缺點就是二進制日誌可能會很大,而且不直觀,因此,你不能使用 mysqlbinlog 來查看二進制日誌,也無法通過看二進制日誌判斷當前執行到那一條 SQL 語句。現在對於 ROW 格式的二進制日誌基本是標配了,主要是因爲它的優勢遠遠大於缺點,並且由於 ROW 格式記錄行數據,因此可以基於這種模式做一些 DBA 工具,比如數據恢復,不同數據庫之間數據同步等。
  • MIXED 也是 MySQL 默認使用的二進制日誌記錄方式,但 MIXED 格式默認採用基於語句的複製,一旦發現基於語句的無法精確的複製時,就會採用基於行的複製。比如用到 UUID()、USER()、CURRENT_USER()、ROW_COUNT() 等無法確定的函數。

26.redo log 和 binlog 有什麼區別?

redo log(重做日誌)和 binlog(歸檔日誌)都是 MySQL 的重要的日誌,它們的區別如下:

  • redo log 是物理日誌,記錄的是“在某個數據頁上做了什麼修改”;
  • binlog 是邏輯日誌,記錄的是這個語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”;
  • redo log 是 InnoDB 引擎特有的,binlog 是 MySQL 的 Server 層實現的,所有引擎都可以使用;
  • redo log 是循環寫的,空間固定會用完,binlog 是可以追加寫入的,“追加寫”是指 binlog 文件寫到一定大小後會切換到下一個,並不會覆蓋以前的日誌。

最開始 MySQL 裏並沒有 InnoDB 引擎,MySQL 自帶的引擎是 MyISAM,但是 MyISAM 沒有 crash-safe 的能力,binlog 日誌只能用於歸檔。而 InnoDB 是另一個公司以插件形式引入 MySQL 的,既然只依靠 binlog 是沒有 crash-safe 能力的,因此 InnoDB 使用另外一套日誌系統,也就是 redo log 來實現 crash-safe 能力。

27.慢查詢日誌的獲取方式有哪些?

答:慢查詢日誌的常見獲取方式如下。

  • 使用 MySQL 自帶功能,開啓慢查詢日誌,在 MySQL 的安裝目錄下找到 my.cnf 文件設置 slow-query-log=On 開啓慢查詢,慢查詢默認時長爲 10s,默認存儲文件名爲 host_name-slow.log。
  • 使用三方開源方案 zabbix,zabbix 是一個基於 Web 界面的提供分佈式系統監視以及網絡監視功能的企業級的開源解決方案,能監視各種網絡參數,保證服務器系統的安全運營;並提供靈活的通知機制以讓系統管理員快速定位/解決存在的各種問題。

28.如何定位慢查詢?

答:使用 MySQL 中的 explain 分析執行語句,比如:

explain select * from t where id=5;

如下圖所示:
在這裏插入圖片描述
其中:

  • id — 選擇標識符,id 越大優先級越高,越先被執行
  • select_type — 表示查詢的類型。
  • table — 輸出結果集的表
  • partitions — 匹配的分區
  • type — 表示表的連接類型
  • possible_keys — 表示查詢時,可能使用的索引
  • key — 表示實際使用的索引
  • key_len — 索引字段的長度
  • ref— 列與索引的比較
  • rows — 大概估算的行數
  • filtered — 按表條件過濾的行百分比
  • Extra — 執行情況的描述和說明

其中最重要的就是 type 字段,type 值類型如下:

  • all — 掃描全表數據
  • index — 遍歷索引
  • range — 索引範圍查找
  • index_subquery — 在子查詢中使用 ref
  • unique_subquery — 在子查詢中使用 eq_ref
  • ref_or_null — 對 null 進行索引的優化的 ref
  • fulltext — 使用全文索引
  • ref — 使用非唯一索引查找數據
  • eq_ref — 在 join 查詢中使用主鍵或唯一索引關聯
  • const — 將一個主鍵放置到 where 後面作爲條件查詢, MySQL 優化器就能把這次查詢優化轉化爲一個常量,如何轉化以及何時轉化,這個取決於優化器,這個比 eq_ref 效率高一點

29.MySQL 中常見的讀寫分離方案有哪些?

答:MySQL 中常見的讀寫分離方案通常爲以下兩種:

  • 使用 MySQL 官方提供的數據庫代理產品 MySql ProxySQL 搭建自動分配的數據庫讀寫分離環境;
  • 在程序層面配置多數據源使用代碼實現讀寫分離。

30.怎樣保證主備數據庫無延遲?

答:通常保證主備數據庫無延遲有以下三種方法。

  • 每次從庫執行查詢請求前,先判斷 seconds_behind_master 是否已經等於 0。如果還不等於 0 ,那就必須等到這個參數變爲 0 才能執行查詢請求,seconds_behind_master 參數是用來衡量主備延遲時間的長短。
  • 對比位點確保主備無延遲。Master_Log_File 和 Read_Master_Log_Pos,表示的是讀到的主庫的最新位點,Relay_Master_Log_File 和 Exec_Master_Log_Pos,表示的是備庫執行的最新位點。
  • 對比 GTID 集合確保主備無延遲。Auto_Position=1 ,表示這對主備關係使用了 GTID 協議。Retrieved_Gtid_Set,是備庫收到的所有日誌的 GTID 集合;Executed_Gtid_Set,是備庫所有已經執行完成的 GTID 集合。

31.什麼是 MySQL 多實例,如何配置 MySQL 多實例?

答:MySQL 多實例就是在同一臺服務器上啓用多個 MySQL 服務,它們監聽不同的端口,運行多個服務進程,它們相互獨立,互不影響的對外提供服務,便於節約服務器資源與後期架構擴展。 多實例的配置方法有兩種:

  • 一個實例一個配置文件,不同端口;
  • 同一配置文件(my.cnf)下配置不同實例,基於 MySQL 的 d_multi 工具。

32.表的優化策略有哪些?

答:常見的大表優化策略如下。

  • 讀寫分離,主庫負責寫,從庫負責讀。
  • 垂直分區,根據數據屬性單獨拆表甚至單獨拆庫。
  • 水平分區,保持表結構不變,根據策略存儲數據分片,這樣每一片數據被分散到不同的表或者庫中。水平拆分只是解決了單一表數據過大的問題,表數據還在同一臺機器上,對於併發能力沒有什麼意義,因此水平拆分最好分庫。另外分片事務難以解決,跨節點 join 性能較差。

33.數據庫分片方案有哪些?

答:數據庫創建的分片方案有兩種方式:客戶端代理方式和中間件代理方式。

  • 客戶端代理 — 分片邏輯在應用端,封裝在 jar 包中,通過修改或者封裝 JDBC 層來實現,比如 Sharding-JDBC、阿里 TDDL 等。
  • 中間件代理 — 在應用層和數據層中間加了一個代理層。分片邏輯統一維護在中間件服務中,比如 MyCat、網易的 DDB 都是中間件代理的典型代表。

34.查詢語句的優化方案有哪些?

答:常見優化方案如下:

  • 不做列運算,把計算都放入各個業務系統實現;
  • 查詢語句儘可能簡單,大語句拆小語句,減少鎖時間;
  • 不使用 select * 查詢;
  • or 查詢改寫成 in 查詢;
  • 不用函數和觸發器;
  • 避免 %xx 查詢;
  • 少用 join 查詢;
  • 使用同類型比較,比如 ‘123’ 和 ‘123’、123 和 123;
  • 儘量避免在 where 子句中使用 != 或者 <> 操作符,查詢引用會放棄索引而進行全表掃描;
  • 列表數據使用分頁查詢,每頁數據量不要太大。

35.MySQL 毫無規律的異常重啓,可能產生的原因是什麼?該如何解決?

答:可能是積累的長連接導致內存佔用太多,被系統強行殺掉導致的異常重啓,因爲在 MySQL 中長連接在執行過程中使用的臨時內存對象,只有在連接斷開的時候纔會釋放,這就會導致內存不斷飆升,解決方案如下:

  • 定期斷開空閒的長連接;
  • 如果是用的是 MySQL 5.7 以上的版本,可以定期執行 mysql_reset_connection 重新初始化連接資源,這個過程會釋放之前使用的內存資源,恢復到連接剛初始化的狀態。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章