Mysql面試題(一)


什么是索引

索引是幫助MySQL高校獲取數據的排好序的數據結構。
索引的數據結構:

  • 二叉樹
  • 紅黑樹
  • Hash表
  • B_Tree
    索引是用來快速尋找那些具有特定值的記錄,MySQL的索引是以B_Tree樹的形式保存的。如果沒有索引,執行查詢的時候MySQL是從表的第一條記錄開始掃描整個表的記錄,直到找到符合要求的數據。表里面的數據越多,這個操作的代價就越大。如果在搜索的條件上加上索引,MySQL可以快速的得到目標記錄所在的位置,從而大大提高查詢效率。

索引的分類

1. 主鍵索引(主鍵索引不能為null)

主鍵是一種唯一性索引,但它必須指定為“PRIMARY KEY”。
主鍵一般在創建表的時候就指定哪個字段是主鍵。如果創建表的時候不指定,也可以通過修改表的形式添加主鍵。

alter table tablename add primary key

主鍵索引只能有一個
不能使用like,會失效

1.1 查詢索引
desc 表名: 不能顯示索引的名稱
show index from 表名
show keys from 表名

2. 全文索引

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');

❌ 錯誤用法:

select * from articles where body like '%mysql%'; 錯誤用法 索引不會生效

✅ 正確用法:

select * from articles where match(titlle,body) against('database')

說明:

  • 在mysql中fulltext 索引只針對 myisam生效
  • mysql自己提供的fulltext針對英文生效->sphinx (coreseek) 技術處理中文
  • 使用方法是 match(字段名..) against(‘關鍵字’)
mysql> select match(title,body) against ('database') from articles;(輸出的是每行和database的匹配度)

全文索引:停止詞。 因為在一個文本中,創建索引是一個無窮大的數,因此,對一些常用詞和字符,就不會創建,這些詞,稱為停止詞.比如(a,b,mysql,the)

create table ccc(
id int unsigned,
name varchar(32)
)
create index 索引名 on 表 (列1,列名2);

可以使用like,但是前面不能帶%,后面可以帶%好
如果非要使用%進行模糊查詢,並且使用索引。可以 like '000%111' 這樣寫。加如按照訂單號進行模糊查詢。訂單在存儲的時候,默認在前面加上000,這樣就可以實現模糊查詢,而不使索引生效

3. 普通索引

普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。
因此,應該只為那些最經常出現在查詢條件(WHERE column=)或排序條件(ORDERBY column)中的數據列創建索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如一個整數類型的數據列)來創建索引。

4. 唯一索引(唯一索引可以為null)

這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。唯一性索引可以用以下幾種方式創建:

create unique index 索引名稱 on tablename (列的名稱)

修改表的時候

alter table tablename  add unique 索引名稱 (列的名稱)

注意:

  • unique字段可以為NULL,並可以有多NULL, 但是如果是具體內容,則不能重復,但是不能存有重復的空字符串’’
  • 可以使用like,但是前面不能帶%,后面可以帶%好

5. 組合索引(聯合索引)

多列值組成一個索引,專門用於組合搜索,其效率大於索引合並。
只有在查詢條件中使用了創建索引時的第一個字段,索引才會被使用。使用組合索引時遵循最左前綴集合。
a. 建表的時候一起創建

CREATE TABLE mytable (`id` int(11) ,`name` VARCHAR(32) ,INDEX index_mytable_id_name (`id`,`name`));

b. 建表后,直接創建索引

CREATE INDEX index_mytable_id_name ON mytable(id,name);

c. 修改表結構

ALTER TABLE mytable ADD INDEX index_mytable_id_name (id,name);

聯合索引的注意事項

一定要和第一部分的索引一起使用
不要加or關鍵字
可以使用like,但是like不要加上模糊內容前面加上%,后面可以加%
如果列類型是字符串,一定要使用''號引起來
如果mysql估計使用全表掃描要比使用索引快,則不使用索引。

