主頁 > 後端開發 > 95%的人都不知道 MySQL還有索引管理與執行計劃

95%的人都不知道 MySQL還有索引管理與執行計劃

2020-12-17 06:49:20 後端開發

1.1 索引的介紹

  索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊,如果想按特定職員的姓來查找他或她,則與在表中搜索所有的行相比,索引有助于更快地獲取資訊,

  索引的一個主要目的就是加快檢索表中資料的方法,亦即能協助資訊搜索者盡快的找到符合限制條件的記錄ID的輔助資料結構,

file

1.1.1 唯一索引

  唯一索引是不允許其中任何兩行具有相同索引值的索引,當現有資料中存在重復的鍵值時,大多數資料庫不允許將新創建的唯一索引與表一起保存,資料庫還可能防止添加將在表中創建重復鍵值的新資料,

  例如,如果在employee表中職員的姓(lname)上創建了唯一索引,則任何兩個員工都不能同姓,

1.1.2 主鍵索引

  資料庫表經常有一列或多列組合,其值唯一標識表中的每一行,該列稱為表的主鍵,在資料庫關系圖中為表定義主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特定型別,

  該索引要求主鍵中的每個值都唯一,當在查詢中使用主鍵索引時,它還允許對資料的快速訪問,

1.1.3 聚集索引

  在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同,一個表只能包含一個聚集索引,如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配,與非聚集索引相比,聚集索引通常提供更快的資料訪問速度,

  聚集索引和非聚集索引的區別,如字典默認按字母順序排序,讀者如知道某個字的讀音可根據字母順序快速定位,因此聚集索引和表的內容是在一起的,如讀者需查詢某個生僻字,則需按字典前面的索引,舉例按偏旁進行定位,找到該字對應的頁數,再打開對應頁數找到該字,

  這種通過兩個地方而查詢到某個字的方式就如非聚集索引,

1.1.4 索引列

  可以基于資料庫表中的單列或多列創建索引,多列索引可以區分其中一列可能有相同值的行,如果經常同時搜索兩列或多列或按兩列或多列排序時,索引也很有幫助,

  例如,如果經常在同一查詢中為姓和名兩列設定判據,那么在這兩列上創建多列索引將很有意義,

  檢查查詢的WHERE和JOIN子句,在任一子句中包括的每一列都是索引可以選擇的物件,對新索引進行試驗以檢查它對運行查詢性能的影響,考慮已在表上創建的索引數量,最好避免在單個表上有很多索引,

  檢查已在表上創建的索引的定義,最好避免包含共享列的重疊索引,

檢查某列中唯一資料值的數量,并將該數量與表中的行數進行比較,比較的結果就是該列的可選擇性,這有助于確定該列是否適合建立索引,如果適合,確定索引的型別,

1.1.5 B樹演算法

file
  B樹的搜索,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那么就命中;否則,如果查詢關鍵字比結點關鍵字小,就進入左邊;如果比結點關鍵字大,就進入右邊;如果左邊或右邊的指標為空,則報告找不到相應的關鍵,

如果B樹的所有非葉子結點的左右子樹的結點數目均保持差不多(平衡),那么B樹的搜索性能逼近二分查找;但它比連續記憶體空間的二分查找的優點是,改變B樹結構(插入與洗掉結點)不需要移動大段的記憶體資料,甚至通常是常數開銷,

1.1.6 B+樹演算法

B+樹是B-樹的變體,也是一種多路搜索樹:

       1.其定義基本與B-樹同,除了:
       2.非葉子結點的子樹指標與關鍵字個數相同;
       3.非葉子結點的子樹指標P[i],指向關鍵字值屬于[K[i], K[i+1])的子樹(B-樹是開區間);
       5.為所有葉子結點增加一個鏈指標;
       6.所有關鍵字都在葉子結點出現;
       如:(M=3)

file
   B+的搜索與B-樹也基本相同,區別是B+樹只有達到葉子結點才命中(B-樹可以在非葉子結點命中),其性能也等價于在關鍵字全集做一次二分查找;

? B+的特性:

       1.所有關鍵字都出現在葉子結點的鏈表中(稠密索引),且鏈表中的關鍵字恰好是有序的;
       2.不可能在非葉子結點命中;
       3.非葉子結點相當于是葉子結點的索引(稀疏索引),葉子結點相當于是存盤(關鍵字)資料的資料層;
       4.更適合檔案索引系統;

