欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    Mysql索引

    一、索引類型

    1.1、索引介紹

    索引可以提升查詢速度,會影響where查詢,以及order by排序。MySQL索引類型如下:

    • 從索引存儲結構劃分:B Tree索引、Hash索引、FULLTEXT全文索引、R Tree索引
    • 從應用層次劃分:普通索引、唯一索引、主鍵索引、復合索引
    • 從索引鍵值類型劃分:主鍵索引、輔助索引(二級索引)
    • 從數據存儲和索引鍵值邏輯關系劃分:聚集索引(聚簇索引)、非聚集索引(非聚簇索引)

    1.2、索引基礎回顧

    1、普通索引

    這是最基本的索引類型,基于普通字段建立的索引,沒有任何限制。

    創建普通索引的方法如下:

    CREATE INDEX <索引的名字> ON tablename (字段名);ALTER TABLE tablename ADD INDEX [索引的名字] (字段名);CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名) );

    查看索引的方法:

    show index from tableName;

    刪除索引的方法:

    drop index <索引名字> on <表名>;

    查看建表語句

    show create table users;show index from users;

    2、唯一索引

    與"普通索引"類似,不同的就是:索引字段的值必須唯一,但允許有空值 。在創建或修改表時追加唯一約束,就會自動創建對應的唯一索引。

    創建唯一索引的方法如下:

    CREATE UNIQUE INDEX <索引的名字> ON tablename (字段名);ALTER TABLE tablename ADD UNIQUE INDEX [索引的名字] (字段名);CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (字段名) ;

    3、主鍵索引

    它是一種特殊的唯一索引,不允許有空值。在創建或修改表時追加主鍵約束即可,每個表只能有一個主鍵。

    創建主鍵索引的方法如下:

    CREATE TABLE tablename ( [...], PRIMARY KEY (字段名) );ALTER TABLE tablename ADD PRIMARY KEY (字段名);

    4、復合索引

    單一索引是指索引列為一列的情況,即新建索引的語句只實施在一列上;用戶可以在多個列上建立索引,這種索引叫做復合索引(組合索引)。復合索引可以代替多個單一索引,相比多個單一索引復合索引所需的開銷更小。

    索引同時有兩個概念叫做窄索引和寬索引,窄索引是指索引列為1-2列的索引,寬索引也就是索引列超過2列的索引,設計索引的一個重要原則就是能用窄索引不用寬索引,因為窄索引往往比組合索引更有效。

    創建組合索引的方法如下:

    CREATE INDEX <索引的名字> ON tablename (字段名1,字段名2...);ALTER TABLE tablename ADD INDEX [索引的名字] (字段名1,字段名2...);CREATE TABLE tablename ( [...], INDEX [索引的名字] (字段名1,字段名2...) );

    復合索引使用注意事項:

    • 何時使用復合索引,要根據where條件建索引,注意不要過多使用索引,過多使用會對更新操作效率有很大影響。
    • 如果表已經建立了(col1,col2),就沒有必要再單獨建立(col1);如果現在有(col1)索引,如果查詢需要col1和col2條件,可以建立(col1,col2)復合索引,對于查詢有一定提高。

    5、全文索引

    查詢操作在數據量比較少時,可以使用like模糊查詢,但是對于大量的文本數據檢索,效率很低。如果使用全文索引,查詢速度會比like快很多倍。在MySQL 5.6 以前的版本,只有MyISAM存儲引擎支持全文索引,從MySQL 5.6開始MyISAM和InnoDB存儲引擎均支持。

    創建全文索引的方法如下:

    CREATE FULLTEXT INDEX <索引的名字> ON tablename (字段名);ALTER TABLE tablename ADD FULLTEXT [索引的名字] (字段名);CREATE TABLE tablename ( [...], FULLTEXT KEY [索引的名字] (字段名) ;

    和常用的like模糊查詢不同,全文索引有自己的語法格式,使用 match 和 against 關鍵字,比如

    select * from user where match(name) against('aaa');

    全文索引使用注意事項:

    • 全文索引必須在字符串、文本字段上建立。
    • 全文索引字段值必須在最小字符和最大字符之間的才會有效。(innodb:3-84;myisam:4-84)
    • 全文索引字段值要進行切詞處理,按syntax字符進行切割,例如b+aaa,切分成b和aaa
    • 全文索引匹配查詢,默認使用的是等值匹配,例如a匹配a,不會匹配ab,ac。如果想匹配可以在布爾模式下搜索a*

    select * from userwhere match(name) against('a*' in boolean mode);

    二、索引原理

    MySQL官方對索引定義:是存儲引擎用于快速查找記錄的一種數據結構。需要額外開辟空間和數據維護工作。

    索引是物理數據頁存儲,在數據文件中(InnoDB,ibd文件),利用數據頁(page)存儲。

    索引可以加快檢索速度,但是同時也會降低增刪改操作速度,索引維護需要代價。

    索引涉及的理論知識:二分查找法、Hash和B+Tree。

    2.1二分查找法

    二分查找法也叫作折半查找法,它是在有序數組中查找指定數據的搜索算法。它的優點是等值查詢、范圍查詢性能優秀,缺點是更新數據、新增數據、刪除數據維護成本高。

    • 首先定位left和right兩個指針
    • 計算(left+right)/2
    • 判斷除2后索引位置值與目標值的大小比對
    • 索引位置值大于目標值就-1,right移動;如果小于目標值就+1,left移動

    舉個例子,下面的有序數組有17 個值,查找的目標值是7,過程如下:

    第一次查找


    第二次查找


    第三次查找


    第四次查找



    2.2Hash結構

    Hash底層實現是由Hash表來實現的,是根據鍵值 <key,value> 存儲數據的結構。非常適合根據key查找value值,也就是單個key查詢,或者說等值查詢。其結構如下所示:


    從上面結構可以看出,Hash索引可以方便的提供等值查詢,但是對于范圍查詢就需要全表掃描了。Hash索引在MySQL 中Hash結構主要應用在Memory原生的Hash索引 、InnoDB 自適應哈希索引。

    InnoDB提供的自適應哈希索引功能強大,接下來重點描述下InnoDB 自適應哈希索引。【用在Buffer Pool的地方】


    InnoDB自適應哈希索引是為了提升查詢效率,InnoDB存儲引擎會監控表上各個索引頁的查詢,當InnoDB注意到某些索引值訪問非常頻繁時,會在內存中基于B+Tree索引再創建一個哈希索引,使得內存中的 B+Tree 索引具備哈希索引的功能,即能夠快速定值訪問頻繁訪問的索引頁。

    InnoDB自適應哈希索引:在使用Hash索引訪問時,一次性查找就能定位數據,等值查詢效率要優于B+Tree。


    自適應哈希索引的建立使得InnoDB存儲引擎能自動根據索引頁訪問的頻率和模式自動地為某些熱點頁建立哈希索引來加速訪問。另外InnoDB自適應哈希索引的功能,用戶只能選擇開啟或關閉功能,無法進行人工干涉。

    show engine innodb status \G;show variables like '%innodb_adaptive%';


    2.3B+Tree結構

    MySQL數據庫索引采用的是B+Tree結構,在B-Tree結構上做了優化改造。

    B-Tree結構



    • 索引值和data數據分布在整棵樹結構中
    • 每個節點可以存放多個索引值及對應的data數據
    • 樹節點中的多個索引值從左到右升序排列

    B-Tree的搜索:從根節點開始,對節點內的索引值序列采用二分法查找,如果命中就結束查找。沒有命中會進入子節點重復查找過程,直到所對應的的節點指針為空,或已經是葉子節點了才結束。 適合做等值查詢(MongoDB)

    B+Tree結構



    • 非葉子節點不存儲data數據,只存儲索引值,這樣便于存儲更多的索引值
    • 葉子節點包含了所有的索引值和data數據
    • 葉子節點用指針連接,提高區間的訪問性能

    相比B樹,B+樹進行范圍查找時,只需要查找定位兩個節點的索引值,然后利用葉子節點的指針進行遍歷即可。而B樹需要遍歷范圍內所有的節點和數據,顯然B+Tree效率高。【適合做范圍查詢和全表掃描,Mysql默認結構】

    為啥使用B+Tree

    為啥MySQL使用B+Tree而不使用二叉樹或者紅黑樹或者B-Tree呢?

    1、二叉樹的弊端,在插入數據的時候比如id是自增那么就會形成單邊樹,在進行查找的時候會產生很多磁盤io效率比較低。


    2、紅黑樹,會自動平衡二叉樹,可以有效解決二叉樹的單邊樹問題,但是對于Mysqllaishuo存儲數據可能上千萬那么,紅黑樹因為每個節點只能有兩個子節點,也會產生比較多的子節點導致在查找的時候增加磁盤io


    3、B-Tree樹,每個節點都有固定的大小mysql默認是16k,這樣子就可以解決紅黑樹導致的子節點層級過多的問題,但是B-Tree有另外一個問題,就是每個節點都有所有的數據,如果節點對應的數據過多的話每個節點就不能有太多的橫向節點,就會導致跟紅黑樹一樣的問題節點的層級比較多,增加磁盤IO。


    4、B+Tree樹,Mysql在B-Tree的基礎上優化的一種形態的數據結構,B+Tree是非葉子節點都包含數據,這樣子非葉子節點就在規定的大小(16k)中包含盡可能多的索引值,就可以減少樹節點的層級,有效的減少磁盤IO,所有的數據都在子節點上,并且子節點之間相互指向【方便范圍查找】,因此子節點直接可以直接快速的訪問。【MySQL通常只有三層就可以解決】


    MySQL中有主鍵索引和非主鍵索引(輔助索引),主鍵索引data中存儲了所有的數據,非主鍵索引只存儲了當前的列和主鍵索引。

    2.4聚簇索引和輔助索引

    1、聚簇索引(聚集索引)

    聚簇索引是一種數據存儲方式,InnoDB的聚簇索引就是按照主鍵順序構建 B+Tree結構。B+Tree的葉子節點就是行記錄,行記錄和主鍵值緊湊地存儲在一起。 這也意味著 InnoDB 的主鍵索引就是數據表本身,它按主鍵順序存放了整張表的數據,占用的空間就是整個表數據量的大小。通常說的主鍵索引就是聚集索引。

    InnoDB的表要求必須要有聚簇索引:

    • 如果表定義了主鍵,則主鍵索引就是聚簇索引
    • 如果表沒有定義主鍵,則第一個非空unique列作為聚簇索引
    • 否則InnoDB會從建一個隱藏的row-id作為聚簇索引

    2、輔助索引

    InnoDB輔助索引,也叫作二級索引,是根據索引列構建 B+Tree結構。但在 B+Tree 的葉子節點中只存了索引列和主鍵的信息。二級索引占用的空間會比聚簇索引小很多, 通常創建輔助索引就是為了提升查詢效率。一個表InnoDB只能創建一個聚簇索引,但可以創建多個輔助索引。【非主鍵索引的索引就是輔助索引,只存儲當前的索引列和主鍵列】


    3、非聚簇索引

    與InnoDB表存儲不同,MyISAM數據表的索引文件和數據文件是分開的,被稱為非聚簇索引結構。

    簡單理解,就是索引結構和數據結構分開存儲,需要先通過索引找到地址值在通過地址值去查找數據,這樣子就增加了磁盤IO。


    4、對比

    聚簇索引和非聚簇索引:B+Tree的葉子節點存放主鍵索引值和行記錄就屬于聚簇索引;如果索引值和行記錄分開存放就屬于非聚簇索引。

    主鍵索引和輔助索引:B+Tree的葉子節點存放的是主鍵字段值就屬于主鍵索引;如果存放的是非主鍵值就屬于輔助索引(二級索引)。

    2.5常見面試題

    1、為啥InnoDB表必須要有主鍵

    因為InnoDB表使用的存儲引擎是B+Tree而B+Tree必須要有一個自增的主鍵來構成索引結構。如果不自己建主鍵的話,Mysql內部會自動生成唯一的列作為主鍵。

    2、為啥要使用自增的整型?

    假如使用uuid作為uuid作為主鍵進行存儲的話,沒辦法進行快速的比較進行查找,并且uuid存儲的空間比較大。自增的話方便快速存儲。

    3、為什么非主鍵索引結構葉子節點存儲的是主鍵值?

    為了數據一致性和節省存儲空間。【完整性的數據只需要維護一份就行,就在主鍵索引中維護即可】


    三、索引分析

    3.1Explain介紹

    MySQL 提供了一個 EXPLAIN 命令,它可以對 SELECT 語句進行分析,并輸出 SELECT 執行的詳細信息,供開發人員有針對性的優化。例如: EXPLAIN SELECT * from user WHERE id < 3;


    1、select_type屬性

    表示查詢的類型。常用的值如下:

    • SIMPLE : 表示查詢語句不包含子查詢或union
    • PRIMARY:表示此查詢是最外層的查詢【先執行】
    • UNION:表示此查詢是UNION的第二個或后續的查詢
    • DEPENDENT UNION:UNION中的第二個或后續的查詢語句,使用了外面查詢結果
    • UNION RESULT:UNION的結果
    • SUBQUERY:SELECT子查詢語句
    • DEPENDENT SUBQUERY:SELECT子查詢語句依賴外層查詢的結果。

    最常見的查詢類型是SIMPLE,表示我們的查詢沒有子查詢也沒用到UNION查詢。

    2、type屬性

    表示存儲引擎查詢數據時采用的方式。比較重要,通過它可以判斷出查詢是全表掃描還是基于索引的部分掃描。常用屬性值如下,從上至下效率依次增強。

    • NULL:表示不用訪問表,速度最快。
    • system、const:使用主鍵索引或者唯一索引進行等值常量查詢,效率比較高,如果查詢的條數為一條的話就是system。
    • eq_ref:使用主鍵索引或者唯一索引進行多表關聯時候on之后的條件。表示前面表的每一個記錄,都只能匹配后面表的一行結果。(不可能是簡單查詢)
    • ref:表相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前綴,索引要和某個值相比較,可能會找到多個符合條件的行。(可以是簡單查詢)【explain select * from film where name='film1';】
    • range:表示使用索引范圍查詢。使用>、>=、<、<=、in等等。
    • index:掃描全表索引,這通常比ALL快一些。
    • ALL:全表掃描,意味著mysql需要從頭到尾去查找所需要的行。通常情況下這需要增加索引來進行優化

    建議:在平時的sql中至少要把sql優化成range級別的才算可以。

    NULL> const> eq_ref> ref> range> index>ALL

    3、possible_keys

    表示查詢時能夠使用到的索引。注意并不一定會真正使用,顯示的是索引名稱。

    4、key

    表示查詢時真正使用到的索引,顯示的是索引名稱。

    5、ref

    這一列顯示了在key列記錄的索引中,表查找值所用到的列或常量,常見的有:const(常量),字段名(例:film.id)

    6、rows

    MySQL查詢優化器會根據統計信息,估算SQL要查詢到結果需要掃描多少行記錄。原則上rows是越少效率越高,可以直觀的了解到SQL效率高低。

    7、key_len

    表示查詢使用了索引的字節數量。可以判斷是否全部使用了組合索引。

    key_len的計算規則如下:

    字符串類型

    • 字符串長度跟字符集有關:latin1=1、gbk=2、utf8=3、utf8mb4=4
    • char(n):n*字符集長度
    • varchar(n):n * 字符集長度 + 2字節

    數值類型

    • TINYINT:1個字節
    • SMALLINT:2個字節
    • MEDIUMINT:3個字節
    • INT、FLOAT:4個字節
    • BIGINT、DOUBLE:8個字節

    時間類型

    • DATE:3個字節
    • TIMESTAMP:4個字節
    • DATETIME:8個字節

    字段屬性

    • NULL屬性占用1個字節,如果一個字段設置了NOT NULL,則沒有此項。

    比如一個users表中name 類型為varchar(50),那么使用到name索引值的話key_len=53 【50長度 + 2可變長 + 1(Default NULL)】

    8、Extra

    Extra表示很多額外的信息,各種操作會在Extra提示相關信息,常見幾種如下:

    • Using index:使用覆蓋索引,不需要回表。【性能最高】
    • Using index condition:查詢的列不完全被索引覆蓋,where條件中是一個前導列的范圍;【性能其次】
    • Using where:使用 where 語句來處理結果,查詢的列未被索引覆蓋,需要回表。
    • Using temprorary:使用到了內存表,一般出現于去重、分組等操作。【distinct操作】
    • Using filesort:查詢的結果需要在內存中進行排序,效率很低,需要進行優化
    • Select tables optimized away:使用某些聚合函數(比如 max、min)來訪問存在索引的某個字段。【explain select min(id) from user;】·

    3.2回表查詢和覆蓋索引

    回表查詢:在之前介紹過,InnoDB索引有聚簇索引和輔助索引。聚簇索引的葉子節點存儲行記錄,InnoDB必須要有且只有一個。輔助索引的葉子節點存儲的是主鍵值和索引字段值,通過輔助索引無法直接定位行記錄,通常情況下,需要掃碼兩遍索引樹。先通過輔助索引定位主鍵值,然后再通過聚簇索引定位行記錄,這就叫做回表查詢,它的性能比掃一遍索引樹低。

    覆蓋索引:只需要在一棵索引樹上就能獲取SQL所需的所有列數據,無需回表,速度更快,這就叫做索引覆蓋。

    3.3最左前綴原則

    復合輔助索引存儲結構


    篩選的話會根據創建索引的順序諸葛對索引進行篩選,類似于A(B(C)) 只有找到A匹配之后在去匹配B,B匹配之后再去匹配C。不能跨級匹配,比如A匹配之后沒有匹配B而直接匹配C不會的。


    結論:按照索引創建的順序,從左向右匹配直到遇到范圍查詢 > < between 索引失效。

    案例數據準備:

    CREATE TABLE `employees` ( `id` INT (11) NOT NULL AUTO_INCREMENT, `name` VARCHAR (24) NOT NULL DEFAULT '' COMMENT '姓名', `age` INT (11) NOT NULL DEFAULT '0' COMMENT '年齡', `position` VARCHAR (20) NOT NULL DEFAULT '' COMMENT '職位', `hire_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入職時間', PRIMARY KEY (`id`), KEY `idx_name_age_position` (`name`, `age`, `position`) USING BTREE) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='員工記錄表';INSERT INTO employees(name,age,position,hire_time) VALUES('LiLei',22,'manager',NOW());INSERT INTO employees(name,age,position,hire_time) VALUES('HanMeimei',23,'dev',NOW());INSERT INTO employees(name,age,position,hire_time) VALUES('Lucy',23,'dev',NOW());

    案例分析

    查詢語句一

    EXPLAIN SELECT * FROM employees WHERE name='LiLei';



    使用了組合索引,key_len是74計算:24*3 + 2 (24個字符,3是urf8編碼,2是可變長度 【如果默認值為null的話需要在加1】)

    查詢語句二

    EXPLAIN SELECT * FROM employees WHERE name='LiLei' AND age=22 AND position='manager';



    使用了索引,key_len=140計算:24*3+2 + 4 + 20*3+2=140(int默認為4字節)

    查詢語句三

    EXPLAIN SELECT * FROM employees WHERE age=22 AND position='manager';

    不會使用索引,復合索引存儲,是匹配第一個字段【name】,在匹配第二個字段【age】,在匹配第三個字段【position】


    查詢語句四

    EXPLAIN SELECT * FROM employees WHERE age > 22 and name='LiLei' AND position='manager';



    此時生效的索引只有name和age,position沒有生效。原因,在做范圍查找的時候第三個索引就沒辦法進行精確匹配了。

    注意

    1、不在索引列上做任何操作(計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描。【EXPLAIN SELECT * FROM employees WHERE left(name,3)='LiLei';】 2、在復合索引中使用非最后一個索引的列進行范圍查找就會導致后邊的索引列失效,就是查詢語句四。

    3.4字符串不加單引號索引失效

    EXPLAIN SELECT * FROM employees WHERE name=1000;



    3.5Like查詢

    MySQL在使用like模糊查詢時,索引能不能起作用? select * from employees where name like '%o%'; //不起作用

    select * from employees where name like 'o%'; //起作用

    select * from employees where name like '%o'; //不起作用

    3.6 NULL查詢

    is null,is not null 也無法使用索引

    EXPLAIN SELECT * FROM employees WHERE name is null

    建議在給一些索引篩選列設置默認值為空字符串。

    3.7!=或者<>

    mysql在使用不等于(!=或者<>)的時候無法使用索引會導致全表掃描。

    EXPLAIN SELECT * FROM employees WHERE name=1000;

    3.8or和in關鍵字

    少用or或in,用它查詢時,mysql不一定使用索引,mysql內部優化器會根據檢索比例、表大小等多個因素整體評估是否使用索引。

    EXPLAIN SELECT * FROM employees WHERE name='LiLei' or name='HanMeimei';



    3.9.范圍查詢優化

    給employees表添加索引

    ALTER TABLE `employees` ADD INDEX `idx_age` (`age`) USING BTREE ;

    查詢語句

    explain select * from employees where age >=1 and age <=2000;



    沒有使用索引,原因:mysql內部優化器會根據檢索比例、表大小等多個因素整體評估是否使用索引。比如這個例子,可能是由于單次數據量查詢過大導致優化器最終選擇不走索引優化方法:可以講大的范圍拆分成多個小范圍。

    explain select * from employees where age >=1001 and age <=2000;




    3.10總結




    四、索引優化工具Trace

    4.1思考與分析

    思考:根據3的employees表,索引為idex_name_age_position 思考下邊的SQL是否走索引?

    SQL1:explain select * from employees where name > 'a';

    SQL2:explain select name,age,position from employees where name > 'a';

    SQL3:explain select * from employees where name > 'zzz';

    結果:SQL1不走索引,SQL2走索引,SQL3走索引。

    4.2Trace工具使用

    對于4.1的問題分析,SQL1為啥不走索引?而SQL2和SQL3都走索引?

    我們開啟trace工具對MySQL執行優化器進行查看,注意 平時生產上不能開啟,影響性能。

    set session optimizer_trace='enabled=on',end_markers_in_json=on; -- 開啟trace

    運行SQL1和trace

    select * from employees where name > 'a';select * from information_schema.OPTIMIZER_TRACE;

    查看結果二TRACE

    { "steps": [ { "join_preparation": { ‐‐第一階段:SQL準備階段 … }, { "join_optimization": { "steps": [ { "condition_processing": { ‐‐第二階段:SQL優化階段 … }, { "table_dependencies": [ -- 表依賴詳情 … ] /* table_dependencies */ }, { "ref_optimizer_key_uses": [ ] /* ref_optimizer_key_uses */ }, { "rows_estimation": [ -- 預估表的訪問成本 { "table": "`employees`", "range_analysis": { "table_scan": { "rows": 3, ‐‐掃描行數 "cost": 3.7 --查詢成本(沒有單位數值越大成本越高) } /* table_scan */, "potential_range_indices": [‐‐查詢可能使用的索引 { "index": "PRIMARY", "usable": false, "cause": "not_applicable" }, { "index": "idx_name_age_position", --輔助索引 "usable": true, "key_parts": [ "name", "age", "position", "id" ] /* key_parts */ } ] /* potential_range_indices */, "setup_range_conditions": [ ] /* setup_range_conditions */, "group_index_range": { "chosen": false, "cause": "not_group_by_or_distinct" } /* group_index_range */, "analyzing_range_alternatives": { --分析各個索引使用成本 "range_scan_alternatives": [ { "index": "idx_name_age_position", "ranges": [ "a < name" ‐‐索引使用范圍 ] /* ranges */, "index_dives_for_eq_ranges": true, "rowid_ordered": false, ‐‐使用該索引獲取的記錄是否按照主鍵排序 "using_mrr": false, "index_only": false, ‐‐是否使用覆蓋索引 "rows": 3, ‐‐索引掃描行數 "cost": 4.61, ‐‐索引使用成本 "chosen": false, ‐‐是否選擇該索引 "cause": "cost" } ] /* range_scan_alternatives */, "analyzing_roworder_intersect": { "usable": false, "cause": "too_few_roworder_scans" } /* analyzing_roworder_intersect */ } /* analyzing_range_alternatives */ } /* range_analysis */ } ] /* rows_estimation */ }, { "considered_execution_plans": [ { "plan_prefix": [ ] /* plan_prefix */, "table": "`employees`", "best_access_path": { ‐‐最優訪問路徑 "considered_access_paths": [‐‐最終選擇的訪問路徑 { "access_type": "scan",--訪問類型:為scan,全表掃描 "rows": 3, "cost": 1.6, "chosen": true ‐‐確定選擇 } ] /* considered_access_paths */ } /* best_access_path */, "cost_for_plan": 1.6, "rows_for_plan": 3, "chosen": true } ] }, }

    查看的時候,如果做索引優化只需要查看rows_estimation 、analyzing_range_alternatives 、considered_execution_plans 這些個屬性即可。

    結論

    1、通過trace工具可以分析,SQL1在使用索引的情況下首先需要查詢索引樹,還需要回表掃描主鍵索引樹。二個掃描的成本>全表掃描的成本,因此MySQL沒有選擇使用索引。

    2、SQL2只掃描輔助索引樹就可以得到結果,因此會走索引。

    3、SQL3掃描了一行查看到沒有關聯的數據因此直接返回的結果為空索引會走索引樹。

    五、排序優化

    5.1排序

    MySQL查詢支持index和filesort兩種方式的排序,index就是根據主鍵進行排序,物理排序效率比較高;filesort是先把結果查出,然后在緩存或磁盤進行排序操作,效率較低。

    5.2排序案例

    基于employees表進行查看

    case1



    分析:利用最左前綴法則:中間字段不能斷,因此查詢用到了name索引,從key_len=74也能看出,age索引列用在排序過程中,因為Extra字段里沒有using filesort

    case2



    分析:從explain的執行結果來看:key_len=74,查詢使用了name索引,由于用了position進行排序,跳過了

    age,出現了Using filesort。

    case3



    分析:查找只用到索引name,age和position用于排序,無Using filesort。

    case4



    分析:和Case 3中explain的執行結果一樣,但是出現了Using filesort,因為索引的創建順序為name,age,position,但是排序的時候age和position顛倒位置了。

    case5



    分析:與Case 4對比,在Extra中并未出現Using filesort,因為age為常量,在排序中被優化,所以索引未顛倒,不會出現Using filesort。

    case6



    分析:雖然排序的字段列與索引順序一樣,且order by默認升序,這里position desc變成了降序,導致與索引的排序方式不同,從而產生Using filesort。Mysql8以上版本有降序索引可以支持該種查詢方式。

    case7



    分析:對于排序來說,多個相等條件也是范圍查詢

    case8



    5.3 filesort文件排序

    介紹

    單路排序:是一次性取出滿足條件行的所有字段,然后在sort buffer中進行排序;用trace工具可以看到sort_mode信息里顯示< sort_key, additional_fields >或者< sort_key,packed_additional_fields >

    雙路排序(又叫回表排序模式):首先根據相應的條件取出相應的排序字段和可以直接定位行數據的行 ID,然后在 sort buffer 中進行排序,排序完后需要再次去主鍵索引取回其它需要的字段;用trace工具可以看到sort_mode信息里顯示< sort_key, rowid >

    參數控制:MySQL 通過比較系統變量 max_length_for_sort_data(默認1024字節) 的大小和需要查詢的字段總大小來判斷使用哪種排序模式。

    • 如果 max_length_for_sort_data 比查詢字段的總長度大,那么使用 單路排序模式;
    • 如果 max_length_for_sort_data 比查詢字段的總長度小,那么使用 雙路排序模式。

    案例

    示例驗證下各種排序方式



    查看下這條sql對應trace結果如下(只展示排序部分):

    ‐‐開啟traceset session optimizer_trace="enabled=on",end_markers_in_json=on; select * from employees where name='zhuge' order by position;select * from information_schema.OPTIMIZER_TRACE;trace排序部分結果:"join_execution": { ‐‐Sql執行階段 "select#": 1, "steps": [ { "filesort_information": [ { "direction": "asc", "table": "`employees`", "field": "position" } ] /* filesort_information */, "filesort_priority_queue_optimization": { "usable": false, "cause": "not applicable (no LIMIT)" } /* filesort_priority_queue_optimization */, "filesort_execution": [ ] /* filesort_execution */, "filesort_summary": { ‐‐文件排序信息 "rows": 10000, ‐‐預計掃描行數 "examined_rows": 10000, ‐‐參數排序的行 "number_of_tmp_files": 3, ‐‐使用臨時文件的個數,這個值如果為0代表全部使用的sort_buffer內存排序,否則使用的磁盤文件排序 "sort_buffer_size": 262056, ‐‐排序緩存的大小 "sort_mode": "<sort_key, packed_additional_fields>" ‐‐排序方式,這里用的單路排序 } /* filesort_summary */ } ] /* steps */ }

    詳細執行流程

    1. 從索引name找到第一個滿足 name=‘zhuge’ 條件的主鍵 id

    2. 根據主鍵 id 取出整行,取出所有字段的值,存入 sort_buffer 中

    3. 從索引name找到下一個滿足 name=‘zhuge’ 條件的主鍵 id

    4. 重復步驟 2、3 直到不滿足 name=‘zhuge’

    5. 對 sort_buffer 中的數據按照字段 position 進行排序

    6. 返回結果給客戶端

    雙路排序

    set max_length_for_sort_data=10; ‐‐employees表所有字段長度總和肯定大于10字節 select * from employees where name='zhuge' order by position; select * from information_schema.OPTIMIZER_TRACE;trace排序部分結果:"join_execution": { "select#": 1, "steps": [ { "filesort_information": [ { "direction": "asc", "table": "`employees`", "field": "position" } ] /* filesort_information */, "filesort_priority_queue_optimization": { "usable": false, "cause": "not applicable (no LIMIT)" } /* filesort_priority_queue_optimization */, "filesort_execution": [ ] /* filesort_execution */, "filesort_summary": { "rows": 10000, "examined_rows": 10000, "number_of_tmp_files": 2, "sort_buffer_size": 262136, "sort_mode": "<sort_key, rowid>" ‐‐排序方式,這里用的雙路排序 } /* filesort_summary */ } ] /* steps */ } /* join_execution */ set session optimizer_trace="enabled=off"; ‐‐關閉trace

    詳細執行流程:

    1. 從索引 name 找到第一個滿足 name=‘zhuge’ 的主鍵id

    2. 根據主鍵 id 取出整行,把排序字段 position 和主鍵 id 這兩個字段放到 sort buffer 中

    3. 從索引 name 取下一個滿足 name=‘zhuge’ 記錄的主鍵 id

    4. 重復 2、3 直到不滿足 name=‘zhuge’

    5. 對 sort_buffer 中的字段 position 和主鍵 id 按照字段 position 進行排序

    6. 遍歷排序好的 id 和字段 position,按照 id 的值回到原表中取出 所有字段的值返回給客戶端

    總結

    其實對比兩個排序模式,單路排序會把所有需要查詢的字段都放到 sort buffer 中,而雙路排序只會把主鍵和需要排序的字段放到 sort buffer 中進行排序,然后再通過主鍵回到原表查詢需要的字段。

    如果 MySQL 排序內存配置的比較小并且沒有條件繼續增加了,可以適當把 max_length_for_sort_data 配

    置小點,讓優化器選擇使用雙路排序算法,可以在sort_buffer 中一次排序更多的行,只是需要再根據主鍵回到原表取數據。

    如果 MySQL 排序內存有條件可以配置比較大,可以適當增大 max_length_for_sort_data 的值,讓優化器

    優先選擇全字段排序(單路排序),把需要的字段放到 sort_buffer 中,這樣排序后就會直接從內存里返回查詢結果了。

    所以,MySQL通過 max_length_for_sort_data 這個參數來控制排序,在不同場景使用不同的排序模式,從而提升排序效率。

    注意:如果全部使用sort_buffer內存排序一般情況下效率會高于磁盤文件排序,但不能因為這個就隨便增大sort_buffer(默認1M),mysql很多參數設置都是做過優化的,不要輕易調整。

    5.4總結

    1、MySQL支持兩種方式的排序filesort和index,Using index是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。

    2、order by滿足兩種情況會使用Using index。

    1) order by語句使用索引最左前列。

    2) 使用where子句與order by子句條件列組合滿足索引最左前列。

    3、盡量在索引列上完成排序,遵循索引建立(索引創建的順序)時的最左前綴法則。

    4、如果order by的條件不在索引列上,就會產生Using filesort。

    5、能用覆蓋索引盡量用覆蓋索引

    6、group by與order by很類似,其實質是先排序后分組,遵照索引創建順序的最左前綴法則。對于group

    by的優化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能寫在where中的限定條件就不要去having限定了。







    六、SQL優化實戰

    6.1分頁查詢優化

    很多時候我們業務系統實現分頁功能可能會用如下sql實現select * from employees limit 10000,10;

    性能分析:表示從表employees 中取出從 10001 行開始的 10 行記錄。看似只查詢了 10 條記錄,實際這條 SQL 是先讀取 10010條記錄,然后拋棄前 10000 條記錄,然后讀到后面 10 條想要的數據。因此要查詢一張大表比較靠后的數據,執行效率是非常低的。

    1、優化技巧1

    根據自增且連續的主鍵排序的分頁查詢。

    優化前select * from employees limit 90000,5;優化后select * from employees where id > 90000 limit 5;




    弊端:這種優化方式只適用于表中id是連續自增的一旦出現有數據刪除那么就會導致結果不一致

    2、優化技巧2

    根據非主鍵字段排序的分頁查詢

    優化前select * from employees ORDER BY name limit 90000,5;優化后select * from employees e inner join (select id from employees order by name limit 90000,5) edon e.id=ed.id;





    優點:內查詢是走主鍵索引的,inner join關聯主鍵的效率非常高。而原 SQL 使用的是 filesort 排序,而優化后的 SQL 使用的是索引排序。

    6.2Join關聯查詢優化

    1、準備

    create table t1 (id int not null auto_increment,a int default null,b int default null,PRIMARY KEY (`id`),INDEX `idx_a` (a) USING BTREE ) engine=innodb charset=utf8;create table t2 like t1;往t1表插入1萬行記錄,往t2表插入100行記錄

    2、mysql的表關聯常見有兩種算法

    • Nested-Loop Join 算法
    • Block Nested-Loop Join 算法

    嵌套循環連接 Nested-Loop Join(NLJ) 算法

    一次一行循環地從第一張表(稱為驅動表)中讀取行,在這行數據中取到關聯字段,根據關聯字段在另一張表(被驅動表)里取出滿足條件的行,然后取出兩張表的結果合集。

    explain select * from t1 inner join t2 on t1.a=t2.a



    從執行計劃中可以看到這些信息:

    • 驅動表是 t2,被驅動表是 t1。先執行的就是驅動表(執行計劃結果的id如果一樣則按從上到下順序執行sql);優化器一般會優先選擇小表做驅動表。所以使用 inner join 時,排在前面的表并不一定就是驅動表
    • 使用了 NLJ算法。一般 join 語句中,如果執行計劃 Extra 中未出現 Using join buffer 則表示使用的 join 算法是 NLJ。

    sql的大致流程

    1. 從表 t2 中讀取一行數據;

    2. 從第 1 步的數據中,取出關聯字段 a,到表 t1 中查找;

    3. 取出表 t1 中滿足條件的行,跟 t2 中獲取到的結果合并,作為結果返回給客戶端;

    4. 重復上面 3 步。

    總結:整個過程會讀取 t2 表的所有數據(掃描100行),然后遍歷這每行數據中字段 a 的值,根據 t2 表中 a 的值索引掃描 t1 表中的對應行(掃描100次 t1 表的索引,1次掃描可以認為最終只掃描 t1 表一行完整數據,也就是總共 t1 表也掃描了100行)。因此整個過程掃描了 200 行。

    如果被驅動表的關聯字段沒索引,使用NLJ算法性能會比較低,mysql會選擇Block Nested-Loop Join算法。

    基于塊的嵌套循環連接 Block Nested-Loop Join( BNL )算法

    把驅動表的數據讀入到 join_buffer 中,然后掃描被驅動表,把被驅動表每一行取出來跟 join_buffer 中的數據做對比。

    explain select * from t1 inner join t2 on t1.b=t2.b



    Extra 中 的Using join buffer (Block Nested Loop)說明該關聯查詢使用的是 BNL 算法。

    sql的大致流程如下:

    1. 把 t2 的所有數據放入到 join_buffer 【內存】中

    2. 把表 t1 中每一行取出來,跟 join_buffer 中的數據做對比

    3. 返回滿足 join 條件的數據整個過程對表 t1 和 t2 都做了一次全表掃描,因此掃描的總行數為10000(表 t1 的數據總量) + 100(表 t2 的數據總量)=10100。并且 join_buffer 里的數據是無序的,因此對表 t1 中的每一行,都要做 100 次判斷,所以內存中的判斷次數是100 * 10000=100 萬次。

    思考:被驅動表的關聯字段沒索引為什么要選擇使用 BNL 算法而不使用 Nested-Loop Join 呢?

    如果上面第二條sql使用 Nested-Loop Join,那么掃描行數為 100 * 10000=100萬次,這個是磁盤掃描

    很顯然,用BNL磁盤掃描次數少很多,相比于磁盤掃描,BNL的內存計算會快得多。

    因此MySQL對于被驅動表的關聯字段沒索引的關聯查詢,一般都會使用 BNL 算法。如果有索引一般選擇 NLJ 算法,有索引的情況下 NLJ 算法比 BNL算法性能更高

    3、對于關聯SQL的優化

    • 關聯字段加索引,讓mysql做join操作時盡量選擇NLJ算法。
    • 小標驅動大表,寫多表連接sql時如果明確知道哪張表是小表可以用straight_join寫法固定連接驅動方式,省去mysql優化器自己判斷的時間。

    straight_join解釋:straight_join功能同join類似,但能讓左邊的表來驅動右邊的表,能改表優化器對于聯表查詢的執行順序。

    比如:select * from t2 straight_join t1 on t2.a=t1.a; 代表制定mysql選著 t2 表作為驅動表。

    • straight_join只適用于inner join,并不適用于left join,right join。(因為left join,right join已經代表指定了表的執行順序)
    • 盡可能讓優化器去判斷,因為大部分情況下mysql優化器是比人要聰明的。使用straight_join一定要慎重,因為部分情況下人為指定的執行順序并不一定會比優化引擎要靠譜。

    6.3in和exists優化

    原則:小表驅動大表,即小的數據集驅動大的數據集

    in:當B表的數據集小于A表的數據集時,in優于exists

    select * from A where id in (select id from B)#等價于: for(select id from B){ //先執行 select * from A where A.id=B.id //在執行 }





    exists :當A表的數據集小于B表的數據集時,exists優于in

    將主查詢A的數據,放到子查詢B中做條件驗證,根據驗證結果(true或false)來決定主查詢的數據是否保留

    select * from A where exists (select 1 from B where B.id=A.id) #等價于: for(select * from A){//先執行 select * from B where B.id=A.id } #A表與B表的ID字段應建立索引




    1、EXISTS (subquery)只返回TRUE或FALSE,因此子查詢中的SELECT * 也可以用SELECT 1替換,官方說法是實際執行時會忽略SELECT清單,因此沒有區別

    2、EXISTS子查詢的實際執行過程可能經過了優化而不是我們理解上的逐條對比

    3、EXISTS子查詢往往也可以用JOIN來代替,何種最優需要具體問題具體分析

    6.4count(*)查詢優化

    # 臨時關閉mysql查詢緩存,為了查看sql多次執行的真實時間

    set global query_cache_size=0;

    set global query_cache_type=0;

    思考:下邊查詢語句哪個更高?

    select count(1) from employees;

    select count(id) from employees;

    select count(name) from employees;

    select count(*) from employees;

    結論:在MySQL5.7之前count(1) > count(name) >=count(*) > count(id),但是在MySQL5.7以后版本四個sql的執行計劃一樣,說明這四個sql執行效率應該差不多,區別在于根據某個字段count不會統計字段為null值的數據行。最終使用的都是輔助索引。

    為什么mysql最終選擇輔助索引而不是主鍵聚集索引?

    因為二級索引相對主鍵索引存儲數據更少,檢索性能應該更高。

    常見優化方法

    1、查詢mysql自己維護的總行數

    對于myisam存儲引擎的表做不帶where條件的count查詢性能是很高的,因為myisam存儲引擎的表的總行數會被mysql存儲在磁盤上,查詢不需要計算。【因為MyISAM引擎不支持事務,因此不會出現數據不一致情況,索引MySIAM會在內存中維護一份總數量值】

    2、show table status語句

    如果只需要知道表總行數可以使用 show table status like '表名'

    3、將總數維護到Redis里

    插入或刪除表數據行的時候同時維護redis里的表總行數key的計數值(用incr或decr命令),但是這種方式可能不準,很難保證表操作和redis操作的事務一致性。

    4、增加計數表

    插入或刪除表數據行的時候同時維護計數表,讓他們在同一個事務里操作。

    6.5查看SQL執行時長工具

    查看是否打開

    show variables like 'profiling'

    打開

    set profiling=1

    使用

    show profiles;


    七、MySQL參數優化

    優化選擇

    • 優化成本:硬件升級>系統配置>表結構設計>SQL語句及索引。
    • 優化效果:硬件升級<系統配置<表結構設計<SQL語句及索引。

    7.1系統參數配置

    MySQL會在內存中保存一定的數據,通過LRU算法將不常訪問的數據保存在硬盤文件中。盡可能的擴大內存中的數據量,將數據保存在內存中,從內存中讀取數據,可以提升MySQL性能。擴大innodb_buffer_pool_size,能夠全然從內存中讀取數據。最大限度降低磁盤操作。

    確定innodb_buffer_pool_size 足夠大的方法:

    show global status like 'innodb_buffer_pool_pages_%';+----------------------------------+-------+| Variable_name | Value |+----------------------------------+-------+| Innodb_buffer_pool_pages_data | 267 || Innodb_buffer_pool_pages_dirty | 0 || Innodb_buffer_pool_pages_flushed | 36 || Innodb_buffer_pool_pages_free | 7925 | free代表能夠使用的空間| Innodb_buffer_pool_pages_misc | 0 || Innodb_buffer_pool_pages_total | 8192 |+----------------------------------+-------+在/etc/my.cnf文件中修改innodb_buffer_pool_size=750M 【innodb_buffer_pool_size默認為128M,理論上可以擴大到內存的3/4或4/5。(只安裝了mysql可以)】重啟mysql服務器

    如果是專用的MySQL Server可以禁用SWAP【不建議,禁用就不會從磁盤上讀取文件了】

    #查看swapcat /proc/swaps Filename Type Size Used Priority/dev/sda2 partition 1048572 0 -1#關閉所有交換設備和文件.swapoff -a

    7.2數據預熱

    預熱腳本

    SELECT DISTINCT CONCAT('SELECT ',ndxcollist,' FROM ',db,'.',tb, ' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache FROM ( SELECT engine,table_schema db,table_name tb, index_name,GROUP_CONCAT(column_name ORDER BY seq_in_index)ndxcollist FROM ( SELECT B.engine,A.table_schema,A.table_name, A.index_name,A.column_name,A.seq_in_index FROM information_schema.statistics A INNER JOIN ( SELECT engine,table_schema,table_name FROM information_schema.tables WHERE engine='InnoDB' ) B USING (table_schema,table_name) WHERE B.table_schema NOT IN ('information_schema','mysql') ORDER BY table_schema,table_name,index_name,seq_in_index ) A GROUP BY table_schema,table_name,index_name ) AAORDER BY db,tb;

    將該腳本保存為:loadtomem.sql

    執行命令:mysql -uroot -proot -AN < /root/loadtomem.sql > /root/loadtomem.sql

    在需要數據預熱時,比如重啟數據庫:mysql -uroot < /root/loadtomem.sql > /dev/null 2>&1

    7.3降低磁盤寫入次數

    • 增大redolog,減少落盤次數 :innodb_log_file_size 設置為 0.25 * innodb_buffer_pool_size
    • 通用查詢日志、慢查詢日志可以不開 ,bin-log開:生產中不開通用查詢日志,遇到性能問題開慢查詢日志
    • 寫redolog策略 innodb_flush_log_at_trx_commit設置為0或2:如果不涉及非常高的安全性 (金融系統),或者基礎架構足夠安全,或者事務都非常小,都能夠用 0或者 2 來減少磁盤操作。



    不知不覺上半年各家手機品牌都經過了年初第一仗洗禮后,悄悄來到了2020年的年中了。旗艦級的手機各方面的硬件堆料,自然價格水漲船高,所以它們的價格都在4、6千元左右,對于中薪階層用戶來說這個價格很難消費得起,更別提是老一輩的用戶了。按照平時的慣例,年初為旗艦機的推出,年中為次旗艦中端機推出,最近這幾天榮耀剛剛推出了榮耀X10手機,這款手機在發布的時候就能看到官宣口號為:“超能科技,5G風暴”,從口號可以看出它是一款5G手機,另外它的價格方面算是又刷新一次性價比5G手機的底牌。對于到底是不是真性價比呢,下面分享一下這幾天我使用的體驗給小伙伴們。感謝數碼頻道提供本次測評產品:榮耀X10 探速黑 8GB+128GB。

    榮耀X10 5G雙模 麒麟820 4300mAh續航 4000萬高感光影像系統 6.63英寸升降全面屏 全網通 8GB+128GB 探速黑
    ¥2399
    購買
    <script src="http://mp.toutiao.com/mp/agw/mass_profit/pc_product_promotions_js?item_id=6830065528208359943"></script>




    榮耀X10的包裝依然是“素色”設計,全白的底色設計,包裝上很簡潔,沒有什么花哨大標題出現。包裝中間是漸變色的10X和HONOR,與素色白底結合,會顯得格外亮眼。雖然包裝是素色的設計,如果了解榮耀的HONORTechChic潮流定向,就會發現榮耀在去年已經“跨界”往時尚圈發展了,簡單說就是通過設計融入了理想、藝術、情感的科技生活。這次的“超能科技,5G風暴”主要是體現在性能與普及兩方面,性能就是搭載了全新的麒麟820移動平臺,普及就是雙模NSA/SA 全頻段5G通信。



    榮耀X10大眾的標配:透明軟膠手機殼、22.5W快充充電器、USB-A to USB-C數據線、取卡針、說明書等。現在的各品牌手機在出廠的時候基本上已經預貼了PET保護膜,這種貼膜以目前的工藝來說不算最好,也不算差,帶有疏油層,新膜順滑度比較高,但是后期日常使用磨損還是會出現生澀感,需要更換貼膜的,相比鋼化膜來說耐用度和順滑度肯定要差,如果沒有特別需求的小伙伴就將就用,等后期網上有全膠的鋼化膜再考慮更換。另外還配備的透明軟膠手機殼也能滿足日常需求保護使用,所以基本上不需要購置其他手機配件了。

    真全面屏,沒有魅眼孔




    不知道未來手機屏幕和前置攝像頭還能做出怎么樣的結合?或許明年就是真屏下攝像頭的設計,但是今年的手機全面屏設計基本上是兩極化:一種就是無遮擋升級真全面屏,一種就是挖孔魅眼全面屏,而以前比較流行的劉海屏幾乎只是在iPhone尋找蹤跡,其他品牌的手機都使用比較少了,也算是跳出一直以來爭論的“誰像誰,誰抄誰”大坑。這次榮耀X10也延續上代榮耀X9屏幕設計,并沒有采用魅眼全面屏,而是使用了真全面屏+升降攝像頭的設計。無遮擋升級真全面屏的設計帶來最大的好處就是實現了四邊無異型屏幕狀態,同時也能帶來更好的視覺觀感,榮耀X10的屏占比達到92%左右,在使用APP應用程序的時候也不用擔心APP有沒有做適配避開遮擋問題。

    90Hz高刷新率,帶來的手感變化



    上圖為放慢0.7X速度播放,左側是榮耀X10,右側小米Mix 2S,可以看見在日常屏幕的交互體驗來看,可以發現的確高刷新率在屏幕點擊滑動、拖拉等動作都能帶來更跟手的手感體驗。小米Mix 2S的屏幕上下滑動會明顯感覺到連貫性有一些跳幀,也就是說明低刷新率在快速滾動的時候就會明顯感覺一卡一卡的。

    榮耀X10搭載了一塊 2400*1080 分辨率的 6.63 英寸 LCD屏幕,支持最高 90Hz 刷新率、180Hz 觸控采樣率,對于這個屏幕參數,也算跟上了行業腳步。之前我評測過Redmi K30 Pro,作為友商目前最旗艦手機型號最大的致命傷就是只有 60Hz 刷新率,僅僅只是擁有 180Hz 觸控采用率,現在回頭把玩就能體驗出60Hz和90Hz刷新率之間的差距。

    今年很多手機新品都搭載了90Hz/120Hz高刷新率屏幕,在高刷新率的流暢體驗下來,的確能體驗到差距,但是也延伸到了一個問題:耗電。現在的手機都是高功耗手機,手機CPU越來越強大,機身越來越薄,但電池密度技術突破進展慢,所以耗電還是比較大的,很多手機都加入了快速充電技術來填補這個“坑”。建議使用榮耀X10的小伙伴們在日常使用開啟 60Hz 刷新率,如果是玩游戲的話就開啟 90Hz 刷新率,這樣可以讓電池續航更加持久一些,還是比較期待后期榮耀搭載的Magic系統能加入智能模式,可以在日常使用和游戲之間識別自動切換刷新率,這樣可以避免手動開啟的繁瑣。

    榮耀X10的LCD屏幕表現




    榮耀X10這塊LCD屏幕官方并沒有太多提及它的性能,整體實際的色彩感觀體驗不錯,算是中規中矩的屏幕,畢竟價格在這里,所以還是沒辦法像旗艦手機使用那些艷麗的AMOLED屏幕這么討喜眼球感觀。手機并沒有標注峰值亮度多少,在實際測試中,即便是在強光下也能看清楚。手機在正面設置了光線傳感器,實際體驗在遇到環境光線變化后,它還是能比較快速的自動調整亮度,精準性還不錯。



    屏幕支持全局電子書模式,同時屏幕也經過德國萊茵TüV低藍光護眼認證,支持9級濾藍光調節,可以有效過濾藍光實現護眼。當在手機設置顯示中開啟電子書模式,它就會模擬Kindle的黑色灰度全局顯示,通過減少視覺疲勞來實現護眼效果,視覺疲勞指數和Kindle類似,也就是說在閱讀電子書的情況下,合適的色溫設置和整個畫面的對比度約束可以有效的降低人眼的長時間閱讀的不適感。另外手機還能設置護眼模式、深色模式,通過多種設置來實現屏幕的護眼效果,護眼效果自然是緩解人眼疲勞度的,并不是絕對防護的,所以建議小伙伴們在每天放一放手機,多走走,減少手機接觸時間。

    都2020年了,為什么還會使用LCD屏幕呢,為什么不是更好的OLED屏幕?一方面是成本的制約,另一方面就是LCD屏幕的技術比較成熟,相比OLED顯示效果會更加通透一些,并不會有OLED屏幕那種艷麗色彩的色差,當在暗光表現下LCD屏幕出現的頻閃率要優于OLED屏幕。

    榮耀X10機器的設計




    因為LCD屏幕的原因,所以無法使用屏下光學指紋識別,另外它的指紋識別功能是集成在右側的電源按鍵上,這種設計相對于傳統的背后指紋設計會顯得整機協調性更好一些。另外在使用順手度上來說,右手大拇指或者左手食指解鎖體驗還不錯,不過其他手指解鎖就有點不順手了。


    比較有趣的就是側邊指紋設計在系統上做了習慣性選擇解鎖:是輕觸解鎖,還是按壓解鎖。輕觸解鎖就是當手指觸摸指紋識別區域,識別成功就馬上解鎖;而按壓解鎖則是在按壓下去瞬間才識別解鎖,這樣的解鎖方式對于一些老人使用會更加方便,也減少了日常使用的誤觸率。以前我爸媽在剛開始使用指紋解鎖的手機時候經常會下意識去做一個“按壓”動作,覺得這樣才是“識別”了。



    從手機頂部邊框可以看見帶有3.5mm耳機插孔,底部是常規式的功能布局:SIM卡槽、USB-C接口、麥克風、揚聲器。榮耀X10沒有配備雙揚聲器的設計,當外放的時候,還是會略比雙揚聲器的手機有點欠缺飽滿的聲音。好在榮耀X10搭載了自研音樂功放,Smart PA“智能功率放大器”,可以消除音樂播放中雜音,同時提升音量,就算音量調至最大,也不會出現爆音。另外這次的榮耀X10的SIM卡槽支持雙卡雙待外,還支持最大256GB NM專用存儲卡進行存儲空間拓展,這樣就不用擔心手機存儲空間不夠裝拍攝的4K錄像視頻和照片了。

    22.5W快充能解決電量焦慮癥嗎?



    榮耀X10標配的22.5W快充充電器,通過檢測表測試,可以發現它支持3種充電協議:BC1.2、QC2.0(5V/9V/12V)、HUAWEI-FCP 24W(5V/9V/12V)。雖然充電協議并不算多,但是也覆蓋了市面常見使用的快速充電協議,所以其他設備充電也是可以使用的。



    網上經常看見有人討論說快充會傷害手機電池健康度的言論,事實上只要正確使用充電,對電池的健康度傷害可以說是微乎其微,建議就是隨手充電,不用刻意用電到20%以下或者提示低電量再去充電,這樣會真的傷電池!平時都可以發現很多的手機都是在20%電量的時候就警示低電量需要及時補電了。

    這次測試我特別讓榮耀X10電量耗盡關機實驗的,關機狀態下從0%充電到100%的實際效率和充電時間,每5分鐘記錄一次充電量,統計繪制而成上圖表,通過柱形表可以看到榮耀X10與22.5W快充組合的充電效率。充電30分鐘,基本充到52%電量,隨后在電量大約在80%開始轉為涓流充電,充電速度明顯變慢,特別是電量充到95%之后,基本充5分鐘才增長1%,最終充滿4300mAh大電池耗時100分鐘,榮耀X10快速充電對于發熱量控制也比較好,溫度控制在大約35℃左右。

    現在的智能手機越來越強勁,也帶來了電量焦慮癥:平時出門,總會擔心會不會出門半天,還沒回到家手機就沒電了,又或者是手機充電速度太慢了,經常要花很長的時間等待充電。快速充電都是體現在碎片化時間上的利用,讓短時間里能快速給手機補電,避免長時間等待充電時間,擺脫了電量焦慮癥。



    我拿到手的這臺榮耀X10是探速黑,它的機身后蓋采用的是3D幻變玻璃材質,在不同的角度以及光線下,會呈現不一樣的光線折射紋理,根據官方介紹榮耀X10采用21層玻璃工藝,從上到下依次是:1、AF防指紋膜 2、玻璃 3、logo絲印 4、OCA膠 5、漸變色膠印6層(漸變) 6、PET 7、UV膠轉印層(柱透鏡紋理) 8、鍍膜5層(炫光反光) 9、絲印蓋底4層(油墨) ,共21層。當然現在很多的手機設計區別的地方就是背面了,全面屏時代看正面是很難分辨出是哪一款手機的,所以現在品牌的設計就是放在背面了,不過如果是日常裸機使用的小伙伴就能展現出原機的設計感,如果是選擇了保護殼,就真的是看殼設計了,誰都不知道殼后到底是什么樣子。

    榮耀X10搭載RYYB高感光影像系統有突出嗎?



    榮耀X10的鏡頭模組部分外觀是呈現凸出狀態的,安裝手機殼之后平放桌面不用擔心磨損鏡頭。現在很多的手機在對鏡頭模組部分已經沒有刻意“磨平”處理,這是因為手機的拍攝能力越來越強。

    拍照表現上,榮耀X10搭載4000萬RYYB高感光影像系統,它主要是由AI三攝來構成:

    主攝:40MP RYYB高感光鏡頭, 光圈F1.8,1/1.7英寸傳感器,最大支持7296*5472像素 ;

    廣角:8MP超廣角和景深二合一鏡頭,光圈F2.4,最大支持3264*2448像素;

    微距:2MP超微距鏡頭,支持4厘米微距拍攝,光圈F2.4,1600*1200像素;


    榮耀X10支持40MP的專業模式拍攝輸出,還有一個高像素模式拍攝輸出,比較可惜的就是它在專業模式下沒有RAW格式保存,經常拍攝的小伙伴就知道RAW格式和JPEG格式后期調校照片的寬容度是有什么大差別,還是希望后期能通過固件升級加入RAW格式存儲支持。手機拍攝40MP到底有沒有意義呢?如果是攝影愛好者的話,就意義重大,因為40MP拍攝出來的照片在手機看起來沒有太大區別,反而會覺得40MP拍攝出來還沒正常拍攝的清晰,實際上是被手機有限的尺寸所欺騙了,當導入電腦這種大屏顯示設備觀察就能發現細節上的區別:40MP拍攝的照片呈現細節更多,可以讓攝影后期制作擁有更大的自由調整空間,就像最早流行于攝影圈中說的那句話“底大一級壓死人”一樣。

    “底”指的是手機鏡頭模組里的圖像傳感器,在現實觀感中能被人眼所看到的任何物體,其實都是通過表面反射出的光線,這些光線信息再被眼睛接收反饋大腦才得以看見。光線收集的多少取決光圈的大小,光線信息接收的多少又取決于圖像傳感器的大小。也就是說,如果一個手機能同時擁有“大光圈+大圖像傳感器”的組合,就能拍攝出亮度更高、噪點更少、更清晰的照片。


    日常使用的榮耀X10拍攝素質到底是如何的?有什么特別的地方嗎?比較吸引我的就是榮耀X10除了搭載旗艦同款RYYB顏色濾鏡陣列高感光傳感器外,還有貓頭鷹算法2.0、AIS手持超級夜景2.0、超級HDR等這些拍攝調校加成功能。至于這個鏡頭模組的組合在多場景下拍攝的表現力到底如何,那么看一下實際樣張就知道,因為我日常拍攝的照片比較多,所以就抽選了幾張我個人覺得比較滿意的展示一下:






    通過上述樣張,可以看出榮耀X10日常使用隨手拍攝,沒有特別刻意調校參數拍攝出來的真實效果如何:從畫面的清晰度及質量到光線明暗的處理及光影的控制,榮耀X10的確讓我很驚喜,因為4000萬RYYB高感光影像系統在光線足的環境下拍攝,的確各方面的把控直出照片很不錯。當然也不能說搭載了RYYB高感光影像系統就絕對的完美了,而是在這個價位上能有高素質的手機并不多,與家族旗艦機型還是有一小段賽跑距離,期待加快固件升級對于拍攝性能的優化調校提升空間。




    上述樣張是沒有穩定器和三腳架的情況下,手持自動拍攝出來的傍晚入夜前夕,還有全夜拍樣張。可以看出照片中對于夜拍效果,基本上夜間暗光環境下會自動對暗部進行提亮,使得照片整體直出效果提升,暗光不再黑暗,保留更多細節,這些也是得益于榮耀X10搭載“底大一級”的1/1.7英寸傳感器以及F1.8大光圈。







    這2組樣張是自動模式拍攝和夜景模式拍攝的對比。還有局部細節的100%截圖對比,通過對比后就可以發現夜景模式在極暗環境下提升暗部的亮度,另外高光部分也會抑制避免過曝出現,簡單說就是該亮的地方亮了,該暗的地方暗了。夜景模式主要是使用AIS手持超級夜景2.0技術,通過6秒的曝光,和NPU能力,來實現綜合多幀圖像合成出來算法中最優的夜景照片,目前看夜景拍攝的樣片在放大之后還是會感覺一些細節出現涂抹比較明顯的地方,希望后期固件能跟上優化調校。給喜歡手機拍攝的小伙伴建議,如果想在夜拍中得到更純凈的照片,還是建議搭載三腳架來穩定拍攝,會比手持拍攝效果更好。




    上述樣張是使用超級微距拍攝,4厘米微距拍攝可以清晰看見磚頭塊上的縫隙還有苔蘚呈現星狀扁平葉狀的樣子、黃皮果上的表皮茸毛等。雖然只是2MP的微距鏡頭,但是成像素質還是很不錯的,如果可以放大,還是能看見2MP像素還是有點粗糙的。超級微距拍攝日常生活中可能很少用得上,如果未來升級能支持微距錄像功能,這樣可以做一些微距Vlog視頻拍攝,提升相機可玩性功能。



    鷹眼的AI極速抓拍也是這次榮耀X10拍攝功能特點,上述樣張我專門選擇了夜間環境和孩子滑輪取材拍攝,一來考驗暗光環境抓拍,二來滑輪速度很快,算是雙重考驗極速抓拍的苛刻條件了。可以從樣張照片看出,整體成片效果算是滿意的:凍結運動瞬間孩子急速滑過與后面慢一點的孩子追趕。在靜與動,動與速的多者之間都能比較出色實現抓拍效果,同樣后期還是有待提升,夜間極速抓拍最終還有有點“糊”,如果是白天光線好的環境抓拍效果會更突出一點,我就不特別做白天極速抓拍了,因為夜間的極速抓拍已經能很好反應出榮耀X10的抓拍能力。

    麒麟820的硬件性能



    榮耀X10搭載了有5G“神U”之稱的麒麟820移動平臺,使用7nm工藝制程,與8nm工藝相比,麒麟820能效高20%,晶體管密度高50%。整體性能較前代麒麟810搭載2個A76大核加6個A55小核的基礎上,麒麟820的CPU大小核組合:1個大核+3個中核(基于Cortex-A76開發)和4個小核(Cortex-A55),其中大核的主頻高達2.36GHz;麒麟820搭載全新的G57 MC6架構定制6核GPU,整體性能較前代提升25%,結合Kirin Gaming+2.0技術讓游戲體驗更好。對于它的性能到底是怎么樣的呢?我手上這臺榮耀X10 探速黑 8GB+128GB通過安兔兔跑分得出:345447(CPU:112296分,GPU:112650,MEM:61518分,UX:58983分),可見它的性能各方面的確很強悍。另外榮耀X10使用的存儲是LPDDR4X,存儲測試分值25188分(順序讀:7692分,速度502.7MB/s;順序寫:8536分,速度557.9MB/s;隨機讀寫:8960分,讀速度61.6MB/s,寫速度212.3MB/s)



    性能方面除了傳統的軟件跑分外,還有手游也是最能檢驗手機的整體性能,分別體驗了比較熱門的《王牌戰士》、《和平精英》等游戲進行測試。在游戲中,每款持續游戲時間2小時,游戲基本維持在最高幀最高特效狀態流暢穩定運行,整體出現的波動非常小,也沒有出現持續游戲導致的降頻問題。

    通過游戲測試,說明麒麟820對于游戲關聯線程優化很好,讓性能功耗調度使得游戲體驗保持流暢穩定,發熱量也很低,大約維持在35℃,保持溫感。雖然榮耀X10并不是電競游戲手機,但是搭載有石墨烯散熱,可以高效降溫讓手機不發熱。另外榮耀X10也自帶有【游戲空間】進行管理游戲,進入游戲之后左手向右滑動呼出菜單,可以在游戲空間可以針對游戲進行優化,提高游戲體驗感,例如游戲加速、QQ懸浮窗、消息免打擾、屏蔽截屏、網絡加速等特殊功能,再加上開啟90Hz高刷新率提升游戲操控流暢性,能給玩游戲帶來更好的游戲體驗感。


    首先了解一下現在5G的兩種組網模式:NSA/SA,NSA則是非獨立組網,SA即為獨立組網。兩種組網模式是目前全球通信業務中5G必須依賴的技術:NSA組網模式下是4G、5G共用核心網,所以運營商會節省很大部分的網絡投資,所以在NSA下設備的上下行傳輸及失效都比SA要差,并且因為NSA要同時連接雙路網絡,耗電情況也會有所提高。兩種組網模式性能固然差距不小,但也是4G向5G演變的必經之路,SA才是5G的最終方向。

    榮耀X10采用麒麟820 5G SoC,支持雙模NSA/SA全頻段5G通信,具備領先行業的5G速率。5G NR理論下行峰值速率達2.9Gbps,5G NR理論上行峰值速率達1.2Gbps,并且在目前實際現網環境中,實際上下行傳輸速率有明顯優勢。隨手測試了一下我當地的電信5G速度,下載速度大約為435Mbps/秒,目前全國各地的5G基站穩定性還不是非常好,這個速度沒有達到最佳峰值下載速度,但是相比4G的下載速度21.8Mbps/秒要快很多倍,現在下載大約2GB容量的游戲,最好狀態是10秒左右,真的是非常的快,當然5G使用的流量也很快,希望未來各大運營商加大5G套餐資費優惠力度,不然流量真的用不起。榮耀X10使用的是5G環繞式獨立側邊天線,針對5G需求,重構天線設計及布局,進一步提升橫屏體驗,實現單手上網、雙手游戲、頭手語音,全場景用戶常用握姿-同檔位5G+4G+WIFI 通信最優。

    榮耀X10的使用后感



    榮耀X10憑借潮流設計和極致性能,滿足了用戶的日常使用需求,1899元起的售價,加上硬件各方面性能,麒麟820作為中端來看,都有著很強的競爭力算是目前5G手機普及選擇中的一員,主要是它支持全頻段的雙模5G網絡頻段,不管在國內還是國外都能用上5G頻段。另外榮耀X10使用的是Magic UI 3.1系統,它也有一些很不錯實用型功能:YOYO語音助手、旅行助手、Hitouch智能識屏、情景智能等一些使用功能,來做到與生活實際做到融入化的體驗。榮耀X10到底值不值得入手呢?以5G手機來說,它的綜合各方面性能也體現了它屬于性價比手機中的一款,也算是中薪階層都能用得起的5G手機之一。當然也有一些不足,例如沒有使用目前新出的WiFi 6而是WiFi 5,使得在WiFi連接環境下,最多只能達到866Mbps的協議速度。希望這次分享能給關注今年5G手機的小伙伴們有所幫助喲,最后感謝數碼頻道提供本次測評產品。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有