ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL-视图-触发器-事务-存储过程-函数-流程控制-索引与慢查询优化-06

2019-08-24 22:01:33  阅读:207  来源: 互联网

标签:06 name mysql 视图 索引 MySQL 磁盘 id select


目录

小科普

核心业务逻辑代码一般都是放在服务端

客户端容易被懂行点的人修改源码,造成损失

视图***

什么是视图

一个查询语句的结果是虚拟表,将(查询出)这张虚拟表(的sql语句)保存下来,他就变成了一个视图(mysql中还是以表的形式存在的)

为什么要用视图

当频繁需要用到多张表的联表结果,你就可以事先生成好视图,之后直接调用即可,避免了反复写联表操作的 sql 语句(实际效果相当于再次执行语句)

如何生成视图

# 语法
create view 视图名 as 生成虚拟表的查询语句

create view teacher_course as select * from teacher inner join course on teacher.tid = course.teacher_id;

show tables  # 即可看到该视图(当做表了)
select * from teacher_course;  # 看到的就是

修改视图 --> 最好(千万)不要

关联表数据改动前

关联表数据改动之后

视图中的数据自动更新了--> 执行查询视图记录语句 = 重新执行了创建视图的那个sql 语句

注意:

1.视图只有表结构,视图中的数据还是来源于原来的表

2.不要改动视图表中的数据(可能会报错,也可能会改其他表的数据)

​ ---> 我在cmd终端改动影响到了其他表

3.不要太依赖视图,尽量少用视图来写业务逻辑

  • 视图会影响性能,占用硬盘资源、数据库资源
  • 工作中可能是别的部门的人管理数据库,跨部门交流比较麻烦,而且如果别人改动了视图关联表,或删了视图那涉及到的业务逻辑就很危险了。

触发器

什么是触发器

到达某个条件自动触发

触发条件

当你在对数据进行增删改的情况下会自动触发触发器的运行

触发器语法结构

修改mysql的默认结束符(;)

delimiter $$ # --> 默认 ; 改成了 $$只对当前窗口有效,重新登录也会无效

delimiter $$ # 改变当前窗口sql 语句的结束符
create trigger 触发器的名字 after/before insert/update/delete on 表名 for each row
begin
    # 操作其他表的sql 语句
end $$
delimiter ;  # 把sql结束符改回 ;

# 触发器常见命名格式:tri_before/after_insert/update/delete_表名

触发器死循环

触发器里面的代码会触发触发器本身的执行,造成了死循环

在触发器里面千万不要写操作本表的语句,增删改查都不要,会报错

比如:user表的 新增前触发器 代码块内写的是 user表的新增插值操作,就会造成触发器死循环(直接报错)

六个触发器的执行时机

新增前、新增后、删除前、删除后、更新前、更新后

小案例(新增后)

create table user(
    id int primary key auto_increment,
    name varchar(32) not null,
    password varchar(255) not null
)

create table log(
    id int primary key auto_increment,
    message varchar(255)
);


drop trigger tri_after_insert_user;  # 删除已存在的触发器 tri_after_insert_user
delimiter $$
create trigger tri_after_insert_user after insert on user for each row
begin
    # insert into user(name, password) values('老子翻车了', '123');  # 死循环了,像递归,不断触发这个触发器
    # select * from user;  # 也会报错,触发器里不能返回值 Not allowed to return a result set from a trigger
    insert into log(message) values ('看到我就说明你没翻车');
end $$
delimiter ;

insert into user(name, password) values('会翻车吗', '可能吧');

select * from user;
select * from log;

# 删除触发器
drop trigger tri_after_insert_user;

扩展: 视图、存储过程的查看

摘抄自:mysql查看存储过程函数

# 查询数据库中的存储过程和函数
       select `name` from mysql.proc where db = 'xx' and `type` = 'PROCEDURE'  # 存储过程
       select `name` from mysql.proc where db = 'xx' and `type` = 'FUNCTION'   # 函数

       show procedure status\G;  # 存储过程(\G 竖式排版查看,横的太长了 看不清)
       show function status\G;  # 函数

# 查看存储过程或函数的创建代码

  show create procedure proc_name\G;
  show create function func_name\G;

# 查看视图
  SELECT * from information_schema.VIEWS;   # 视图
  SELECT * from information_schema.TABLES;   # 表

