MySQL中varchar(50)和varchar(500)區(qū)別是什么?
共 10872字,需瀏覽 22分鐘
·
2024-06-24 09:19
往期熱門文章:
一. 問題描述
-
對于可變長度的字段,在滿足條件的前提下,盡可能使用較短的變長字段長度。
-
基于存儲空間的考慮 -
基于性能的考慮
Varchar(50)和varchar(500)存儲空間上是一樣的,真的是這樣嗎?
二.驗證存儲空間區(qū)別
1.準備兩張表
CREATE TABLE `category_info_varchar_50` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` varchar(50) NOT NULL COMMENT '分類名稱',
`is_show` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否展示:0 禁用,1啟用',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '序號',
`deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除',
`create_time` datetime NOT NULL COMMENT '創(chuàng)建時間',
`update_time` datetime NOT NULL COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE COMMENT '名稱索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分類';
CREATE TABLE `category_info_varchar_500` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` varchar(500) NOT NULL COMMENT '分類名稱',
`is_show` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否展示:0 禁用,1啟用',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '序號',
`deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除',
`create_time` datetime NOT NULL COMMENT '創(chuàng)建時間',
`update_time` datetime NOT NULL COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE COMMENT '名稱索引'
) ENGINE=InnoDB AUTO_INCREMENT=288135 DEFAULT CHARSET=utf8mb4 COMMENT='分類';
2.準備數(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.驗證存儲空間
SELECT
table_schema AS "數(shù)據(jù)庫",
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;
SELECT
table_schema AS "數(shù)據(jù)庫",
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;
4.結(jié)論
三.驗證性能區(qū)別
1.驗證索引覆蓋查詢
select name from category_info_varchar_50 where name = 'name100000'
-- 耗時0.012s
select name from category_info_varchar_500 where name = 'name100000'
-- 耗時0.012s
select name from category_info_varchar_50 order by name;
-- 耗時0.370s
select name from category_info_varchar_500 order by name;
-- 耗時0.379s
1.驗證索引查詢
select * from category_info_varchar_50 where name = 'name100000'
--耗時 0.012s
select * from category_info_varchar_500 where name = 'name100000'
--耗時 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')
-- 耗時 0.011s -0.014s
-- 增加 order by name 耗時 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')
-- 耗時 0.012s -0.014s
-- 增加 order by name 耗時 0.014s - 0.017s
3.驗證全表查詢和排序
全表無排序
全表有排序
select * from category_info_varchar_50 order by name ;
--耗時 1.498s
select * from category_info_varchar_500 order by name ;
--耗時 4.875s
結(jié)論:
分析原因
varchar50 全表執(zhí)行sql分析
varchar500 全表執(zhí)行sql分析
四.最終結(jié)論
來源:juejin.cn/post/7350228838151847976
往期熱門文章:
1、驚艷到我的 10個 MySQL高級查詢技巧!
2、我有點想用JDK17了
3、解放大腦:ChatGPT + PlantUML = 不用畫圖了
4、高逼格的SQL寫法:行行比較
5、限流算法哪家強?時間窗口,令牌桶與漏桶算法對比
6、每天都提交代碼,那你知道.git目錄內(nèi)部的秘密嗎?
7、我患上了空指針后遺癥
8、這10個小技巧讓你減少80%的Bug!
9、升級 JDK17 一個不可拒絕的理由
10、SQL中為什么不要使用1=1?
評論
圖片
表情