索引的代價

  • 占用磁盤空間(索引保存在對應表后綴名為MYI文件中)

frm、MYD、MYI是myisam引擎表的結構文件、數據文件、索引文件。
frm、ibd是innodb引擎表的結構文件、數據和索引文件。

哪些列適合加索引。

  • 經常作為查詢條件的列應該創建索引
  • 不會出現在where語句后面的不應該創建索引。
  • 頻繁更新的字段,也不應該創建索引
  • 唯一性太差的字段,不適合創建索引,即使更新很頻繁。
    • 如:select * from emp where sex = '男'

總結:滿足以下條件的字段,才應該創建索引。

  • 肯定在where中經常使用的
  • 該字段內容不是唯一的幾個值
  • 字段內容不是頻繁變化的
  • 如果不加索引和加上索引效率差不多,就不要加索引了。

索引創建的方法

ALTER table 表名 ADD [UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY [索引名] (字段名1 [(長度)] [ASC | DESC]) [USING 索引方法];
-- 或
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX 索引名 ON 表名(字段名) [USING 索引方法];

刪除索引

DROP INDEX 索引名 ON 表名
-- 或
ALTER TABLE 表名 DROP INDEX 索引名

能說下myisam 和 innodb的區別嗎?

myisam引擎是5.5版本之前的默認引擎,支持全文檢索、壓縮、空間函數等,但是不支持事務和行級鎖,所以一般用於有大量查詢少量插入的場景來使用,而且myisam不支持外鍵,並且索引和數據是分開存儲的。
innodb是基於聚簇索引建立的,和myisam相反它支持事務、外鍵,並且通過MVCC來支持高並發,索引和數據存儲在一起。

支持全文索引(MyISAM支持全文索引,INNODB不支持全文索引)
鎖機制(MyISAM時表鎖,innodb是行鎖)

說下mysql的索引有哪些吧,聚簇和非聚簇索引又是什么?

索引按照數據結構來說主要包含B+樹和Hash索引。

假設我們有張表,結構如下:

create table user( id int(11) not null, age int(11) not null, primary key(id), key(age) );

B+樹是左小右大的順序存儲結構,節點只包含id索引列,而葉子節點包含索引列和數據,這種數據和索引在一起存儲的索引方式叫做聚簇索引,一張表只能有一個聚簇索引。假設沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替,如果沒有的話則會隱式定義一個主鍵作為聚簇索引。

那你知道什么是覆蓋索引和回表嗎?

覆蓋索引指的是在一次查詢中,如果一個索引包含或者說覆蓋所有需要查詢的字段的值,我們就稱之為覆蓋索引,而不再需要回表查詢。
而要確定一個查詢是否是覆蓋索引,我們只需要explain sql語句看Extra的結果是否是“Using index”即可。
// 加入說又一個表。有三個字段,id(主鍵),username(普通索引),sex
那么 select * from user where username = "liufei"; // 這種是沒有使用覆蓋索引的,回表查詢了
如果 select id,username where username = "liufei"; // 這種就使用了覆蓋索引。
因為索引中沒有sex,當命中username索引時,索引的葉子節點存儲了id,還需要通過id去找sex字段。
那么怎么樣使用覆蓋索引將三個字段全部查詢出來??
將username的普通索引,升級成username和sex的聯合索引。

這就是所謂的回表查詢,先定位主鍵值,再定位行記錄,它的性能較掃一遍索引樹更低。

詳情查看:https://www.cnblogs.com/myseries/p/11265849.html

mysql鎖的類型有哪些?

mysql的鎖分為共享鎖和排他鎖,也叫做讀鎖和寫鎖。
讀鎖是共享的,可以通過lock in share mode實現,這時候只能讀不能寫。
寫鎖是排他的,它會阻塞其他的寫鎖和讀鎖。從顆粒度來區分,可以分為表鎖和行鎖兩種。
表鎖會鎖定整張表並且阻塞其他用戶對該表的所有讀寫操作,比如alter修改表結構的時候會鎖表。
行鎖又可以分為樂觀鎖和悲觀鎖,悲觀鎖可以通過for update實現,樂觀鎖則通過版本號實現。

你能說下事務的基本特性和隔離級別嗎?

事務基本特性ACID分別是:

  • 原子性(Atomicity):事務是一個完整的操作,事務的各部分是不可分割的(原子),要么都執行,要么都不執行。
  • 一致性(consistency):當事務完成時,數據必須處於一致性。
  • 隔離型(isolation):是指一個事務的修改在最終提交前,對其他事務是不可見的。
  • 永久性(durability):是指事務一旦提交,所做的修改就會永久保存到數據庫中。

而隔離性有4個隔離級別,分別是:

  • 讀未提交(read uncommit)。可能會讀到其他事務未提交的數據,也叫做臟讀。
    用戶本來應該讀取到id=1的用戶age應該是10,結果讀取到了其他事務還沒有提交的事務,結果讀取結果age=20,這就是臟讀。

  • read commit 讀已提交,兩次讀取結果不一致,叫做不可重復讀(通常針對數據更新(UPDATE)操作)。
    不可重復讀解決了臟讀的問題,他只會讀取已經提交的事務。
    用戶開啟事務讀取id=1用戶,查詢到age=10,再次讀取發現結果=20,在同一個事務里同一個查詢讀取到不同的結果叫做不可重復讀。

  • repeatable read 可重復復讀,這是mysql的默認級別,就是每次讀取結果都一樣,但是有可能產生幻讀(通常針對數據插入(INSERT)操作)。

  • serializable 串行,一般是不會使用的,他會給每一行讀取的數據加鎖,會導致大量超時和鎖競爭的問題。

事務隔離級別 臟讀 不可重復讀 幻讀
讀未提交(read-uncommitted)
不可重復讀(read-committed)
可重復讀(repeatable-read)
串行化(serializable)

二、事務的並發問題
  1、臟讀:事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據
  2、不可重復讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果 不一致。
  3、幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。

  小結:不可重復讀的和幻讀很容易混淆,不可重復讀側重於修改,幻讀側重於新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表

那ACID靠什么保證的呢?

A原子性由undo log日志保證,它記錄了需要回滾的日志信息,事務回滾時撤銷已經執行成功的sql

C一致性一般由代碼層面來保證

I隔離性由MVCC來保證

D持久性由內存+redo log來保證,mysql修改數據同時在內存和redo log記錄這次操作,事務提交的時候通過redo log刷盤,宕機的時候可以從redo log恢復

那你說說什么是幻讀,什么是MVCC?

要說幻讀,首先要了解MVCC,MVCC叫做多版本並發控制,實際上就是保存了數據在某個時間節點的快照。

我們每行數實際上隱藏了兩列,創建時間版本號,過期(刪除)時間版本號,每開始一個新的事務,版本號都會自動遞增。

還是拿上面的user表舉例子,假設我們插入兩條數據,他們實際上應該長這樣。

a-draft-type=“table” data-size=“normal” data-row-style=“normal”>
id name create_version delete_version
這時候假設小明去執行查詢,此時current_version=3

select * from user where id<=3; 復制代碼

同時,小紅在這時候開啟事務去修改id=1的記錄,current_version=4

update user set name=‘張三三’ where id=1; 復制代碼

執行成功后的結果是這樣的

a-draft-type=“table” data-size=“normal” data-row-style=“normal”>
id name create_version delete_version
如果這時候還有小黑在刪除id=2的數據,current_version=5,執行后結果是這樣的。

a-draft-type=“table” data-size=“normal” data-row-style=“normal”>
id name create_version delete_version
由於MVCC的原理是查找創建版本小於或等於當前事務版本,刪除版本為空或者大於當前事務版本,小明的真實的查詢應該是這樣

select * from user where id<=3 and create_version<=3 and (delete_version>3 or delete_version is null); 復制代碼

所以小明最后查詢到的id=1的名字還是’張三’,並且id=2的記錄也能查詢到。這樣做是為了保證事務讀取的數據是在事務開始前就已經存在的,要么是事務自己插入或者修改的。

明白MVCC原理,我們來說什么是幻讀就簡單多了。舉一個常見的場景,用戶注冊時,我們先查詢用戶名是否存在,不存在就插入,假定用戶名是唯一索引。

小明開啟事務current_version=6查詢名字為’王五’的記錄,發現不存在。
小紅開啟事務current_version=7插入一條數據,結果是這樣:
a-draft-type=“table” data-size=“normal” data-row-style=“normal”>
id Name create_version delete_version
小明執行插入名字’王五’的記錄,發現唯一索引沖突,無法插入,這就是幻讀。

一條SQL的執行過程

參考連接

MySQL 基本架構概覽:

  • 連接器: 身份認證和權限相關(登錄 MySQL 的時候)。

連接器主要和身份認證和權限相關的功能相關,就好比一個級別很高的門衛一樣。
主要負責用戶登錄數據庫,進行用戶的身份認證,包括校驗賬戶密碼,權限等操作,如果用戶賬戶密碼已通過,連接器會到權限表中查詢該用戶的所有權限,之后在這個連接里的權限邏輯判斷都是> 會依賴此時讀取到的權限數據,也就是說,后續只要這個連接不斷開,即時管理員修改了該用戶的權限,該用戶也是不受影響的。

  • 查詢緩存: 執行查詢語句的時候,會先查詢緩存(MySQL 8.0 版本后移除,因為這個功能不太實用)。

查詢緩存主要用來緩存我們所執行的 SELECT 語句以及該語句的結果集。
連接建立后,執行查詢語句的時候,會先查詢緩存,MySQL 會先校驗這個 sql 是否執行過,以 Key-Value 的形式緩存在內存中,Key 是查詢預計,Value 是結果集。如果緩存 key 被命中,就會> > 直接返回給客戶端,如果沒有命中,就會執行后續的操作,完成后也會把結果緩存起來,方便下一次調用。當然在真正執行緩存查詢的時候還是會校驗用戶的權限,是否有該表的查詢條件。
MySQL 查詢不建議使用緩存,因為查詢緩存失效在實際業務場景中可能會非常頻繁,假如你對一個表更新的話,這個表上的所有的查詢緩存都會被清空。對於不經常更新的數據來說,使用緩存還是可以的。
所以,一般在大多數情況下我們都是不推薦去使用查詢緩存的。

  • 分析器: 沒有命中緩存的話,SQL 語句就會經過分析器,分析器說白了就是要先看你的 SQL 語句要干嘛,再檢查你的 SQL 語句語法是否正確。

MySQL 沒有命中緩存,那么就會進入分析器,分析器主要是用來分析 SQL 語句是來干嘛的,分析器也會分為幾步:
第一步,詞法分析,一條 SQL 語句有多個字符串組成,首先要提取關鍵字,比如 select,提出查詢的表,提出字段名,提出查詢條件等等。做完這些操作后,就會進入第二步。
第二步,語法分析,主要就是判斷你輸入的 sql 是否正確,是否符合 MySQL 的語法。
完成這 2 步之后,MySQL 就准備開始執行了,但是如何執行,怎么執行是最好的結果呢?這個時候就需要優化器上場了。

  • 優化器: 按照 MySQL 認為最優的方案去執行。

優化器的作用就是它認為的最優的執行方案去執行(有時候可能也不是最優,這篇文章涉及對這部分知識的深入講解),比如多個索引的時候該如何選擇索引,多表查詢的時候如何選擇關聯順序等。
可以說,經過了優化器之后可以說這個語句具體該如何執行就已經定下來。

  • 執行器: 執行語句,然后從存儲引擎返回數據。

當選擇了執行方案后,MySQL 就准備開始執行了,首先執行前會校驗該用戶有沒有權限,如果沒有權限,就會返回錯誤信息,如果有權限,就會去調用引擎的接口,返回接口執行的結果。

簡單來說 MySQL 主要分為 Server 層和存儲引擎層:
•Server 層:主要包括連接器、查詢緩存、分析器、優化器、執行器等,所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖,函數等,還有一個通用的日志模塊 binglog 日志模塊。
•存儲引擎: 主要負責數據的存儲和讀取,采用可以替換的插件式架構,支持 InnoDB、MyISAM、Memory 等多個存儲引擎,其中 InnoDB 引擎有自有的日志模塊 redolog 模塊。現在最常用的存儲引擎是 InnoDB,它從 MySQL 5.5.5 版本開始就被當做默認存儲引擎了。

總結

  • MySQL 主要分為 Server 層和引擎層,Server 層主要包括連接器、查詢緩存、分析器、優化器、執行器,同時還有一個日志模塊(binlog),這個日志模塊所有執行引擎都可以共用,redolog 只有 InnoDB 有。
  • 引擎層是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
  • SQL 等執行過程分為兩類,一類對於查詢等過程如下:權限校驗---》查詢緩存---》分析器---》優化器---》權限校驗---》執行器---》引擎
  • 對於更新等語句執行流程如下:分析器----》權限校驗----》執行器---》引擎---redo log prepare---》binlog---》redo log commit

你們數據量級多大?分庫分表怎么做的?

首先分庫分表分為垂直和水平兩個方式,一般來說我們拆分的順序是先垂直后水平。

垂直分庫

基於現在微服務拆分來說,都是已經做到了垂直分庫了。

垂直分表
如果表字段比較多,將不常用的、數據較大的等等做拆分。

水平分表

首先根據業務場景來決定使用什么字段作為分表字段(sharding_key),比如我們現在日訂單1000萬,我們大部分的場景來源於C端,我們可以用user_id作為sharding_key,數據查詢支持到最近3個月的訂單,超過3個月的做歸檔處理,那么3個月的數據量就是9億,可以分1024張表,那么每張表的數據大概就在100萬左右。

比如用戶id為100,那我們都經過hash(100),然后對1024取模,就可以落到對應的表上了。

那分表后的ID怎么保證唯一性的呢?

因為我們主鍵默認都是自增的,那么分表之后的主鍵在不同表就肯定會有沖突了。有幾個辦法考慮:

  • 設定步長,比如1-1024張表我們分別設定1-1024的基礎步長,這樣主鍵落到不同的表就不會沖突了。
  • 分布式ID,自己實現一套分布式ID生成算法或者使用開源的比如雪花算法這種。
  • 分表后不使用主鍵作為查詢依據,而是每張表單獨新增一個字段作為唯一主鍵使用,比如訂單表訂單號是唯一的,不管最終落在哪張表都基於訂單號作為查詢依據,更新也一樣。
  • 利⽤ redis ⽣成 id : 性能⽐᫾好,靈活⽅便,不依賴於數據庫。但是,引⼊了新的組件造成系統更加復雜,可⽤性降低,編碼更加復雜,增加了系統成本。
  • 美團的Leaf分布式ID⽣成系統 :Leaf 是美團開源的分布式ID⽣成器,能保證全局唯⼀性、趨勢遞增、單調遞增、信息安全,⾥⾯也提到了⼏種分布式⽅案的對⽐,但也需要依賴關系數據庫、Zookeeper等中間件。感覺還不錯。美團技術團隊的⼀篇⽂章:https://tech.meituan.com/2017/04/21/mt-leaf.html

主從復制的應用場景

通過主從復制,可以實現數據的備份、故障轉移、MySQl集群、高可用、讀寫分離等。
MySQL的主從復制是MySQL本身自帶的一個功能,不需要額外的第三方就可以實現,其復制的功能是借助binlog二進制日志文件里面的SQL命令實現的主從復制,可以理解為我Matster端執行了一條SQL命令,那么Slave端同樣會執行一遍,從而達到主從復制的效果。

說說mysql主從同步怎么做的?


Binary log:主數據庫的二進制日志。
Relay log:從服務器的中繼日志。

第一步:master在每個事務更新數據完成之前,將該操作記錄串行地寫入到binlog文件中。
第二步:salve開啟一個I/O Thread,該線程在master打開一個普通連接,主要工作是binlog dump process。如果讀取的進度已經跟上了master,就進入睡眠狀態並等待master產生新的事件。I/O線程最終的目的是將這些事件寫入到中繼日志中。
第三步:SQL Thread會讀取中繼日志,並順序執行該日志中的SQL事件,從而與主數據庫中的數據保持一致。

全同步復制
主庫寫入binlog后強制同步日志到從庫,所有的從庫都執行完成后才返回給客戶端,但是很顯然這個方式的話性能會受到嚴重影響。

半同步復制
和全同步不同的是,半同步復制的邏輯是這樣,從庫寫入日志成功后返回ACK確認給主庫,主庫收到至少一個從庫的確認就認為寫操作完成。

那主從的延遲怎么解決呢?

這個問題貌似真的是個無解的問題,只能是說自己來判斷了,需要走主庫的強制走主庫查詢。

  • 方法一:忽略錯誤后,繼續同步
  • 方式二:重新做主從,完全同步

什么是慢查詢?

MySQL默認10秒內沒有響應SQL結果,則為慢查詢
可以去修改MySQL慢查詢默認時間

-- 查詢慢查詢時間
show variables like 'long_query_time';
-- 修改慢查詢時間
set long_query_time=1; ---但是重啟mysql之后,long_query_time依然是my.ini中的值

如何將慢查詢定位到日志中
在默認情況下,我們的mysql不會記錄慢查詢,需要在啟動mysql時候,指定記錄慢查詢才可以
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模式啟動,數據庫將操作寫入日志,以備恢復)
bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]
先關閉mysql,再啟動, 如果啟用了慢查詢日志,默認把這個文件放在
my.ini 文件中記錄的位置