# 查看触发器
  SHOW TRIGGERS [FROM db_name] [LIKE expr]
  SELECT * FROM triggers T WHERE trigger_name="mytrigger"\G;

NEW对象指代的就是当前记录(对象)

NEW 对象可以取到触发这个触发器的sql语句的记录对象,通过 . 字段名 的方式来获取到字段值

# 案例 (mysql大小写不敏感)
CREATE TABLE cmd (
    id INT PRIMARY KEY auto_increment,
    USER CHAR (32),
    priv CHAR (10),
    cmd CHAR (64),
    sub_time datetime, #提交时间
    success enum ('yes', 'no') #0代表执行失败
);

CREATE TABLE errlog (
    id INT PRIMARY KEY auto_increment,
    err_cmd CHAR (64),
    err_time datetime
);

delimiter $$  # 将mysql默认的结束符由;换成$$
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
    if NEW.success = 'no' then  # 新记录都会被MySQL封装成NEW对象
        insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
    end if;
end $$
delimiter ;  # 结束之后记得再改回来,不然后面结束符就都是$$了

#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
    USER,
    priv,
    cmd,
    sub_time,
    success
)
VALUES
    ('egon','0755','ls -l /etc',NOW(),'yes'),
    ('egon','0755','cat /etc/passwd',NOW(),'no'),
    ('egon','0755','useradd xxx',NOW(),'no'),
    ('egon','0755','ps aux',NOW(),'yes');

# 查询errlog表记录
select * from errlog;
# 删除触发器
drop trigger tri_after_insert_cmd;

事务 *****

什么是事务

事务包含一堆sql语句,要么全部成功,要么都不成功

事务的四大特性 ACID

用自己的话背下来

A:原子性 atomicity

一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

C:一致性 consistency

事务必须是使数据库从一个一致性状态变到另一个一致性状态。

一致性与原子性是密切相关的。

I:隔离性 isolation

一个事务的执行不能被其他事务干扰。

即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

D:持久性 durability

持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

接下来的其他操作或故障不应该对其有任何影响。

如何开启事务

start transaction 标志下面的语句都是 事务

事务开始后,只会在内存中修改

只有commit 之后才会写到硬盘上

事务回滚

rollback 事务开始的地方到这里的语句都会回滚(失效)

永久性更改

commit 把数据刷在硬盘上,后面再 rollback 就回滚不回去了

start transaction、rollback、commit 有点像python异常捕获的 try ... except ... else ...

小案例

create table user(
id int primary key auto_increment,
name char(32),
balance int
);

insert into user(name,balance)
values
('wsb',1000),
('egon',1000),
('ysb',1000);

# 修改数据之前先开启事务操作
start transaction;

# 修改操作
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元

# 回滚到上一个状态
rollback;

# 开启事务之后,只要没有执行commit操作,数据其实都没有真正刷新到硬盘
commit;
"""开启事务检测操作是否完整,不完整主动回滚到上一个状态,如果完整就应该执行commit操作"""

# 站在python代码的角度,应该实现的伪代码逻辑,
try:
    update user set balance=900 where name='wsb'; #买支付100元
    update user set balance=1010 where name='egon'; #中介拿走10元
    update user set balance=1090 where name='ysb'; #卖家拿到90元
except 异常:
    rollback;
else:
    commit;

# 那如何检测异常?

存储过程

什么是存储过程

就类似于python中的自定义函数

内部封装了 sql 语句,后续想要实现相应的操作,只需要调用存储过程即可

如何创建存储过程

语法结构

# 无参数版
delimiter $$  # 改mysql的结束符
create procedure 存储结构名字()
begin
    sql 语句;
end
delimiter ;  # 改回来

call 存储结构名字()  # 调用写好的存储过程


# 有参数版
delimiter $$  # 改mysql的结束符
create procedure 存储结构名字(
    in m int,  # in 只能传进来,不能返回
    in n int,  # 参数对应的意思---> 进还是出, 变量名, 数据类型
    out res int,  # out 只能返回,不能传
    inout xxx int,  # inout 可以传进来,也可以被返回
)
begin
    sql 语句;
end
delimiter ;  # 改回来

call 存储结构名字(m, n)  # 参数怎么传不知道。。

