加载中...

屌炸天实战 MySQL 系列教程(三)【秒杀五年经验 LowB工程师】你不知道的 视图、触发器、存储过程、函数、事务、索引、语句


第一篇:屌炸天实战 MySQL 系列教程(一) 生产标准线上环境安装配置案例及棘手问题解决

第二篇:屌炸天实战 MySQL 系列教程(二) 史上最屌、你不知道的数据库操作

第三篇:屌炸天实战 MySQL 系列教程(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句

 

前天有一个五年java开发经验工程师,问我存储过程怎么写?

我的天呐!你这个也太 low 了!

你给我点赞,我教你实战!

 

本章内容:

  • 视图、增/删/改/查
  • 触发器、增/删/改/查
  • 存储过程、增/删/改/查
  • 存储过程三种传参,pymysql 怎么用?
  • 函数、增/删/改/查/return值
  • 内置函数
  • 事务
  • 索引!

 

一、视图

视图是查询命令结果构成的一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结果集合,并可以当作表来查询使用。

1、创建视图

  1. --格式:CREATE VIEW 视图名称 AS SQL语句
  2. CREATE VIEW v1 AS
  3. SELET nid,
  4. name
  5. FROM
  6. A
  7. WHERE
  8. nid > 4

2、删除视图

  1. --格式:DROP VIEW 视图名称
  2. DROP VIEW v1

3、修改视图

  1. -- 格式:ALTER VIEW 视图名称 AS SQL语句
  2. ALTER VIEW v1 AS
  3. SELET A.nid,
  4. B. NAME
  5. FROM
  6. A
  7. LEFT JOIN B ON A.id = B.nid
  8. LEFT JOIN C ON A.id = C.nid
  9. WHERE
  10. A.id > 2
  11. AND C.nid < 5

4、使用视图

视图的使用和普通表一样,由于视图是虚拟表,所以无法对其真实表进行创建、更新和删除操作,仅做查询用。

  1. select * from v1

 

二、触发器

对某个表进行【增/删/改】操作的前后触发一些操作即为触发器,如果希望触发增删改的行为之前或之后做操作时,可以使用触发器,触发器用于自定义用户对表的行进行【增/删/改】前后的行为。

1、基本语法

  1. # 插入前
  2. CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4. ...
  5. END
  6. # 插入后
  7. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  8. BEGIN
  9. ...
  10. END
  11. # 删除前
  12. CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
  13. BEGIN
  14. ...
  15. END
  16. # 删除后
  17. CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
  18. BEGIN
  19. ...
  20. END
  21. # 更新前
  22. CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
  23. BEGIN
  24. ...
  25. END
  26. # 更新后
  27. CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
  28. BEGIN
  29. ...
  30. END

2、创建触发器

创建触发器基本语法是以下code:

但有一点要注意,触发器内关键字NEW表示即将插入的数据行,OLD表示即将删除的数据行。

  1. # 插入前触发器
  2. delimiter //
  3. CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
  4. BEGIN
  5. IF NEW. NAME == 'nick' THEN
  6. INSERT INTO tb2 (NAME)
  7. VALUES
  8. ('aa')
  9. END
  10. END//
  11. delimiter ;
  1. # 插入后触发器
  2. delimiter //
  3. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  4. BEGIN
  5. IF NEW. num = 666 THEN
  6. INSERT INTO tb2 (NAME)
  7. VALUES
  8. ('666'),
  9. ('666') ;
  10. ELSEIF NEW. num = 555 THEN
  11. INSERT INTO tb2 (NAME)
  12. VALUES
  13. ('555'),
  14. ('555') ;
  15. END IF;
  16. END//
  17. delimiter ;

3、删除触发器

  1. DROP TRIGGER tri_after_insert_tb1;

4、使用触发器

触发器是由于对表的增、删、改操作时被动执行的

  1. insert into tb1(num) values(666)

 

三、存储过程

存储过程是一个SQL语句集合,类似函数,需要主动调用。

1、创建存储过程

  1. # 无参数存储过程
  2.  
  3. # 创建存储过程
  4. delimiter //
  5. create procedure p1()
  6. BEGIN
  7. select * from t1;
  8. END//
  9. delimiter ;
  10. # 执行存储过程
  11. call p1()

都说了类似函数,那必须得可以接收参数,且参数有三类:

  • in          仅用于传入参数用
  • out        仅用于返回值用
  • inout     既可以传入又可以当作返回值
  1. # 有参数存储过程
  2.  
  3. # 创建存储过程
  4. delimiter \\ # 结尾分号改为\\
  5. create procedure p1(
  6. in i1 int,
  7. in i2 int,
  8. inout i3 int,
  9. out r1 int
  10. )
  11. BEGIN
  12. DECLARE temp1 int; # 创建申明局部变量
  13. DECLARE temp2 int default 0;
  14. set temp1 = 1;
  15. set r1 = i1 + i2 + temp1 + temp2;
  16. set i3 = i3 + 100;
  17. end\\
  18. delimiter ;
  19. # 执行存储过程
  20. DECLARE @t1 INT default 3;
  21. DECLARE @t2 INT;
  22. CALL p1 (1, 2 ,@t1, @t2);
  23. SELECT @t1,@t2;

2、删除存储过程

  1. drop procedure proc_name;

3、执行存储过程

执行为函数名加括号;

DECLARE代表创建一个局部变量

  1. # 无参数
  2. call proc_name()
  3. # 有参数,全in
  4. call proc_name(1,2)
  5. # 有参数,有in,out,inout
  6. DECLARE @t1 INT;
  7. DECLARE @t2 INT default 3;
  8. call proc_name(1,2,@t1,@t2)
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import pymysql
  4. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
  5. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  6. # 执行存储过程
  7. cursor.callproc('p1', args=(1, 22, 3, 4))
  8. # 获取执行完存储的参数
  9. cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
  10. result = cursor.fetchall()
  11. conn.commit()
  12. cursor.close()
  13. conn.close()
  14. print(result)
pymysql执行存储过程

 

四、函数

该讲讲真正的函数了,与存储过程不同的是有return值

1、自定义函数

  1. delimiter \\
  2. create function f1(
  3. i1 int,
  4. i2 int)
  5. returns int
  6. BEGIN
  7. declare num int;
  8. set num = i1 + i2;
  9. return(num);
  10. END \\
  11. delimiter ;

2、删除函数

  1. drop function func_name;

3、执行函数

  1. # 获取返回值
  2. declare @i VARCHAR(32);
  3. select UPPER('nick') into @i;
  4. SELECT @i;
  5. # 在查询中使用
  6. select f1(11,nid) ,name from tb2;

4、内置函数

当然MySQL也不例外,有着非常好用的内置函数

  1. CHAR_LENGTH(str)
  2. 返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
  3. 对于一个包含五个二字节字符集, LENGTH()返回值为 10, CHAR_LENGTH()的返回值为5
  4. CONCAT(str1,str2,...)
  5. 字符串拼接
  6. 如有任何一个参数为NULL ,则返回值为 NULL
  7. CONCAT_WS(separator,str1,str2,...)
  8. 字符串拼接(自定义连接符)
  9. CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。
  10. CONV(N,from_base,to_base)
  11. 进制转换
  12. 例如:
  13. SELECT CONV('a',16,2); 表示将 a 16进制转换为2进制字符串表示
  14. FORMAT(X,D)
  15. 将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若 D 0, 则返回结果不带有小数点,或不含小数部分。
  16. 例如:
  17. SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
  18. INSERT(str,pos,len,newstr)
  19. str的指定位置插入字符串
  20. pos:要替换位置其实位置
  21. len:替换的长度
  22. newstr:新字符串
  23. 特别的:
  24. 如果pos超过原字符串长度,则返回原字符串
  25. 如果len超过原字符串长度,则由新字符串完全替换
  26. INSTR(str,substr)
  27. 返回字符串 str 中子字符串的第一个出现位置。
  28. LEFT(str,len)
  29. 返回字符串str 从开始的len位置的子序列字符。
  30. LOWER(str)
  31. 变小写
  32. UPPER(str)
  33. 变大写
  34. LTRIM(str)
  35. 返回字符串 str ,其引导空格字符被删除。
  36. RTRIM(str)
  37. 返回字符串 str ,结尾空格字符被删去。
  38. SUBSTRING(str,pos,len)
  39. 获取字符串子序列
  40. LOCATE(substr,str,pos)
  41. 获取子序列索引位置
  42. REPEAT(str,count)
  43. 返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count
  44. count <= 0,则返回一个空字符串。
  45. str count NULL,则返回 NULL
  46. REPLACE(str,from_str,to_str)
  47. 返回字符串str 以及所有被字符串to_str替代的字符串from_str
  48. REVERSE(str)
  49. 返回字符串 str ,顺序和字符顺序相反。
  50. RIGHT(str,len)
  51. 从字符串str 开始,返回从后边开始len个字符组成的子序列
  52. SPACE(N)
  53. 返回一个由N空格组成的字符串。
  54. SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
  55. 不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。
  56. mysql> SELECT SUBSTRING('Quadratically',5);
  57. -> 'ratically'
  58. mysql> SELECT SUBSTRING('foobarbar' FROM 4);
  59. -> 'barbar'
  60. mysql> SELECT SUBSTRING('Quadratically',5,6);
  61. -> 'ratica'
  62. mysql> SELECT SUBSTRING('Sakila', -3);
  63. -> 'ila'
  64. mysql> SELECT SUBSTRING('Sakila', -5, 3);
  65. -> 'aki'
  66. mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
  67. -> 'ki'
  68. TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str) TRIM(remstr FROM] str)
  69. 返回字符串 str 其中所有remstr 前缀和/或后缀都已被删除。若分类符BOTHLEADINTRAILING中没有一个是给定的,则假设为BOTH remstr 为可选项,在未指定情况下,可删除空格。
  70. mysql> SELECT TRIM(' bar ');
  71. -> 'bar'
  72. mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
  73. -> 'barxxx'
  74. mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
  75. -> 'bar'
  76. mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
  77. -> 'barx'

