From d9253230f0f77e7fab4156ad36ce38cfd0e6ab73 Mon Sep 17 00:00:00 2001 From: dunwu Date: Tue, 27 Jun 2023 23:11:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20Mysql=20=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codes/mysql/SQL必知必会示例/README.md | 2 +- codes/mysql/SQL必知必会示例/create.sql | 18 +-- codes/mysql/SQL必知必会示例/select.sql | 12 +- .../SQL性能优化/SQL函数影响索引.sql | 119 ++++++++++++++++++ codes/mysql/SQL性能优化/等MDL锁.sql | 27 ++++ codes/mysql/基本DDL示例.sql | 35 +++--- 6 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 codes/mysql/SQL性能优化/SQL函数影响索引.sql create mode 100644 codes/mysql/SQL性能优化/等MDL锁.sql diff --git a/codes/mysql/SQL必知必会示例/README.md b/codes/mysql/SQL必知必会示例/README.md index 50ade32..4ec3603 100644 --- a/codes/mysql/SQL必知必会示例/README.md +++ b/codes/mysql/SQL必知必会示例/README.md @@ -1,3 +1,3 @@ # 源码说明 -> 本目录代码为 [《SQL 必知必会》](https://item.jd.com/11232698.html) 部分示例源码 +> 本目录代码为 [《SQL 必知必会》](https://book.douban.com/subject/35167240/) 部分示例源码 diff --git a/codes/mysql/SQL必知必会示例/create.sql b/codes/mysql/SQL必知必会示例/create.sql index b3928a2..b15e1c3 100644 --- a/codes/mysql/SQL必知必会示例/create.sql +++ b/codes/mysql/SQL必知必会示例/create.sql @@ -72,25 +72,25 @@ CREATE TABLE vendors ( -- Define primary keys -- ------------------- ALTER TABLE customers - ADD PRIMARY KEY (cust_id); +ADD PRIMARY KEY (cust_id); ALTER TABLE orderitems - ADD PRIMARY KEY (order_num, order_item); +ADD PRIMARY KEY (order_num, order_item); ALTER TABLE orders - ADD PRIMARY KEY (order_num); +ADD PRIMARY KEY (order_num); ALTER TABLE products - ADD PRIMARY KEY (prod_id); +ADD PRIMARY KEY (prod_id); ALTER TABLE vendors - ADD PRIMARY KEY (vend_id); +ADD PRIMARY KEY (vend_id); -- ------------------- -- Define foreign keys -- ------------------- ALTER TABLE orderitems - ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders(order_num); +ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders(order_num); ALTER TABLE orderitems - ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products(prod_id); +ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products(prod_id); ALTER TABLE orders - ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id) REFERENCES customers(cust_id); +ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id) REFERENCES customers(cust_id); ALTER TABLE products - ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors(vend_id); +ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors(vend_id); diff --git a/codes/mysql/SQL必知必会示例/select.sql b/codes/mysql/SQL必知必会示例/select.sql index 79dd3d4..9f63a09 100644 --- a/codes/mysql/SQL必知必会示例/select.sql +++ b/codes/mysql/SQL必知必会示例/select.sql @@ -1,8 +1,8 @@ -/** - * Mysql 查询示例 - * @author Zhang Peng - * @date 2018/5/5 - */ +-- -------------------------------------------------------------------------------------- +-- Mysql 查询示例 +-- @author Zhang Peng +-- @date 2018/5/5 +-- ---------------------------------------------------------------------------------------- -- ------------------------------------------- -- 查询数据 @@ -24,7 +24,7 @@ FROM products; SELECT DISTINCT vend_id FROM products; --- 限制结果 +-- 限制查询数量 -- 返回前 5 行(1) SELECT * FROM products diff --git a/codes/mysql/SQL性能优化/SQL函数影响索引.sql b/codes/mysql/SQL性能优化/SQL函数影响索引.sql new file mode 100644 index 0000000..1420f99 --- /dev/null +++ b/codes/mysql/SQL性能优化/SQL函数影响索引.sql @@ -0,0 +1,119 @@ +-- -------------------------------------------------------------------------------------- +-- 函数操作影响索引效率示例 +-- @author Zhang Peng +-- ---------------------------------------------------------------------------------------- + +-- 步骤 1、建表 +CREATE TABLE tradelog ( + id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Id', + tradeid VARCHAR(32) DEFAULT NULL, + operator INT(11) DEFAULT NULL, + t_modified DATETIME DEFAULT NULL, + PRIMARY KEY (id), + KEY tradeid(tradeid), + KEY t_modified(t_modified) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4; + +CREATE TABLE trade_detail ( + id INT(11) NOT NULL, + tradeid VARCHAR(32) DEFAULT NULL, + trade_step INT(11) DEFAULT NULL, /* 操作步骤 */ + step_info VARCHAR(32) DEFAULT NULL, /* 步骤信息 */ + PRIMARY KEY (id), + KEY tradeid(tradeid) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +-- 步骤 2、存储过程初始化数据 + +INSERT INTO trade_detail +VALUES (1, 'aaaaaaaa', 1, 'add'); +INSERT INTO trade_detail +VALUES (2, 'aaaaaaaa', 2, 'update'); +INSERT INTO trade_detail +VALUES (3, 'aaaaaaaa', 3, 'commit'); +INSERT INTO trade_detail +VALUES (4, 'aaaaaaab', 1, 'add'); +INSERT INTO trade_detail +VALUES (5, 'aaaaaaab', 2, 'update'); +INSERT INTO trade_detail +VALUES (6, 'aaaaaaab', 3, 'update again'); +INSERT INTO trade_detail +VALUES (7, 'aaaaaaab', 4, 'commit'); +INSERT INTO trade_detail +VALUES (8, 'aaaaaaac', 1, 'add'); +INSERT INTO trade_detail +VALUES (9, 'aaaaaaac', 2, 'update'); +INSERT INTO trade_detail +VALUES (10, 'aaaaaaac', 3, 'update again'); +INSERT INTO trade_detail +VALUES (11, 'aaaaaaac', 4, 'commit'); + +INSERT INTO tradelog +VALUES (1, 'aaaaaaaa', 1000, now()); +INSERT INTO tradelog +VALUES (2, 'aaaaaaab', 1000, now()); +INSERT INTO tradelog +VALUES (3, 'aaaaaaac', 1000, now()); + +DELIMITER ;; +DROP PROCEDURE IF EXISTS init; +CREATE PROCEDURE init() +BEGIN + DECLARE i INT; + SET i = 3; + WHILE i < 10000 + DO + INSERT INTO tradelog(tradeid, operator, t_modified) + VALUES (concat(char(97 + (i DIV 1000)), char(97 + (i % 1000 DIV 100)), char(97 + (i % 100 DIV 10)), + char(97 + (i % 10))), i, now()); + SET i = i + 1; + END WHILE; +END;; +DELIMITER ; +CALL init(); + +-- 步骤 3、执行计划查看SQL效率 +-- 3.1.1 此 SQL 对索引字段做函数操作,优化器会放弃走树搜索功能,改为全表扫描 +EXPLAIN +SELECT count(*) +FROM tradelog +WHERE month(t_modified) = 7; + +-- 3.1.2 SQL 优化 +EXPLAIN +SELECT count(*) +FROM tradelog +WHERE (t_modified >= '2016-7-1' AND t_modified < '2016-8-1') OR + (t_modified >= '2017-7-1' AND t_modified < '2017-8-1') OR + (t_modified >= '2018-7-1' AND t_modified < '2018-8-1'); + +-- 3.2.1 此 SQL 对索引字段隐式的使用了转换函数操作,优化器会放弃走树搜索功能,改为全表扫描 +-- 相当于 select * from tradelog where CAST(tradid AS signed int) = 110717; +EXPLAIN +SELECT * +FROM tradelog +WHERE tradeid = 110717; + +-- 3.3.1 下面两条 SQL 的扫描行数不同 +-- 原因是:字符集 utf8mb4 是 utf8 的超集,所以当这两个类型的字符串在做比较的时候, +-- MySQL 内部的操作是,先把 utf8 字符串转成 utf8mb4 字符集,再做比较。 +# 需要做字符编码转换 +EXPLAIN +SELECT d.* +FROM tradelog l, trade_detail d +WHERE d.tradeid = l.tradeid AND l.id = 2; + +# 上面的 SQL 等价于这条注掉的 SQL +# SELECT * +# FROM trade_detail +# WHERE CONVERT(traideid USING utf8mb4) = $l2.tradeid.value; + +# 不需要做字符编码转换 +EXPLAIN +SELECT l.operator +FROM tradelog l, trade_detail d +WHERE d.tradeid = l.tradeid AND d.id = 2; diff --git a/codes/mysql/SQL性能优化/等MDL锁.sql b/codes/mysql/SQL性能优化/等MDL锁.sql new file mode 100644 index 0000000..1270ad4 --- /dev/null +++ b/codes/mysql/SQL性能优化/等MDL锁.sql @@ -0,0 +1,27 @@ +-- -------------------------------------------------------------------------------------- +-- 函数操作影响索引效率示例 +-- @author Zhang Peng +-- ---------------------------------------------------------------------------------------- + +CREATE TABLE t ( + id INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Id', + c INT(11) DEFAULT NULL, + PRIMARY KEY (id) +) + ENGINE = InnoDB; + +DELIMITER ;; +DROP PROCEDURE IF EXISTS init; +CREATE PROCEDURE init() +BEGIN + DECLARE i INT; + SET i = 1; + WHILE(i <= 100000) + DO + INSERT INTO t VALUES (i, i); + SET i = i + 1; + END WHILE; +END;; +DELIMITER ; + +CALL init(); diff --git a/codes/mysql/基本DDL示例.sql b/codes/mysql/基本DDL示例.sql index 87e937d..894b933 100644 --- a/codes/mysql/基本DDL示例.sql +++ b/codes/mysql/基本DDL示例.sql @@ -7,7 +7,7 @@ -- --------------------------------------------------------------------- 数据库定义 --- 撤销数据库 test +-- 删除数据库 db_tutorial DROP DATABASE IF EXISTS db_tutorial; -- 创建数据库 db_tutorial @@ -18,11 +18,11 @@ USE db_tutorial; -- --------------------------------------------------------------------- 数据表定义 --- 撤销表 user +-- 删除数据表 user DROP TABLE IF EXISTS user; DROP TABLE IF EXISTS vip_user; --- 创建表 user +-- 创建数据表 user CREATE TABLE user ( id INT(10) UNSIGNED NOT NULL COMMENT 'Id', username VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '用户名', @@ -37,31 +37,32 @@ FROM user; -- 添加列 age ALTER TABLE user - ADD age INT(3); +ADD age INT(3); -- 修改列 age 的类型为 tinyint ALTER TABLE user - MODIFY COLUMN age TINYINT; +MODIFY COLUMN age TINYINT; --- 撤销列 age +-- 删除列 age ALTER TABLE user - DROP COLUMN age; +DROP COLUMN age; -- --------------------------------------------------------------------- 索引定义 --- 创建表 user 的索引 user_index -CREATE INDEX user_index - ON user(id); +-- 创建表的索引 +CREATE INDEX idx_email + ON user(email); --- 创建表 user 的唯一索引 user_index2 -CREATE UNIQUE INDEX user_index2 - ON user(id); +-- 创建表的唯一索引 +CREATE UNIQUE INDEX uniq_username + ON user(username); --- 撤销表 user 的索引 +-- 删除表 user 的索引 ALTER TABLE user - DROP INDEX user_index; +DROP INDEX idx_email; + ALTER TABLE user - DROP INDEX user_index2; +DROP INDEX uniq_username; -- --------------------------------------------------------------------- 视图定义 @@ -71,5 +72,5 @@ SELECT id, username FROM user WHERE id < 10; --- 撤销表 user 的视图 top_10_user_view +-- 删除表 user 的视图 top_10_user_view DROP VIEW top_10_user_view;