1.1.7 HASH:HASH演算法

  哈希索引只有Memory, NDB兩種引擎支持,Memory引擎默認支持哈希索引,如果多個hash值相同,出現哈希碰撞,那么索引以鏈表方式存盤,

  但是,Memory引擎表只對能夠適合機器的記憶體切實有限的資料集,

  要使InnoDB或MyISAM支持哈希索引,可以通過偽哈希索引來實作,叫自適應哈希索引,

  主要通過增加一個欄位,存盤hash值,將hash值建立索引,在插入和更新的時候,建立觸發器,自動添加計算后的hash到表里,

1.1.8 其他的索引

FULLTEXT:全文索引
RTREE:R樹索引

1.2 MySQL索引管理

  索引建立在表的列上(欄位)的,

  在where后面的列建立索引才會加快查詢速度,

  pages<---索引(屬性)<----查資料,

添加索引的方法:

alter table test add index index_name(name);
create index index_name on test(name);

語法格式:

alter table 表 add index 索引名稱(name);

1.2.1 創建普通索引

創建普通索引方法一:

mysql> ALTER TABLE PLAYERS ADD INDEX   name_idx(NAME);
mysql> desc PLAYERS;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| NAME       | char(15)    | NO   | MUL | NULL    |       |

創建普通索引方法二:

mysql> ALTER TABLE PLAYERS ADD INDEX   name_idx(NAME);
mysql> desc PLAYERS;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| NAME       | char(15)    | NO   | MUL | NULL    |       |

1.2.2 洗掉索引

alter table PLAYERS delete INDEX  name_idx;
mysql> show index from  PLAYERS\G
*************************** 1. row ***************************
        Table: PLAYERS
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: PLAYERNO
    Collation: A
  Cardinality: 14
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment:

1.3 MySQL中的約束索引

主鍵索引

  只能有一個主鍵,

  主鍵索引:列的內容是唯一值,例如學號.

  表創建的時候至少要有一個主鍵索引,最好和業務無關,

普通索引

  加快查詢速度,作業中優化資料庫的關鍵,

  在合適的列上建立索引,讓資料查詢更高效,

create index index_name on test(name);
alter table test add index index_name(name);

用了索引,查一堆內容,

  在where條件關鍵字后面的列建立索引才會加快查詢速度.

select id,name from test where state=1 order by id group by name;

唯一索引

  內容唯一,但不是主鍵,

create unique index index_name on test(name);

1.3.1 創建主鍵索引

  建立表時

CREATE TABLE `test` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

  建立表后增加