更多函数:猛击这里 OR 猛击这里

 

五、事务

事务用于将某些操作的多个SQL语句作为原子性操作,只有出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

delimiter 为改变结束符号,默认";"

  1. # 支持事务的存储过程
  2. delimiter \\
  3. create PROCEDURE p1(
  4. OUT p_return_code tinyint
  5. )
  6. BEGIN
  7. DECLARE exit handler for sqlexception
  8. BEGIN
  9. -- ERROR
  10. set p_return_code = 1;
  11. rollback;
  12. END;
  13. DECLARE exit handler for sqlwarning
  14. BEGIN
  15. -- WARNING
  16. set p_return_code = 2;
  17. rollback;
  18. END;
  19. START TRANSACTION;
  20. DELETE from tb1;
  21. insert into tb2(name)values('seven');
  22. COMMIT;
  23. -- SUCCESS
  24. set p_return_code = 0;
  25. END\\
  26. delimiter ;
  1. # 执行存储过程
  2. DECLARE @i TINYINT;
  3. call p1(@i);
  4. select @i;

 

六、索引

1、索引概述

索引是表的索引目录,在查找内容之前先查目录中查找索引位置,从而快速定位查询数据;

可以理解成新华字典中的索引;

索引会保存在额外的文件中。

2、索引种类