案例

存储过程在哪个库里定义就只能在哪个库里面使用

定义存储过程

delimiter $$

create procedure p1(
    in m int,  # in 只能传进来,不能被返回
    in n int,  # 参数对应的意思---> 进还是出, 变量名, 数据类型
    out res int  # out 只能被返回,不能传入
)

begin
    select tname from teacher where tid > m and tid < n;
    set res=0;  # 就类似于一个标志位,用来标识存储器是否执行成功
end $$

delimiter ;

show procedure status\G;  # 查看存储过程(竖式展示排版)

在mysql中调用存储过程

存变量(设置初始值)

set @res=10; # 设置全局变量 @res 等于10select @res; # 查看全局变量 @res 的值

调用

call p1(1,5,@res);

将变量 @res 传入,之后可以通过 select @res 来查看存储过程执行完成后的返回结果

在pymysql中调用存储过程

# 使用的是上一步创建的存储过程
import pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    password='000000',
    database='day38',
    charset='utf8',
    autocommit=True,
)

cursor = conn.cursor(pymysql.cursors.DictCursor)

# --------------------------------------------
# cursor.callproc() 调用存储过程
#   内部自动用变量名存储对应值(看下面案例注释)
# --------------------------------------------
cursor.callproc('p1', (1, 5, 10))  # 这里就不需要设置那个全局变量了(@res=10),内部自动用变量名存储了对应的值
print(cursor.fetchall())
# [{'tname': '李平老师'}, {'tname': '刘海燕老师'}, {'tname': '朱云海老师'}]

'''
callproc 内部自动用变量名存储了对应的值

@_p1_0=1
@_p1_1=5
@_p1_2=10

# 自动取名规律: @_存储过程名_标号
'''
cursor.execute('select @_p1_0=1')
print(cursor.fetchall())
# [{'@_p1_0=1': 1}]
cursor.execute('select @_p1_1=5')
print(cursor.fetchall())
# [{'@_p1_1=5': 1}]
cursor.execute('select @_p1_2=10')
print(cursor.fetchall())
# [{'@_p1_2=10': 0}]

案例-- 使用存储过程监测事务

监测一个事务是否成功,通常使用存储过程包起来

# 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用!!!

delimiter //
create PROCEDURE p5(
    OUT p_return_code tinyint
)
BEGIN
    DECLARE exit handler for sqlexception
    BEGIN
        -- ERROR
        set p_return_code = 1;
        rollback;
    END;


  DECLARE exit handler for sqlwarning
  BEGIN
      -- WARNING
      set p_return_code = 2;
      rollback;
  END;

  START TRANSACTION;
      update user set balance=900 where id =1;
      update user123 set balance=1010 where id = 2;
      update user set balance=1090 where id =3;
  COMMIT;

  -- SUCCESS
  set p_return_code = 0; #0代表执行成功


END //
delimiter ;

函数

注意与存储过程的区别,mysql内置的函数只能在sql语句中使用!

参考博客:函数

MySQL内置函数

常见函数及练习

一、数学函数
    ROUND(x,y)
        返回参数x的四舍五入的有y位小数的值
        
    RAND()
        返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。

二、聚合函数(常用于GROUP BY从句的SELECT查询中)
    AVG(col)返回指定列的平均值
    COUNT(col)返回指定列中非NULL值的个数
    MIN(col)返回指定列的最小值
    MAX(col)返回指定列的最大值
    SUM(col)返回指定列的所有值之和
    GROUP_CONCAT(col) 返回由属于一组的列值连接组合而成的结果    
    