CREATE TABLE `test` (
`id` int(4) NOT NULL,
`name` char(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

增加自增主鍵

alter table test change id id int(4) primary key 
not null auto_increment;

1.3.2 使用欄位前綴創建索引及聯合索引

前綴索引:根據欄位的前N個字符建立索引

create index index_name on test(name(8));

聯合索引:多個欄位建立一個索引,

where a女生 and b身高165 and c身材好
index(a,b,c)

  特點:前綴生效特性,

a,ab,abc 可以走索引,
b ac bc c 不走索引(5.6之后 ac 可以走主鍵索引),

  原則:把最常用來作為條件查詢的列放在前面,

*示例:*

創建表

 create table people (id int not null auto_increment ,name char(20),sr(20),sex int ,age int, primary key (id));

創建聯合索引

mysql> alter table people  add key name_sex_idx(name,sex)
    -> ;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看索引的型別

mysql> desc people;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(20) | YES  | MUL | NULL    |                |
| sex   | int(11)  | YES  |     | NULL    |                |
| age   | int(11)  | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+

建立唯一鍵索引

mysql> alter table people add unique key age_uidx(age);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看資料表

mysql> desc people;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(20) | YES  | MUL | NULL    |                |
| sex   | int(11)  | YES  |     | NULL    |                |
| age   | int(11)  | YES  | UNI | NULL    |                |
+-------+----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

  聯合主鍵是聯合索引的特殊形式

PRIMARY KEY (`Host`,`User`)
alter table test add sex char(4) not null;
create index ind_name_sex on test(name,sex);

前綴加聯合索引

create index index_name on test(name(8),sex(2));

1.4 SQL陳述句優化

1.4.1 企業SQL優化思路

  1、把一個大的不使用索引的SQL陳述句按照功能進行拆分

  2、長的SQL陳述句無法使用索引,能不能變成2條短的SQL陳述句讓它分別使用上索引,

  3、對SQL陳述句功能的拆分和修改

  4、減少“爛”SQL由運維(DBA)和開發交流(確認),共同確定如何改,最終由DBA執行

  5、制定開發流程

1.4.2 不適合走索引的場景

  1、唯一值少的列上不適合建立索引或者建立索引效率低,例如:性別列

  2、小表可以不建立索引,100條記錄,

  3、對于資料倉庫,大量全表掃描的情況,建索引反而會慢

1.4.3 查看表的唯一值數量

select count(distinct user) from mysql.user;
select count(distinct user,host) from mysql.user;

1.4.4 建立索引流程

  1、找到慢SQL,

show processlist;

    記錄慢查詢日志,

  2、explain select句,條件列多,

  3、查看表的唯一值數量:

select count(distinct user) from mysql.user;
select count(distinct user,host) from mysql.user;

    條件列多,可以考慮建立聯合索引,

  4、建立索引(流量低谷)

force index

  5、拆開陳述句(和開發),

  6、like '%%'不用mysql

  7、進行判斷重復的行數

查看行數:

mysql> select count(*) from city;
+----------+
| count(*) |
+----------+
|     4079 |
+----------+
1 row in set (0.00 sec)

查看去重后的行數:

mysql> select count(distinct countrycode) from city;
+-----------------------------+
| count(distinct countrycode) |
+-----------------------------+
|                         232 |
+-----------------------------+
1 row in set (0.00 sec)

1.5 用explain查看SQL的執行計劃

  在作業中,我們用于捕捉性能問題最常用的就是打開慢查詢,定位執行效率差的SQL,那么當我們定位到一個SQL以后還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃描,這些都需要通過EXPLAIN去完成,

  EXPLAIN命令是查看優化器如何決定執行查詢的主要方法,可以幫助我們深入了解MySQL的基于開銷的優化器,還可以獲得很多可能被優化器考慮到的訪問策略的細節,以及當運行SQL陳述句時哪種策略預計會被優化器采用,

  需要注意的是,生成的QEP并不確定,它可能會根據很多因素發生改變,MySQL不會將一個QEP和某個給定查詢系結,QEP將由SQL陳述句每次執行時的實際情況確定,即便使用存盤程序也是如此,盡管在存盤程序中SQL陳述句都是預先決議過的,但QEP仍然會在每次呼叫存盤程序的時候才被確定,

1.5.1 查看 select 陳述句的執行程序

mysql> explain select id,name from test where name='clsn';
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
|  1 | SIMPLE      | test  | ref  | name_idx      | name_idx | 24      | const |    1 | Using where |
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)

  SQL_NO_CACHE的作用是禁止快取查詢結果,

使用where****條件查找

mysql> explain select user,host from mysql.user where user='root' and host='127.0.0.1';
+----+-------------+-------+-------+---------------+---------+---------+-------------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref         | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+-------------+------+-------------+
|  1 | SIMPLE      | user  | const | PRIMARY       | PRIMARY | 228     | const,const |    1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+-------------+------+-------------+
1 row in set (0.00 sec)

1.5.2 通過執行計劃可以知道什么?

mysql> explain select d1.age, t2.id from (select age,name from t1 where id in (1,2))d1, t2 where d1.age=t2.age group by d1.age, t2.id order by t2.id;
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref    | rows | Extra                           |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL   |    2 | Using temporary; Using filesort |
|  1 | PRIMARY     | t2         | ref   | age           | age     | 5       | d1.age |    1 | Using where; Using index        |
|  2 | DERIVED     | t1         | range | PRIMARY       | PRIMARY | 4       | NULL   |    2 | Using where                     |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
3 rows in set (0.00 sec)

1.5.3 MySQL執行計劃呼叫方式

1.EXPLAIN SELECT ……
2.EXPLAIN EXTENDED SELECT ……
  將執行計劃"反編譯"成SELECT陳述句,運行SHOW WARNINGS 可得到被MySQL優化器優化后的查詢陳述句
3.EXPLAIN PARTITIONS SELECT ……
  用于磁區表的EXPLAIN生成QEP的資訊

1.5.4 執行計劃包含的資訊

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

1.5.5 id

  包含一組數字,表示查詢中執行select子句或操作表的順序

【示例一】id相同,執行順序由上至下

mysql> explain select t2.* from t1, t2, t3 where t1.id=t2.id and t1.id=t3.id and t1.name='';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra                    |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
|  1 | SIMPLE      | t1    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where; Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 |                          |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index              |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
3 rows in set (0.00 sec)

【示例二】如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行

mysql> explain select t2.* from t2 where id = (select id from t1 where id = (select t3.id from t3 where t3.name=''));
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | PRIMARY     | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
|  2 | SUBQUERY    | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | no matching row in const table                      |
|  3 | SUBQUERY    | t3    | ref  | name          | name | 63      |      |    1 | Using where; Using index                            |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
3 rows in set (0.00 sec)

【示例三】id如果相同,可以認為是一組,從上往下順序執行;在所有組中,id值越大,優先級越高,越先執行

mysql> explain select t2.* from (select t3.id from t3 where t3.name='')s1, t2 where s1.id=t2.id;
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref   | rows | Extra                    |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL  |    1 |                          |
|  1 | PRIMARY     | t2         | const  | PRIMARY       | PRIMARY | 4       | const |    1 |                          |
|  2 | DERIVED     | t3         | ref    | name          | name    | 63      |       |    1 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
3 rows in set (0.00 sec)

1.5.6 select_type

示查詢中每個select子句的型別(簡單OR復雜)
    a. SIMPLE:查詢中不包含子查詢或者UNION
    b. 查詢中若包含任何復雜的子部分,最外層查詢則被標記為:PRIMARY
    c. 在SELECT或WHERE串列中包含了子查詢,該子查詢被標記為:SUBQUERY
    d. 在FROM串列中包含的子查詢被標記為:DERIVED(衍生)用來表示包含在from子句中的子查詢的select,mysql會遞回執行并將結果放到一個臨時表中,服務器內部稱為"派生表",因為該臨時表是從子查詢中派生出來的
    e. 若第二個SELECT出現在UNION之后,則被標記為UNION;若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為:DERIVED
    f. 從UNION表獲取結果的SELECT被標記為:UNION RESULT

說明:

SUBQUERY和UNION還可以被標記為DEPENDENT和UNCACHEABLE,
DEPENDENT意味著select依賴于外層查詢中發現的資料,
UNCACHEABLE意味著select中的某些 特性阻止結果被快取于一個item_cache中,

【示例】

mysql> explain select d1.name, ( select id from t3) d2 from (select id,name from t1 where name='')d1 union (select name,id from t2);
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
| id | select_type  | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
|  1 | PRIMARY      | <derived3> | system | NULL          | NULL | NULL    | NULL |    0 | const row not found      |
|  3 | DERIVED      | t1         | ref    | name          | name | 63      |      |    1 | Using where; Using index |
|  2 | SUBQUERY     | t3         | index  | NULL          | age  | 5       | NULL |    6 | Using index              |
|  4 | UNION        | t2         | index  | NULL          | name | 63      | NULL |    4 | Using index              |
| NULL | UNION RESULT | <union1,4> | ALL    | NULL          | NULL | NULL    | NULL | NULL |                          |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
5 rows in set (0.00 sec)

內容說明:

第一行:id列為1,表示第一個select,select_type列的primary表 示該查詢為外層查詢,table列被標記為<derived3>,表示查詢結果來自一個衍生表,其中3代表該查詢衍生自第三個select查詢,即id為3的select,
第二行:id為3,表示該查詢的執行次序為2( 4 => 3),是整個查詢中第三個select的一部分,因查詢包含在from中,所以為derived,
第三行:select串列中的子查詢,select_type為subquery,為整個查詢中的第二個select,
第四行:select_type為union,說明第四個select是union里的第二個select,最先執行,
第五行:代表從union的臨時表中讀取行的階段,table列的<union1,4>表示用第一個和第四個select的結果進行union操作,

1.5.7 type

  表示MySQL在表中找到所需行的方式,又稱“訪問型別”,常見型別如下:

ALL, index,  range, ref, eq_ref, const, system, NULL

  從左到右,性能從最差到最好

【示例一】ALL:Full Table Scan, MySQL將遍歷全表以找到匹配的行

mysql> explain select * from t1 where email='';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

【示例二】index:Full Index Scan,index與ALL區別為index型別只遍歷索引樹

mysql> explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

【示例三】range:索引范圍掃描,對索引的掃描開始于某一點,回傳匹配值域的行,

顯而易見的索引范圍掃描是帶有between或者where子句里帶有<, >查詢,當mysql使用索引去查找一系列值時,例如IN()和OR串列,也會顯示range(范圍掃描),當然性能上面是有差異的,

mysql> explain select * from t1 where id in (1,4);
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from t1 where id between 1 and 4;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from t1 where id=1 or id=4;       
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec)
mysql> explain select * from t1 where id > 1;      
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

【示例四】ref:使用非唯一索引掃描或者唯一索引的前綴掃描,回傳匹配某個單獨值的記錄行

mysql> explain select * from t1 where name='guo';
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | t1    | ref  | name          | name | 63      | const |    1 | Using where |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
1 row in set (0.00 sec)

【示例五】eq_ref:類似ref,區別就在使用的索引是唯一索引,對于每個索引鍵值,表中只有一條記錄匹配,簡單來說,就是多表連接中使用primary key或者 unique key作為關聯條件,

mysql> explain select t1.name from t1, t2 where t1.id=t2.id;
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t1    | index  | PRIMARY       | name    | 63      | NULL       |    4 | Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
2 rows in set (0.00 sec)

【示例六】const、system:當MySQL對查詢某部分進行優化,并轉換為一個常量時,使用這些型別訪問,

  如將主鍵置于where串列中,MySQL就能將該查詢轉換為一個常量

mysql> explain select * from ( select * from t1 where id=1)b1;
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t1         | const  | PRIMARY       | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
2 rows in set (0.00 sec)

  *注:*system是const型別的特例,當查詢的表只有一行的情況下,使用system

【示例七】NULL:MySQL在優化程序中分解陳述句,執行時甚至不用訪問表或索引, 例如從一個索引列里選取最小值可以通過單獨索引查找完成,

mysql> explain select * from t1 where id = (select min(id) from t2);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra                        |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
|  1 | PRIMARY     | t1    | const | PRIMARY       | PRIMARY | 4       | const |    1 |                              |
|  2 | SUBQUERY    | NULL  | NULL  | NULL          | NULL    | NULL    | NULL  | NULL | Select tables optimized away |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
2 rows in set (0.00 sec)

1.5.8 possible_keys

  指出MySQL能使用哪個索引在表中找到記錄,查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢使用

1.5.9 key

  顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL

【示例】

mysql> explain select id,age from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

1.5.10 key_len

  表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度(key_len顯示的值為索引欄位的最大可能長度,并非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的),

1.5.11 ref

  表示上述表的連接匹配條件,即哪些列或常量被用于查找索引列上的值,

1.5.12 rows

  表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數,

【示例】

mysql> explain select * from t1 , t2 where t1.id=t2.id and t2.name='atlas';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t2    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where |
|  1 | SIMPLE      | t1    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t2.id |    1 |             |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
2 rows in set (0.00 sec)

1.5.13 Extra

  包含不適合在其他列中顯示但十分重要的額外資訊

【示例一】Using index

該值表示相應的select操作中使用了覆寫索引(Covering Index)

mysql> explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

    覆寫索引(Covering Index)

    MySQL可以利用索引回傳select串列中的欄位,而不必根據索引再次讀取資料檔案

    包含所有滿足查詢需要的資料的索引稱為覆寫索引(Covering Index)

    注意:如果要使用覆寫索引,一定要注意select串列中只取出需要的列,不可select *,因為如果將所有欄位一起做索引會導致索引檔案過大,查詢性能下降

【示例二】Using where

  表示mysql服務器將在存盤引擎檢索行后再進行過濾,許多where條件里涉及索引中的列,當(并且如果)它讀取索引時,就能被存盤引擎檢驗,因此不是所有帶where字句的查詢都會顯示"Using where",

  有時"Using where"的出現就是一個暗示:查詢可受益與不同的索引,

mysql> explain select id,name from t1 where id<4;
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | PRIMARY       | name | 63      | NULL |    4 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

【示例三】Using temporary

  表示MySQL需要使用臨時表來存盤結果集,常見于排序和分組查詢

  這個值表示使用了內部臨時(基于記憶體的)表,一個查詢可能用到多個臨時表,有很多原因都會導致MySQL在執行查詢期間創建臨時表,兩個常見的原因是在來自不同表的上使用了DISTINCT,或者使用了不同的ORDER BY和GROUP BY列,可以強制指定一個臨時表使用基于磁盤的MyISAM存盤引擎,這樣做的原因主要有兩個:

    1)內部臨時表占用的空間超過min(tmp_table_size,max_heap_table_size)系統變數的限制

    2)使用了TEXT/BLOB 列

mysql> explain select id from t1 where id in (1,2) group by age,name;
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
1 row in set (0.00 sec)

【示例四】Using filesort

  MySQL中無法利用索引完成的排序操作稱為“檔案排序”

mysql> explain select id,age from t1 order by name; 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
mysql> explain select id,age from t1 order by age; 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

【示例五】Using join buffer

  該值強調了在獲取連接條件時沒有使用索引,并且需要連接緩沖區來存盤中間結果,

  如果出現了這個值,那應該注意,根據查詢的具體情況可能需要添加索引來改進能,

mysql> explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref          | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | name          | name | 63      | NULL         |    4 | Using index              |
|  1 | SIMPLE      | t2    | ref   | name          | name | 63      | test.t1.name |    2 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
2 rows in set (0.00 sec)

洗掉t1索引

mysql> alter table t1 drop key name;                                   
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

洗掉t2索引

mysql> alter table t2 drop key name; 
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

經常查找

mysql> explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
2 rows in set (0.00 sec)

【示例六】Impossible where

  這個值強調了where陳述句會導致沒有符合條件的行,

mysql> EXPLAIN SELECT * FROM t1 WHERE 1=2;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
1 row in set (0.00 sec)

【示例七】Select tables optimized away

  這個值意味著僅通過使用索引,優化器可能僅從聚合函式結果中回傳一行.

mysql> explain select max(id) from t1;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

【示例八】Index merges

  當MySQL 決定要在一個給定的表上使用超過一個索引的時候,就會出現以下格式中的一個,詳細說明使用的索引以及合并的型別,

Using sort_union(...)
Using union(...)
Using intersect(...)

1.5.14 小結

  EXPLAIN不會告訴你關于觸發器、存盤程序的資訊或用戶自定義函式對查詢的影響情況,

  EXPLAIN不考慮各種Cache,

  EXPLAIN不能顯示MySQL在執行查詢時所作的優化作業,

  部分統計資訊是估算的,并非精確值,

  EXPALIN只能解釋SELECT操作,其他操作要重寫為SELECT后查看執行計劃,

1.6 mysql不走索引的原因

1.6.1 一些常見的原因

  1) 沒有查詢條件,或者查詢條件沒有建立索引

  2) 在查詢條件上沒有使用引導列

  3) 查詢的數量是大表的大部分,應該是30%以上,

  4) 索引本身失效

  5) 查詢條件使用函式在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等)

    錯誤的例子:select * from test where id-1=9; 正確的例子:select * from test where id=10;

  6) 對小表查詢

  7) 提示不使用索引

  8) 統計資料不真實

  9) CBO計算走索引花費過大的情況,其實也包含了上面的情況,這里指的是表占有的block要比索引小,

  10)隱式轉換導致索引失效.這一點應當引起重視.也是開發中經常會犯的錯誤.

    由于表的欄位tel_num定義為varchar2(20),但在查詢時把該欄位作為number型別以where條件傳給資料庫,這樣會導致索引失效.

      錯誤的例子:select * from test where tel_nume=13333333333;

      正確的例子:select * from test where tel_nume='13333333333';

  11) 注意使用的特殊符號

    1,<> ,!=

     2,單獨的>,<,(有時會用到,有時不會)

  12)like "%_" 百分號在前.

      select * from t1 where name like 'linux培訓%';

  13) not in ,not exist.

  14) in 盡量改成 union ,

  15)當變數采用的是times變數,而表的欄位采用的是date變數時.或相反情況,

  16)B-tree索引is null不會走,is not null會走,位圖索引 is null,is not null 都會走 ,

  17)聯合索引 is not null 只要在建立的索引列(不分先后)都會走,

  in null時 必須要和建立索引第一列一起使用,當建立索引第一位置條件是is null 時,其他建立索引的列可以是is null(但必須在所有列 都滿足is null的時候),或者=一個值;

  當建立索引的第一位置是=一個值時,其他索引列可以是任何情況(包括is null =一個值),以上兩種情況索引都會走,其他情況不會走,

1.6.2 需要注意的一些

1)    MyISAM 存盤引擎索引鍵長度總和不能超過1000 位元組;
2)    BLOB 和TEXT 型別的列只能創建前綴索引;
3)    MySQL 目前不支持函式索引;
4)    使用不等于(!= 或者<>)的時候MySQL 無法使用索引;
5)    過濾欄位使用了函式運算后(如abs(column)),MySQL 無法使用索引;
6)    Join 陳述句中Join 條件欄位型別不一致的時候MySQL 無法使用索引;
7)    使用LIKE 操作的時候如果條件以通配符開始( '%abc...')MySQL 無法使用索引;
8)    使用非等值查詢的時候MySQL 無法使用Hash 索引;
9)    在我們使用索引的時候,需要注意上面的這些限制,尤其是要注意無法使用索引的情況,因為這很容易讓我們因為疏忽而造成極大的性能隱患,

1.7 資料庫索引的設計原則

  為了使索引的使用效率更高,在創建索引時,必須考慮在哪些欄位上創建索引和創建什么型別的索引,

1.7.1 那么索引設計原則又是怎樣的

1.選擇唯一性索引

  唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄,

  例如,學生表中學號是具有唯一性的欄位,為該欄位建立唯一性索引可以很快的確定某個學生的資訊,如果使用姓名的話,可能存在同名現象,從而降低查詢速度,

2.為經常需要排序、分組和聯合操作的欄位建立索引

  經常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的欄位,排序操作會浪費很多時間,

如果為其建立索引,可以有效地避免排序操作,

3.為常作為查詢條件的欄位建立索引

  如果某個欄位經常用來做查詢條件,那么該欄位的查詢速度會影響整個表的查詢速度,因此,

  為這樣的欄位建立索引,可以提高整個表的查詢速度,

4.限制索引的數目

  索引的數目不是越多越好,每個索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大,修改表時,對索引的重構和更新很麻煩,越多的索引,會使更新表變得很浪費時間,

5.盡量使用資料量少的索引

  如果索引的值很長,那么查詢的速度會受到影響,例如,對一個CHAR(100)型別的欄位進行全文檢索需要的時間肯定要比對CHAR(10)型別的欄位需要的時間要多,

6.盡量使用前綴來索引

  如果索引欄位的值很長,最好使用值的前綴來索引,例如,TEXT和BLOG型別的欄位,進行全文檢索會很浪費時間,如果只檢索欄位的前面的若干個字符,這樣可以提高檢索速度,

7.洗掉不再使用或者很少使用的索引

  表中的資料被大量更新,或者資料的使用方式被改變后,原有的一些索引可能不再需要,資料庫管理員應當定期找出這些索引,將它們洗掉,從而減少索引對更新操作的影響,

8.小表不應建立索引

  包含大量的列并且不需要搜索非空值的時候可以考慮不建索引

1.8 參考文獻

https://baike.baidu.com/item/資料庫索引/8751686?fr=aladdin
https://www.cnblogs.com/oldhorse/archive/2009/11/16/1604009.html
http://blog.csdn.net/manesking/archive/2007/02/09/1505979.aspx
http://blog.csdn.net/woshiqjs/article/details/24135495

歡迎關注公眾號 【碼農開花】一起學習成長
我會一直分享Java干貨,也會分享免費的學習資料課程和面試寶典
回復:【計算機】【設計模式】【面試】有驚喜哦

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/235891.html

標籤:其他

上一篇:SpringCloud-Config組件使用

下一篇:Java Pattern和Matcher用法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more