一般的索引种类及功能:

  • 普通索引:仅加速查询
  • 唯一索引:加速查询 + 列值唯一(可以有null)
  • 主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
  • 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
  • 全文索引:对文本的内容进行分词,进行搜索 

索引合并:使用多个单列索引组合查询搜索
覆盖索引:select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

a、普通索引

  1. # 创建表 + 索引
  2. create table in1(
  3. nid int not null auto_increment primary key,
  4. name varchar(32) not null,
  5. email varchar(64) not null,
  6. extra text,
  7. index ix_name (name)
  8. )
  1. # 创建索引
  2. create index index_name on table_name(column_name)
  1. # 删除索引
  2. drop index_name on table_name;
  1. # 查看索引
  2. show index from table_name;
  1. #注意:对于创建索引时如果是BLOB 和 TEXT 类型,必须指定length。
  2. create index ix_extra on in1(extra(32));

b、唯一索引

  1. # 创建表 + 唯一索引
  2. create table in1(
  3. nid int not null auto_increment primary key,
  4. name varchar(32) not null,
  5. email varchar(64) not null,
  6. extra text,
  7. unique ix_name (name)
  8. )
  1. # 创建唯一索引
  2. create unique index 索引名 on 表名(列名)
  1. # 删除唯一索引
  2. drop unique index 索引名 on 表名

c、主键索引

  1. # 创建表 + 创建主键
  2. create table in1(
  3. nid int not null auto_increment primary key,
  4. name varchar(32) not null,
  5. email varchar(64) not null,
  6. extra text,
  7. index ix_name (name)
  8. )
  9. OR
  10. create table in1(
  11. nid int not null auto_increment,
  12. name varchar(32) not null,
  13. email varchar(64) not null,
  14. extra text,
  15. primary key(ni1),
  16. index ix_name (name)
  17. )
  1. # 创建主键
  2. alter table 表名 add primary key(列名);
  1. # 删除主键
  2. alter table 表名 drop primary key;
  3. alter table 表名 modify 列名 int, drop primary key;

d、组合索引

组合索引是多个列组合成一个索引来查询

应用场景:频繁的同时使用多列来进行查询,如:where name = 'nick' and age = 18。

  1. # 创建表
  2. create table mess(
  3. nid int not null auto_increment primary key,
  4. name varchar(32) not null,
  5. age int not null
  6. )
  7. # 创建组合索引
  8. create index ix_name_age on mess(name,age);

如上创建组合索引之后,查询一定要注意:

  • name and email  -- >使用索引,name一定要放前面
  • name                 -- >使用索引
  • email                 -- >不使用索引

注意:同时搜索多个条件时,组合索引的性能效率好过于多个单一索引合并。

 3、相关命令

  1. # 查看索引
  2. show index from 表名
  3. # 查看执行时间
  4. set profiling = 1; # 开启profiling
  5. SQL... # 执行SQL语句
  6. show profiles; # 查看结果

4、如何正确使用索引

  1. # like '%xx',避免%_写在开头
  2. select * from tb1 where name like '%n';
  3. # 使用函数
  4. select * from tb1 where reverse(name) = 'nick';
  5. # or
  6. select * from tb1 where nid = 1 or email = '630571017@qq.com';
  7. 注:当or条件中有未建立索引的列才失效,否则会走索引
  8. # 类型不一致
  9. 如果列是字符串类型,传入条件是必须用引号引起来。
  10. select * from tb1 where name = 999;
  11. # !=,不等于
  12. select * from tb1 where name != 'nick'
  13. 注:如果是主键,则还是会走索引
  14. select * from tb1 where nid != 123
  15.  
  16. # >,大于
  17. select * from tb1 where name > 'nick'
  18. 注:如果是主键或索引是整数类型,则还是会走索引
  19. select * from tb1 where nid > 123
  20. select * from tb1 where num > 123
  21.  
  22. # order by
  23. select email from tb1 order by name desc;
  24. 当根据索引排序时候,选择的映射如果不是索引,则不走索引
  25. 注:如果对主键排序,则还是走索引:
  26. select * from tb1 order by nid desc;
  27. # 组合索引最左前缀
  28. 如果组合索引为:(name,email),查询使用:
  29. name and email -- 使用索引
  30. name -- 使用索引
  31. email -- 不使用索引

