最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單分析MySQL中的primary key功能

 更新時(shí)間:2015年05月08日 10:06:50   作者:羅龍九  
這篇文章主要介紹了MySQL中的primary key功能,包括講到了其對InnoDB使用的影響,需要的朋友可以參考下

在5.1.46中優(yōu)化器在對primary key的選擇上做了一點(diǎn)改動:

Performance: While looking for the shortest index for a covering index scan, the optimizer did not consider the full row length for a clustered primary key, as in InnoDB. Secondary covering indexes will now be preferred, making full table scans less likely。

該版本中增加了find_shortest_key函數(shù),該函數(shù)的作用可以認(rèn)為是選擇最小key length的

索引來滿足我們的查詢。

該函數(shù)是怎么工作的:

復(fù)制代碼 代碼如下:
What find_shortest_key should do is the following. If the primary key is a covering index

and is clustered, like in MyISAM, then the behavior today should remain the same. If the

primary key is clustered, like in InnoDB, then it should not consider using the primary

key because then the storage engine will have to scan through much more data.

調(diào)用Primary_key_is_clustered(),當(dāng)返回值為true,執(zhí)行find_shortest_key:選擇key length最小的覆蓋索引(Secondary covering indexes),然后來滿足查詢。

首先在5.1.45中測試:

$mysql -V

mysql Ver 14.14 Distrib 5.1.45, for unknown-linux-gnu (x86_64) using EditLine wrapper

root@test 03:49:45>create table test(id int,name varchar(20),name2 varchar(20),d datetime,primary key(id)) engine=innodb;

Query OK, 0 rows affected (0.16 sec)

root@test 03:49:47>insert into test values(1,'xc','sds',now()),(2,'xcx','dd',now()),(3,'sdds','ddd',now()),(4,'sdsdf','dsd',now()),(5,'sdsdaa','sds',now());

Query OK, 5 rows affected (0.00 sec)

Records: 5 Duplicates: 0 Warnings: 0

root@test 03:49:51>

root@test 03:49:51>insert into test values(6,'xce','sdsd',now()),(7,'xcx','sdsd',now()),(8,'sdds','sds',now()),(9,'sdsdsdf','sdsdsd',now()),(10,'sdssdfdaa','sdsdsd',now());

Query OK, 5 rows affected (0.00 sec)

Records: 5 Duplicates: 0 Warnings: 0

創(chuàng)建索引ind_1:

root@test 03:49:53>alter table test add index ind_1(name,d);

Query OK, 0 rows affected (0.09 sec)

Records: 0 Duplicates: 0 Warnings: 0

root@test 03:50:08>explain select count(*) from test;

+—-+————-+——-+——-+—————+———+———+——+——+————-+

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

+—-+————-+——-+——-+—————+———+———+——+——+————-+

| 1 | SIMPLE   | test | index | NULL     | PRIMARY | 4    | NULL |  10 | Using index |

+—-+————-+——-+——-+—————+———+———+——+——+————-+

1 row in set (0.00 sec)

添加ind_2:

root@test 08:04:35>alter table test add index ind_2(d);

Query OK, 0 rows affected (0.07 sec)

Records: 0 Duplicates: 0 Warnings: 0

root@test 08:04:45>explain select count(*) from test;

+—-+————-+——-+——-+—————+———+———+——+——+————-+

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

+—-+————-+——-+——-+—————+———+———+——+——+————-+

| 1 | SIMPLE   | test | index | NULL     | PRIMARY | 4    | NULL |  10 | Using index |

+—-+————-+——-+——-+—————+———+———+——+——+————-+

1 row in set (0.00 sec)

上面的版本【5.1.45】中,可以看到優(yōu)化器選擇使用主鍵來完成掃描,并沒有使用ind_1,ind_2來完成查詢;

接下來是:5.1.48

$mysql -V

mysql Ver 14.14 Distrib 5.1.48, for unknown-linux-gnu (x86_64) using EditLine wrapper

root@test 03:13:15> create table test(id int,name varchar(20),name2 varchar(20),d datetime,primary key(id)) engine=innodb;

Query OK, 0 rows affected (0.00 sec)

root@test 03:48:04>insert into test values(1,'xc','sds',now()),(2,'xcx','dd',now()),(3,'sdds','ddd',now()),(4,'sdsdf','dsd',now()),(5,'sdsdaa','sds',now());

Query OK, 5 rows affected (0.00 sec)

Records: 5 Duplicates: 0 Warnings: 0

root@test 03:48:05>insert into test values(6,'xce','sdsd',now()),(7,'xcx','sdsd',now()),(8,'sdds','sds',now()),(9,'sdsdsdf','sdsdsd',now()),(10,'sdssdfdaa','sdsdsd',now());

Query OK, 5 rows affected (0.01 sec)

Records: 5 Duplicates: 0 Warnings: 0

創(chuàng)建索引ind_1:

root@test 03:13:57>alter table test add index ind_1(name,d);

Query OK, 0 rows affected (0.01 sec)

Records: 0 Duplicates: 0 Warnings: 0

root@test 03:15:55>explain select count(*) from test;

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

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

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

| 1 | SIMPLE   | test | index | NULL     | ind_1 | 52   | NULL |  10 | Using index |

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

root@test 08:01:56>alter table test add index ind_2(d);

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

添加ind_2:

root@test 08:02:09>explain select count(*) from test;

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

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

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

| 1 | SIMPLE   | test | index | NULL     | ind_2 | 9    | NULL |  10 | Using index |

+—-+————-+——-+——-+—————+——-+———+——+——+————-+

1 row in set (0.00 sec)

版本【5.1.48】中首先明智的選擇ind_1來完成掃描,并沒有考慮到使用主鍵(全索引掃描)來完成查詢,隨后添加ind_2,由于 ind_1的key長度是大于ind_2 key長度,所以mysql選擇更優(yōu)的ind_2來完成查詢,可以看到mysql在選擇方式上也在慢慢智能了。

觀察性能:

5.1.48

root@test 08:49:32>set profiling =1;

Query OK, 0 rows affected (0.00 sec)

root@test 08:49:41>select count(*) from test;

+———-+

| count(*) |

+———-+

| 5242880 |

+———-+

1 row in set (1.18 sec)

root@test 08:56:30>show profile cpu,block io for query 1;

+——————————–+———-+———-+————+————–+—————+

| Status             | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |

+——————————–+———-+———-+————+————–+—————+

| starting            | 0.000035 | 0.000000 |  0.000000 |      0 |       0 |

| checking query cache for query | 0.000051 | 0.000000 |  0.000000 |      0 |       0 |

| Opening tables         | 0.000014 | 0.000000 |  0.000000 |      0 |       0 |

| System lock          | 0.000005 | 0.000000 |  0.000000 |      0 |       0 |

| Table lock           | 0.000010 | 0.000000 |  0.000000 |      0 |       0 |

| init              | 0.000015 | 0.000000 |  0.000000 |      0 |       0 |

| optimizing           | 0.000007 | 0.000000 |  0.000000 |      0 |       0 |

| statistics           | 0.000015 | 0.000000 |  0.000000 |      0 |       0 |

| preparing           | 0.000012 | 0.000000 |  0.000000 |      0 |       0 |

| executing           | 0.000007 | 0.000000 |  0.000000 |      0 |       0 |

| Sending data          | 1.178452 | 1.177821 |  0.000000 |      0 |       0 |

| end              | 0.000016 | 0.000000 |  0.000000 |      0 |       0 |

| query end           | 0.000005 | 0.000000 |  0.000000 |      0 |       0 |

| freeing items         | 0.000040 | 0.000000 |  0.000000 |      0 |       0 |

| logging slow query       | 0.000002 | 0.000000 |  0.000000 |      0 |       0 |

| logging slow query       | 0.000086 | 0.000000 |  0.000000 |      0 |       0 |

| cleaning up          | 0.000006 | 0.000000 |  0.000000 |      0 |       0 |

+——————————–+———-+———-+————+————–+—————+

對比性能:

5.1.45

root@test 08:57:18>set profiling =1;

Query OK, 0 rows affected (0.00 sec)

root@test 08:57:21>select count(*) from test;

+———-+

| count(*) |

+———-+

| 5242880 |

+———-+

1 row in set (1.30 sec)

root@test 08:57:27>show profile cpu,block io for query 1;

+——————————–+———-+———-+————+————–+—————+

| Status             | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |

+——————————–+———-+———-+————+————–+—————+

| starting            | 0.000026 | 0.000000 |  0.000000 |      0 |       0 |

| checking query cache for query | 0.000041 | 0.000000 |  0.000000 |      0 |       0 |

| Opening tables         | 0.000014 | 0.000000 |  0.000000 |      0 |       0 |

| System lock          | 0.000005 | 0.000000 |  0.000000 |      0 |       0 |

| Table lock           | 0.000008 | 0.000000 |  0.000000 |      0 |       0 |

| init              | 0.000015 | 0.000000 |  0.000000 |      0 |       0 |

| optimizing           | 0.000006 | 0.000000 |  0.000000 |      0 |       0 |

| statistics           | 0.000014 | 0.000000 |  0.000000 |      0 |       0 |

| preparing           | 0.000012 | 0.000000 |  0.000000 |      0 |       0 |

| executing           | 0.000007 | 0.000000 |  0.000000 |      0 |       0 |

| Sending data          | 1.294178 | 1.293803 |  0.000000 |      0 |       0 |

| end              | 0.000016 | 0.000000 |  0.000000 |      0 |       0 |

| query end           | 0.000004 | 0.000000 |  0.000000 |      0 |       0 |

| freeing items         | 0.000040 | 0.000000 |  0.001000 |      0 |       0 |

| logging slow query       | 0.000002 | 0.000000 |  0.000000 |      0 |       0 |

| logging slow query       | 0.000080 | 0.000000 |  0.000000 |      0 |       0 |

| cleaning up          | 0.000006 | 0.000000 |  0.000000 |      0 |       0 |

+——————————–+———-+———-+————+————–+—————+

從上面的profile中可以看到在Sending data上,差異還是比較明顯的,mysql不需要掃描整個(gè)表的頁塊,而是掃描表中索引key最短的索引頁塊來完成查詢,這樣就減少了很多不必要的數(shù)據(jù)。

PS:innodb是事務(wù)引擎,所以在葉子節(jié)點(diǎn)中除了存儲本行記錄外,還會多記錄一些關(guān)于事務(wù)的信息(DB_TRX_ID ,DB_ROLL_PTR 等),因此單行長度額外開銷20個(gè)字節(jié)左右,最直觀的方法是將myisam轉(zhuǎn)為innodb,存儲空間會明顯上升。那么在主表為t(id,name,pk(id)),二級索引ind_name(name,id),這個(gè)時(shí)候很容易混淆,即使只有兩個(gè)字段,第一索引還是比第二索引要大(可以通過innodb_table_monitor觀察表的的內(nèi)部結(jié)構(gòu))在查詢所有id的時(shí)候,優(yōu)化器還是會選擇第二索引ind_name。

相關(guān)文章

  • MYSQL SERVER收縮日志文件實(shí)現(xiàn)方法

    MYSQL SERVER收縮日志文件實(shí)現(xiàn)方法

    這篇文章主要介紹了MYSQL SERVER收縮日志文件實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 一篇文章看懂MySQL主從復(fù)制與讀寫分離

    一篇文章看懂MySQL主從復(fù)制與讀寫分離

    在實(shí)際的生產(chǎn)環(huán)境中,由單臺Mysql作為獨(dú)立的數(shù)據(jù)庫是完全不能滿足實(shí)際需求的,一般都是通過主從復(fù)制的方式來同步數(shù)據(jù),再通過讀寫分離(來提升數(shù)據(jù)庫的并發(fā)負(fù)載能力,這篇文章主要給大家介紹了關(guān)于MySQL主從復(fù)制與讀寫分離的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 解決從集合運(yùn)算到mysql的not like找不出NULL的問題

    解決從集合運(yùn)算到mysql的not like找不出NULL的問題

    這篇文章主要介紹了解決從集合運(yùn)算到mysql的not like找不出NULL的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • insert...on?duplicate?key?update語法詳解

    insert...on?duplicate?key?update語法詳解

    本文主要介紹了insert...on?duplicate?key?update語法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 如何利用MySQL的binlog恢復(fù)誤刪數(shù)據(jù)庫詳解

    如何利用MySQL的binlog恢復(fù)誤刪數(shù)據(jù)庫詳解

    MySQL一旦誤刪數(shù)據(jù)庫之后恢復(fù)數(shù)據(jù)很麻煩,這里記錄一下艱辛的恢復(fù)過程,這篇文章主要給大家介紹了關(guān)于如何利用MySQL的binlog恢復(fù)誤刪數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • MySQL表數(shù)據(jù)文件損壞導(dǎo)致數(shù)據(jù)庫無法啟動的原因與解決方案

    MySQL表數(shù)據(jù)文件損壞導(dǎo)致數(shù)據(jù)庫無法啟動的原因與解決方案

    在日常的數(shù)據(jù)庫管理中,遇到MySQL表數(shù)據(jù)文件損壞的情況并不罕見,這種情況下,MySQL數(shù)據(jù)庫可能會無法正常啟動,給業(yè)務(wù)運(yùn)行帶來嚴(yán)重影響,本文將探討如何診斷和解決MySQL表數(shù)據(jù)文件損壞導(dǎo)致的數(shù)據(jù)庫無法啟動問題,需要的朋友可以參考下
    2025-03-03
  • 一文帶你搞懂MySQL中的隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換

    一文帶你搞懂MySQL中的隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換

    在mysql中,當(dāng)操作涉及不同類型的數(shù)據(jù)時(shí),會根據(jù)一定的規(guī)則自動進(jìn)行類型轉(zhuǎn)換,本文主要來和大家聊聊隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換的相關(guān)知識,需要的可以參考一下
    2025-04-04
  • MySQL WorkBench管理操作MySQL教程

    MySQL WorkBench管理操作MySQL教程

    MySQL Workbench提供DBAs和developers一個(gè)集成工具環(huán)境,方便管理mysql數(shù)據(jù)庫,這里簡單介紹下MySQL Workbench使用方法,需要的朋友可以參考下
    2014-03-03
  • MySQL中使用replace、regexp進(jìn)行正則表達(dá)式替換的用法分析

    MySQL中使用replace、regexp進(jìn)行正則表達(dá)式替換的用法分析

    這篇文章主要介紹了MySQL中使用replace、regexp進(jìn)行正則表達(dá)式替換的用法,結(jié)合具體實(shí)例形式分析了replace、regexp正則替換的使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-03-03
  • 詳解一條sql語句在mysql中是如何執(zhí)行的

    詳解一條sql語句在mysql中是如何執(zhí)行的

    這篇文章主要介紹了一條sql語句在mysql中是如何執(zhí)行的,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評論

桂东县| 雷波县| 攀枝花市| 二连浩特市| 闸北区| 白城市| 修文县| 盐城市| 资中县| 建德市| 金塔县| 神池县| 南漳县| 余庆县| 河池市| 上思县| 遂平县| 微山县| 龙泉市| 大田县| 济宁市| 通城县| 龙口市| 夹江县| 沭阳县| 郑州市| 日照市| 新乐市| 峨山| 康乐县| 贡嘎县| 平昌县| 贵定县| 通江县| 绥中县| 台南市| 习水县| 肥乡县| 桐城市| 牟定县| 广宁县|