Path to the database root

datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"

mysql5.7下的
在/etc/my.cnf的配置文件下添加下面這個

[mysqld]
-- 下面這三個必須填寫在mysqld下
slow_query_log=ON
slow_query_log_file=/var/log/mysql/slow_query.log
long_query_time=1

注意:
slow_query_log=ON 開啟MySQL的慢查詢。
slow_query_log_file=/var/log/mysql/slow_query.log 指定日志的文件
long_query_time=1 設置慢查詢的時間,默認是10s

然后重啟MySQL

service mysql restart

SQL優化的技巧

  • 查詢SQL盡量不要使用select *,而是select具體字段。
  • 如果知道查詢結果只有一條或者只要最大/最小一條記錄,建議用limit 1
  • 應盡量避免在where子句中使用or來連接條件,否則將導致引擎放棄使用索引而進行全表掃描, 可以 使用UNION合並查詢:
select id from t where num=10 
union all 
select id from t where num=20
  • 有些情況下,可以使用連接來替代子查詢。因為使用join,MySQL不需要在內存中創建臨時表。
select * from dept, emp where dept.deptno=emp.deptno; [簡單處理方式]
select * from dept left join emp on dept.deptno=emp.deptno;  [左外連接,更ok!]
  • 對查詢進行優化,要盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引
  • 應盡量避免在 where 子句中使用!=或<>操作符, MySQL只有對以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE
  • in 和 not in 也要慎用,否則會導致全表掃描
    對於連續的數值,能用 between 就不要用 in 了:
Select id from t where num between 1 and 3
  • 對於like的用法,前后都加%和前面加%將導致全表掃描,而%放到最后才會用到索引。
  • 索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
  • 使用聯合索引時,注意索引列的順序,一般遵循最左匹配原則。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM