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

MySQL?中?Varchar(50)?和?varchar(500)?區(qū)別介紹

 更新時(shí)間:2024年08月01日 09:29:38   作者:數(shù)據(jù)派  
網(wǎng)上說(shuō)Varchar(50)和varchar(500)存儲(chǔ)空間上是一樣的,真的是這樣嗎,基于性能考慮,是因?yàn)檫^(guò)長(zhǎng)的字段會(huì)影響到查詢(xún)性能,本文我將帶著這兩個(gè)問(wèn)題探討驗(yàn)證一下,需要的朋友可以參考下

問(wèn)題

我們?cè)谠O(shè)計(jì)表結(jié)構(gòu)的時(shí)候,設(shè)計(jì)規(guī)范里面有一條如下規(guī)則:對(duì)于可變長(zhǎng)度的字段,在滿(mǎn)足條件的前提下,盡可能使用較短的變長(zhǎng)字段長(zhǎng)度。為什么這么規(guī)定,主要基于兩個(gè)方面

  • 基于存儲(chǔ)空間的考慮

  • 基于性能的考慮

網(wǎng)上說(shuō)Varchar(50)和varchar(500)存儲(chǔ)空間上是一樣的,真的是這樣嗎?基于性能考慮,是因?yàn)檫^(guò)長(zhǎng)的字段會(huì)影響到查詢(xún)性能?
本文我將帶著這兩個(gè)問(wèn)題探討驗(yàn)證一下:

驗(yàn)證存儲(chǔ)空間的區(qū)別

1、準(zhǔn)備兩張表

CREATE TABLE `category_info_varchar_50` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(50) NOT NULL COMMENT '分類(lèi)名稱(chēng)',
  `is_show` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否展示:0 禁用,1啟用',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '序號(hào)',
  `deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除',
  `create_time` datetime NOT NULL COMMENT '創(chuàng)建時(shí)間',
  `update_time` datetime NOT NULL COMMENT '更新時(shí)間',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_name` (`name`) USING BTREE COMMENT '名稱(chēng)索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分類(lèi)';
CREATE TABLE `category_info_varchar_500` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(500) NOT NULL COMMENT '分類(lèi)名稱(chēng)',
  `is_show` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否展示:0 禁用,1啟用',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '序號(hào)',
  `deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除',
  `create_time` datetime NOT NULL COMMENT '創(chuàng)建時(shí)間',
  `update_time` datetime NOT NULL COMMENT '更新時(shí)間',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_name` (`name`) USING BTREE COMMENT '名稱(chēng)索引'
) ENGINE=InnoDB AUTO_INCREMENT=288135 DEFAULT CHARSET=utf8mb4 COMMENT='分類(lèi)';

2、準(zhǔn)備數(shù)據(jù)

給每張表插入相同的數(shù)據(jù),為了凸顯不同,插入100萬(wàn)條數(shù)據(jù)

DELIMITER $$
CREATE PROCEDURE batchInsertData(IN total INT)
BEGIN
    DECLARE start_idx INT DEFAULT 1;
    DECLARE end_idx INT;
    DECLARE batch_size INT DEFAULT 500;
    DECLARE insert_values TEXT;
    SET end_idx = LEAST(total, start_idx + batch_size - 1);
    WHILE start_idx <= total DO
        SET insert_values = '';
        WHILE start_idx <= end_idx DO
            SET insert_values = CONCAT(insert_values, CONCAT('(\'name', start_idx, '\', 0, 0, 0, NOW(), NOW()),'));
            SET start_idx = start_idx + 1;
        END WHILE;
        SET insert_values = LEFT(insert_values, LENGTH(insert_values) - 1); -- Remove the trailing comma
        SET @sql = CONCAT('INSERT INTO category_info_varchar_50 (name, is_show, sort, deleted, create_time, update_time) VALUES ', insert_values, ';');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
      SET @sql = CONCAT('INSERT INTO category_info_varchar_500 (name, is_show, sort, deleted, create_time, update_time) VALUES ', insert_values, ';'); 
      PREPARE stmt FROM @sql;
        EXECUTE stmt;
        SET end_idx = LEAST(total, start_idx + batch_size - 1);
    END WHILE;
END$$
DELIMITER ;
CALL batchInsertData(1000000);

3、驗(yàn)證存儲(chǔ)空間

查詢(xún)第一張表SQL

SELECT
    table_schema AS "數(shù)據(jù)庫(kù)",
    table_name AS "表名",
    table_rows AS "記錄數(shù)",
    TRUNCATE ( data_length / 1024 / 1024, 2 )  AS "數(shù)據(jù)容量(MB)",
    TRUNCATE ( index_length / 1024 / 1024, 2 )  AS "索引容量(MB)" 
FROM
    information_schema.TABLES 
WHERE
    table_schema = 'test_mysql_field' 
and TABLE_NAME = 'category_info_varchar_50'
ORDER BY
    data_length DESC,
    index_length DESC;

查詢(xún)結(jié)果

查詢(xún)第二張表SQL

SELECT
    table_schema AS "數(shù)據(jù)庫(kù)",
    table_name AS "表名",
    table_rows AS "記錄數(shù)",
    TRUNCATE ( data_length / 1024 / 1024, 2 )  AS "數(shù)據(jù)容量(MB)",
    TRUNCATE ( index_length / 1024 / 1024, 2 )  AS "索引容量(MB)" 
FROM
    information_schema.TABLES 
WHERE
    table_schema = 'test_mysql_field' 
and TABLE_NAME = 'category_info_varchar_500'
ORDER BY
    data_length DESC,
    index_length DESC;

查詢(xún)結(jié)果

4、結(jié)論

兩張表在占用空間上確實(shí)是一樣的,并無(wú)差別。

驗(yàn)證性能區(qū)別

1、驗(yàn)證索引覆蓋查詢(xún)

select name from category_info_varchar_50 where name = 'name100000'
-- 耗時(shí)0.012s
select name from category_info_varchar_500 where name = 'name100000'
-- 耗時(shí)0.012s
select name from category_info_varchar_50 order by name;
-- 耗時(shí)0.370s
select name from category_info_varchar_500 order by name;
-- 耗時(shí)0.379s

通過(guò)索引覆蓋查詢(xún)性能差別不大

2、驗(yàn)證索引查詢(xún)

select * from category_info_varchar_50 where name = 'name100000'
--耗時(shí) 0.012s
select * from category_info_varchar_500 where name = 'name100000'
--耗時(shí) 0.012s
select * from category_info_varchar_50 where name in('name100','name1000','name100000','name10000','name1100000',
'name200','name2000','name200000','name20000','name2200000','name300','name3000','name300000','name30000','name3300000',
'name400','name4000','name400000','name40000','name4400000','name500','name5000','name500000','name50000','name5500000',
'name600','name6000','name600000','name60000','name6600000','name700','name7000','name700000','name70000','name7700000','name800',
'name8000','name800000','name80000','name6600000','name900','name9000','name900000','name90000','name9900000') 
-- 耗時(shí) 0.011s -0.014s 
-- 增加 order by name 耗時(shí) 0.012s - 0.015s
select * from category_info_varchar_50 where name in('name100','name1000','name100000','name10000','name1100000',
'name200','name2000','name200000','name20000','name2200000','name300','name3000','name300000','name30000','name3300000',
'name400','name4000','name400000','name40000','name4400000','name500','name5000','name500000','name50000','name5500000',
'name600','name6000','name600000','name60000','name6600000','name700','name7000','name700000','name70000','name7700000','name800',
'name8000','name800000','name80000','name6600000','name900','name9000','name900000','name90000','name9900000') 
-- 耗時(shí)  0.012s -0.014s 
-- 增加 order by name 耗時(shí) 0.014s - 0.017s

索引范圍查詢(xún)性能基本相同, 增加了order By后開(kāi)始有一定性能差別;

3、驗(yàn)證全表查詢(xún)和排序

全表無(wú)排序

全表有排序

select * from category_info_varchar_50 order by  name ;
--耗時(shí) 1.498s
select * from category_info_varchar_500 order by  name  ;
--耗時(shí) 4.875s

結(jié)論:

全表掃描無(wú)排序情況下,兩者性能無(wú)差異,在全表有排序的情況下, 兩種性能差異巨大;

分析原因

varchar50 全表執(zhí)行sql分析

我發(fā)現(xiàn)86%的時(shí)花在數(shù)據(jù)傳輸上,接下來(lái)我們看狀態(tài)部分,關(guān)注Created_tmp_files和sort_merge_passes

Created_tmp_files為3

sort_merge_passes為95

varchar500 全表執(zhí)行sql分析

增加了臨時(shí)表排序

Created_tmp_files 為 4

sort_merge_passes為645

關(guān)于sort_merge_passes, Mysql給出了如下描述:

Number of merge passes that the sort algorithm has had to do. If this value is large, you may want to increase the value of the sort_buffer_size.

其實(shí)sort_merge_passes對(duì)應(yīng)的就是MySQL做歸并排序的次數(shù),也就是說(shuō),如果sort_merge_passes值比較大,說(shuō)明sort_buffer和要排序的數(shù)據(jù)差距越大,我們可以通過(guò)增大sort_buffer_size或者讓填入sort_buffer_size的鍵值對(duì)更小來(lái)緩解sort_merge_passes歸并排序的次數(shù)。

最終結(jié)論

至此,我們不難發(fā)現(xiàn),當(dāng)我們最該字段進(jìn)行排序操作的時(shí)候,Mysql會(huì)根據(jù)該字段的設(shè)計(jì)的長(zhǎng)度進(jìn)行內(nèi)存預(yù)估,如果設(shè)計(jì)過(guò)大的可變長(zhǎng)度,會(huì)導(dǎo)致內(nèi)存預(yù)估的值超出sort_buffer_size的大小,導(dǎo)致mysql采用磁盤(pán)臨時(shí)文件排序,最終影響查詢(xún)性能。

相關(guān)文章

  • 64位CentOs7源碼安裝mysql-5.6.35過(guò)程分享

    64位CentOs7源碼安裝mysql-5.6.35過(guò)程分享

    本文給大家分享的是在64位CentOs7系統(tǒng)中使用源碼安裝mysql-5.6.35的詳細(xì)過(guò)程,非常的細(xì)致,有需要的小伙伴可以參考下
    2017-02-02
  • MySQL存儲(chǔ)引擎InnoDB架構(gòu)原理和執(zhí)行流程

    MySQL存儲(chǔ)引擎InnoDB架構(gòu)原理和執(zhí)行流程

    InnoDB是MySQL的當(dāng)前默認(rèn)存儲(chǔ)引擎,支持外鍵、行級(jí)鎖定和ACID事務(wù),通過(guò)BufferPool緩沖池緩存數(shù)據(jù),RedoLogBuffer和undo日志文件保證數(shù)據(jù)的持久性和回滾能力,MySQL宕機(jī)重啟時(shí),InnoDB會(huì)根據(jù)LSN值決定是否需要從redo日志恢復(fù)數(shù)據(jù)
    2025-04-04
  • MySQL-group-replication 配置步驟(推薦)

    MySQL-group-replication 配置步驟(推薦)

    下面小編就為大家?guī)?lái)一篇MySQL-group-replication 配置步驟(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • MySQL基本命令、常用命令總結(jié)

    MySQL基本命令、常用命令總結(jié)

    這篇文章主要介紹了MySQL基本命令、常用命令總結(jié),需要的朋友可以參考下
    2014-03-03
  • MySQL數(shù)據(jù)庫(kù)中外鍵(foreign?key)用法詳解

    MySQL數(shù)據(jù)庫(kù)中外鍵(foreign?key)用法詳解

    這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫(kù)中外鍵(foreign?key)的相關(guān)資料,MySQL 外鍵約束可以用來(lái)保證表與表之間的關(guān)系完整性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • MySQL中Multiple primary key defined報(bào)錯(cuò)的解決辦法

    MySQL中Multiple primary key defined報(bào)錯(cuò)的解決辦法

    這篇文章主要介紹了MySQL中Multiple primary key defined報(bào)錯(cuò)的解決辦法以及相關(guān)實(shí)例內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2019-08-08
  • 利用MySQL系統(tǒng)數(shù)據(jù)庫(kù)做性能負(fù)載診斷的方法

    利用MySQL系統(tǒng)數(shù)據(jù)庫(kù)做性能負(fù)載診斷的方法

    這篇文章主要介紹了利用MySQL系統(tǒng)數(shù)據(jù)庫(kù)做性能負(fù)載診斷的方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • mysql中如何設(shè)置大小寫(xiě)不敏感

    mysql中如何設(shè)置大小寫(xiě)不敏感

    這篇文章主要介紹了mysql中如何設(shè)置大小寫(xiě)不敏感問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Navicat如何查看并導(dǎo)出ER圖

    Navicat如何查看并導(dǎo)出ER圖

    文章主要介紹了使用Navicat查看和導(dǎo)出數(shù)據(jù)庫(kù)的ER圖的方法,包括在數(shù)據(jù)庫(kù)表右下角選擇ER圖表查看數(shù)據(jù)庫(kù)結(jié)構(gòu),以及通過(guò)逆向工程導(dǎo)出ER圖文件為PDF、PNG或SVG格式,并分享了一個(gè)導(dǎo)出的ER圖示例
    2026-04-04
  • mysql用戶(hù)管理和權(quán)限設(shè)置方式

    mysql用戶(hù)管理和權(quán)限設(shè)置方式

    這篇文章主要介紹了mysql用戶(hù)管理和權(quán)限設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評(píng)論

崇文区| 高要市| 邛崃市| 天祝| 贵州省| 辽宁省| 墨竹工卡县| 宁明县| 佛山市| 若尔盖县| 江孜县| 安西县| 上杭县| 宜春市| 英山县| 巢湖市| 南昌县| 堆龙德庆县| 温州市| 托克托县| 南木林县| 揭西县| 涡阳县| 新疆| 红河县| 滁州市| 吴桥县| 松江区| 玛多县| 武义县| 崇义县| 托克逊县| 廉江市| 额济纳旗| 万盛区| 平舆县| 晋州市| 新龙县| 瓮安县| 通辽市| 义乌市|