三、字符串函数

    CHAR_LENGTH(str)
        返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
    CONCAT(str1,str2,...)
        字符串拼接
        如有任何一个参数为NULL ,则返回值为 NULL。
    CONCAT_WS(separator,str1,str2,...)
        字符串拼接(自定义连接符)
        CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。

    CONV(N,from_base,to_base)
        进制转换
        例如:
            SELECT CONV('a',16,2); 表示将 a 由16进制转换为2进制字符串表示

    FORMAT(X,D)
        将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若  D 为 0, 则返回结果不带有小数点,或不含小数部分。
        例如:
            SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
    INSERT(str,pos,len,newstr)
        在str的指定位置插入字符串
            pos:要替换位置其实位置
            len:替换的长度
            newstr:新字符串
        特别的:
            如果pos超过原字符串长度,则返回原字符串
            如果len超过原字符串长度,则由新字符串完全替换
    INSTR(str,substr)
        返回字符串 str 中子字符串的第一个出现位置。

    LEFT(str,len)
        返回字符串str 从开始的len位置的子序列字符。

    LOWER(str)
        变小写

    UPPER(str)
        变大写
   
    REVERSE(str)
        返回字符串 str ,顺序和字符顺序相反。
        
    SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
        不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。

        mysql> SELECT SUBSTRING('Quadratically',5);
            -> 'ratically'

        mysql> SELECT SUBSTRING('foobarbar' FROM 4);
            -> 'barbar'

        mysql> SELECT SUBSTRING('Quadratically',5,6);
            -> 'ratica'

        mysql> SELECT SUBSTRING('Sakila', -3);
            -> 'ila'

        mysql> SELECT SUBSTRING('Sakila', -5, 3);
            -> 'aki'

        mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
            -> 'ki'
            
四、日期和时间函数
    CURDATE()或CURRENT_DATE() 返回当前的日期
    CURTIME()或CURRENT_TIME() 返回当前的时间
    DAYOFWEEK(date)   返回date所代表的一星期中的第几天(1~7)
    DAYOFMONTH(date)  返回date是一个月的第几天(1~31)
    DAYOFYEAR(date)   返回date是一年的第几天(1~366)
    DAYNAME(date)   返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
    FROM_UNIXTIME(ts,fmt)  根据指定的fmt格式,格式化UNIX时间戳ts
    HOUR(time)   返回time的小时值(0~23)
    MINUTE(time)   返回time的分钟值(0~59)
    MONTH(date)   返回date的月份值(1~12)
    MONTHNAME(date)   返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
    NOW()    返回当前的日期和时间
    QUARTER(date)   返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
    WEEK(date)   返回日期date为一年中第几周(0~53)
    YEAR(date)   返回日期date的年份(1000~9999)
    
    重点:
    DATE_FORMAT(date,format) 根据format字符串格式化date值

       mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
        -> 'Sunday October 2009'
       mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
       mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',
        ->                 '%D %y %a %d %m %b %j');
        -> '4th 00 Thu 04 10 Oct 277'
       mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
        ->                 '%H %k %I %r %T %S %w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
       mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
        -> '1998 52'
       mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
        -> '00'
        
五、加密函数
    MD5()    
        计算字符串str的MD5校验和
    PASSWORD(str)   
        返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
        
六、控制流函数            
    CASE WHEN[test1] THEN [result1]...ELSE [default] END
        如果testN是真,则返回resultN,否则返回default
    CASE [test] WHEN[val1] THEN [result]...ELSE [default]END  
        如果test和valN相等,则返回resultN,否则返回default

    IF(test,t,f)   
        如果test是真,返回t;否则返回f

    IFNULL(arg1,arg2) 
        如果arg1不是空,返回arg1,否则返回arg2

    NULLIF(arg1,arg2) 
        如果arg1=arg2返回NULL;否则返回arg1        
        
七、控制流函数小练习
#7.1、准备表
/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50720
Source Host           : localhost:3306
Source Database       : student

Target Server Type    : MYSQL
Target Server Version : 50720
File Encoding         : 65001