5、注意事项

  1. # 避免使用select *
  2. # count(1)或count(列) 代替 count(*)
  3. # 创建表时尽量时 char 代替 varchar
  4. # 表的字段顺序固定长度的字段优先
  5. # 组合索引代替多个单列索引(经常使用多个条件查询时)
  6. # 尽量使用短索引
  7. # 使用连接(JOIN)来代替子查询(Sub-Queries)
  8. # 连表时注意条件类型需一致
  9. # 索引散列值(重复少)不适合建索引,例:性别不适合

6、执行计划

explain + 查询SQL  用于显示SQL执行信息参数,根据参考信息可以进行SQL优化

  1. mysql> explain select * from suoning;
  2. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  3. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  4. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  5. | 1 | SIMPLE | suoning | ALL | NULL | NULL | NULL | NULL | 4 | |
  6. +----+-------------+---------+------+---------------+------+---------+------+------+-------+
  7. 1 row in set (1.67 sec)
  1. id
  2. 查询顺序标识
  3. 如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
  4. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  5. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  6. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  7. | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 9 | NULL |
  8. | 2 | DERIVED | tb1 | range | PRIMARY | PRIMARY | 8 | NULL | 9 | Using where |
  9. +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
  10. 特别的:如果使用union连接气值可能为null
  11. select_type
  12. 查询类型
  13. SIMPLE 简单查询
  14. PRIMARY 最外层查询
  15. SUBQUERY 映射为子查询
  16. DERIVED 子查询
  17. UNION 联合
  18. UNION RESULT 使用联合的结果
  19. ...
  20. table
  21. 正在访问的表名
  22. type
  23. 查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
  24. ALL 全表扫描,对于数据表从头到尾找一遍
  25. select * from tb1;
  26. 特别的:如果有limit限制,则找到之后就不在继续向下扫描
  27. select * from tb1 where email = 'seven@live.com'
  28. select * from tb1 where email = 'seven@live.com' limit 1;
  29. 虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
  30. INDEX 全索引扫描,对索引从头到尾找一遍
  31. select nid from tb1;
  32. RANGE 对索引列进行范围查找
  33. select * from tb1 where name < 'alex';
  34. PS:
  35. between and
  36. in
  37. > >= < <= 操作
  38. 注意:!= > 符号
  39. INDEX_MERGE 合并索引,使用多个单列索引搜索
  40. select * from tb1 where name = 'alex' or nid in (11,22,33);
  41. REF 根据索引查找一个或多个值
  42. select * from tb1 where name = 'seven';
  43. EQ_REF 连接时使用primary key unique类型
  44. select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
  45. CONST 常量
  46. 表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
  47. select nid from tb1 where nid = 2 ;
  48. SYSTEM 系统
  49. 表仅有一行(=系统表)。这是const联接类型的一个特例。
  50. select * from (select nid from tb1 where nid = 1) as A;
  51. possible_keys
  52. 可能使用的索引
  53. key
  54. 真实使用的
  55. key_len
  56. MySQL中使用索引字节长度
  57. rows
  58. mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
  59. extra
  60. 该列包含MySQL解决查询的详细信息
  61. Using index
  62. 此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
  63. Using where
  64. 这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
  65. Using temporary
  66. 这意味着mysql在对查询结果排序时会使用一个临时表。
  67. Using filesort
  68. 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
  69. Range checked for each record(index map: N)”
  70. 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。
  71. 详细

 7、慢日志查询

日志可以记录哪些查询语句慢,没有走索引,用户发现问题,从而解决优化

a、配置MySQL自动记录慢日志

 修改配置文件 my.ini,没有则添加

  1. slow_query_log = OFF # 是否开启慢日志记录
  2. long_query_time = 2 # 时间限制,超过此时间,则记录
  3. slow_query_log_file = /usr/slow.log # 日志文件
  4. log_queries_not_using_indexes = OFF # 为使用索引的搜索是否记录
  5.  
  6. # 查看当前配置信息:
  7.   show variables like '%query%'
  8. # 修改当前配置:
  9.  set global 变量名 =

b、查看MySQL慢日志