Date: 2018-01-02 12:05:30
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `c_id` int(11) NOT NULL,
  `c_name` varchar(255) DEFAULT NULL,
  `t_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`c_id`),
  KEY `t_id` (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'python', '1');
INSERT INTO `course` VALUES ('2', 'java', '2');
INSERT INTO `course` VALUES ('3', 'linux', '3');
INSERT INTO `course` VALUES ('4', 'web', '2');

-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `s_id` int(10) DEFAULT NULL,
  `c_id` int(11) DEFAULT NULL,
  `num` double DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('1', '1', '1', '79');
INSERT INTO `score` VALUES ('2', '1', '2', '78');
INSERT INTO `score` VALUES ('3', '1', '3', '35');
INSERT INTO `score` VALUES ('4', '2', '2', '32');
INSERT INTO `score` VALUES ('5', '3', '1', '66');
INSERT INTO `score` VALUES ('6', '4', '2', '77');
INSERT INTO `score` VALUES ('7', '4', '1', '68');
INSERT INTO `score` VALUES ('8', '5', '1', '66');
INSERT INTO `score` VALUES ('9', '2', '1', '69');
INSERT INTO `score` VALUES ('10', '4', '4', '75');
INSERT INTO `score` VALUES ('11', '5', '4', '66.7');

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `s_id` varchar(20) NOT NULL,
  `s_name` varchar(255) DEFAULT NULL,
  `s_age` int(10) DEFAULT NULL,
  `s_sex` char(1) DEFAULT NULL,
  PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '鲁班', '12', '男');
INSERT INTO `student` VALUES ('2', '貂蝉', '20', '女');
INSERT INTO `student` VALUES ('3', '刘备', '35', '男');
INSERT INTO `student` VALUES ('4', '关羽', '34', '男');
INSERT INTO `student` VALUES ('5', '张飞', '33', '女');

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `t_id` int(10) NOT NULL,
  `t_name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', '大王');
INSERT INTO `teacher` VALUES ('2', 'alex');
INSERT INTO `teacher` VALUES ('3', 'egon');
INSERT INTO `teacher` VALUES ('4', 'peiqi');

#7.2、统计各科各分数段人数.显示格式:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]

select  score.c_id,
          course.c_name, 
      sum(CASE WHEN num BETWEEN 85 and 100 THEN 1 ELSE 0 END) as '[100-85]',
      sum(CASE WHEN num BETWEEN 70 and 85 THEN 1 ELSE 0 END) as '[85-70]',
      sum(CASE WHEN num BETWEEN 60 and 70 THEN 1 ELSE 0 END) as '[70-60]',
      sum(CASE WHEN num < 60 THEN 1 ELSE 0 END) as '[ <60]'
from score,course where score.c_id=course.c_id GROUP BY score.c_id;    

date_format() 函数(需掌握)

CREATE TABLE blog (
    id INT PRIMARY KEY auto_increment,
    NAME CHAR (32),
    sub_time datetime
);

INSERT INTO blog (NAME, sub_time)
VALUES
    ('第1篇','2015-03-01 11:31:21'),
    ('第2篇','2015-03-11 16:31:21'),
    ('第3篇','2016-07-01 10:21:31'),
    ('第4篇','2016-07-22 09:23:21'),
    ('第5篇','2016-07-23 10:11:11'),
    ('第6篇','2016-07-25 11:21:31'),
    ('第7篇','2017-03-01 15:33:21'),
    ('第8篇','2017-03-01 17:32:21'),
    ('第9篇','2017-03-01 18:31:21');

select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');

自定义函数

注意

  • 函数中不要写sql语句(否则会报错),函数仅仅只是一个功能,是一个在sql中被应用的功能

  • 若要想在begin...end...中写sql,请用存储过程

delimiter //
create function f1(
    i1 int,
    i2 int)
returns int
BEGIN
    declare num int;
    set num = i1 + i2;
    return(num);
END //
delimiter ;

# 在查询中使用函数
select f1(11,nid) ,name from tb2;

# 删除函数
drop function func_name;

流程控制

if 条件语句

# if条件语句
delimiter //  # 修改mysql 默认的语句结束符
CREATE PROCEDURE proc_if ()
BEGIN
    
    declare i int default 0;
    if i = 1 THEN
        SELECT 1;
    ELSEIF i = 2 THEN
        SELECT 2;
    ELSE
        SELECT 7;
    END IF;

END //
delimiter ;  # 将sql语句默认结束符改回 ;

while 循环

# while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN

    DECLARE num INT ;
    SET num = 0 ;
    WHILE num < 10 DO
        SELECT
            num ;
        SET num = num + 1 ;
    END WHILE ;

END //
delimiter ;

索引与慢查询优化 **

mysql 默认有查询优化机制,我们不需要再上面花多少精力,能优化的,mysql基本都直接给我们优化了(可适当增加几个索引)

详细内容参考egon 的博客

第八篇:索引原理与慢查询优化 ,写的很详细,案例也很充分,我这个写的不好

标签:06,name,mysql,视图,索引,MySQL,磁盘,id,select
来源: https://www.cnblogs.com/suwanbin/p/11406262.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有