mysqldumpslow -s at -a  /usr/local/var/mysql/MacBook-Pro-3-slow.log

  1. --verbose 版本
  2. --debug 调试
  3. --help 帮助
  4. -v 版本
  5. -d 调试模式
  6. -s ORDER 排序方式
  7. what to sort by (al, at, ar, c, l, r, t), 'at' is default
  8. al: average lock time
  9. ar: average rows sent
  10. at: average query time
  11. c: count
  12. l: lock time
  13. r: rows sent
  14. t: query time
  15. -r 反转顺序,默认文件倒序拍。reverse the sort order (largest last instead of first)
  16. -t NUM 显示前Njust show the top n queries
  17. -a 不要将SQL中数字转换成N,字符串转换成Sdon't abstract all numbers to N and strings to 'S'
  18. -n NUM abstract numbers with at least n digits within names
  19. -g PATTERN 正则匹配;grep: only consider stmts that include this string
  20. -h HOSTNAME mysql机器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),
  21. default is '*', i.e. match all
  22. -i NAME name of server instance (if using mysql.server startup script)
  23. -l 总时间中不减去锁定时间;don't subtract lock time from total time

 

七、其它

自然所有的东西都离不开基本的语法语句啦,循环语句与判断语句

1、条件语句

if then\ elseif then\ else\ end if

  1. # if条件语句
  2. delimiter \\
  3. CREATE PROCEDURE proc_if ()
  4. BEGIN
  5. declare i int default 0;
  6. if i = 1 THEN
  7. SELECT 1;
  8. ELSEIF i = 2 THEN
  9. SELECT 2;
  10. ELSE
  11. SELECT 7;
  12. END IF;
  13. END\\
  14. delimiter ;

2、循环语句

分为三种循环语句:while循环、repeat循环、loop循环

  1. # while循环
  2. delimiter \\
  3. CREATE PROCEDURE proc_while ()
  4. BEGIN
  5. DECLARE num INT ;
  6. SET num = 0 ;
  7. WHILE num < 10 DO
  8. SELECT
  9. num ;
  10. SET num = num + 1 ;
  11. END WHILE ;
  12. END\\
  13. delimiter ;
  1. # repeat循环,相当于 do while
  2. delimiter \\
  3. CREATE PROCEDURE proc_repeat ()
  4. BEGIN
  5. DECLARE i INT ;
  6. SET i = 0 ;
  7. repeat
  8. select i;
  9. set i = i + 1;
  10. until i >= 5
  11. end repeat;
  12. END\\
  13. delimiter ;
  1. # loop
  2. delimiter \\
  3. CREATE PROCEDURE proc_loop ()
  4. BEGIN
  5. declare i int default 0;
  6. loop_label: loop
  7. select i;
  8. set i=i+1;
  9. if i>=5 then
  10. leave loop_label;
  11. end if;
  12. end loop;
  13. END\\
  14. delimiter ;

3、动态执行SQL语句

  1. # 动态执行SQL
  2. delimiter \\
  3. DROP PROCEDURE IF EXISTS proc_sql \\
  4. CREATE PROCEDURE proc_sql ()
  5. BEGIN
  6. declare p1 int;
  7. set p1 = 11;
  8. set @p1 = p1;
  9. PREPARE prod FROM 'select * from tb2 where nid > ?';
  10. EXECUTE prod USING @p1;
  11. DEALLOCATE prepare prod;
  12. END\\
  13. delimiter ;
  1. # 方式二
  2. delimiter \\
  3. DROP PROCEDURE IF EXISTS proc_sql \\  # 如果不存在则添加,否则不做操作
  4. CREATE PROCEDURE proc_sql (
  5. in strSQL char(128),
  6. in nidd int
  7. )
  8. BEGIN
  9. set @sqll = strSQL;
  10. set @p1 = nidd;
  11. PREPARE prod FROM @sqll;
  12. EXECUTE prod USING @p1;
  13. DEALLOCATE prepare prod;
  14. END\\
  15. delimiter ;
  16. call proc_sql('select * from suoning2 where id > ?','2');

 


还没有评论.