一、视图

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

  1. SELECT
  2. *
  3. FROM
  4. (
  5. SELECT
  6. nid,
  7. NAME
  8. FROM
  9. tb1
  10. WHERE
  11. nid > 2
  12. ) AS A
  13. WHERE
  14. A. NAME > 'alex';

临时表搜索

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

创建视图

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

删除视图

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

修改视图

  1. # 使用视图时,将其当作表进行操作即可,由于视图是虚拟表,所以无法使用其对真实表进行创建、更新和删除操作,仅能做查询用
  2. 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. # 插入后
  8. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  9. BEGIN
  10. ...
  11. END
  12.  
  13. # 删除前
  14. CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
  15. BEGIN
  16. ...
  17. END
  18.  
  19. # 删除后
  20. CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
  21. BEGIN
  22. ...
  23. END
  24.  
  25. # 更新前
  26. CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
  27. BEGIN
  28. ...
  29. END
  30.  
  31. # 更新后
  32. CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
  33. BEGIN
  34. ...
  35. END

创建基本语法

  1. delimiter //
  2. CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4.  
  5. IF NEW. NAME == 'alex' THEN
  6. INSERT INTO tb2 (NAME)
  7. VALUES
  8. ('aa')
  9. END
  10. END//
  11. delimiter ;

插入前触发器

  1. delimiter //
  2. CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
  3. BEGIN
  4. IF NEW. num = 666 THEN
  5. INSERT INTO tb2 (NAME)
  6. VALUES
  7. (''),
  8. ('') ;
  9. ELSEIF NEW. num = 555 THEN
  10. INSERT INTO tb2 (NAME)
  11. VALUES
  12. (''),
  13. ('') ;
  14. END IF;
  15. END//
  16. delimiter ;

插入后触发器

 2.删除触发器

  1. DROP TRIGGER tri_after_insert_tb1;

3、使用触发器

  触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的。

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

三、存储过程

  存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行。

1、创建存储过程

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

无参数存储过程

对于存储过程,可以接收参数,其参数有三类:

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

有参数的存储过程

  1. delimiter //
  2. create procedure p1()
  3. begin
  4. select * from v1;
  5. end //
  6. delimiter ;

1. 结果集

  1. delimiter //
  2. create procedure p2(
  3. in n1 int,
  4. inout n3 int,
  5. out n2 int,
  6. )
  7. begin
  8. declare temp1 int ;
  9. declare temp2 int default 0;
  10.  
  11. select * from v1;
  12. set n2 = n1 + 100;
  13. set n3 = n3 + n1 + 100;
  14. end //
  15. delimiter ;

2. 结果集+out值

  1. delimiter \\
  2. create PROCEDURE p1(
  3. OUT p_return_code tinyint
  4. )
  5. BEGIN
  6. DECLARE exit handler for sqlexception
  7. BEGIN
  8. -- ERROR
  9. set p_return_code = 1;
  10. rollback;
  11. END;
  12.  
  13. DECLARE exit handler for sqlwarning
  14. BEGIN
  15. -- WARNING
  16. set p_return_code = 2;
  17. rollback;
  18. END;
  19.  
  20. START TRANSACTION;
  21. DELETE from tb1;
  22. insert into tb2(name)values('seven');
  23. COMMIT;
  24.  
  25. -- SUCCESS
  26. set p_return_code = 0;
  27.  
  28. END\\
  29. delimiter ;

3. 事务

  1. delimiter //
  2. create procedure p3()
  3. begin
  4. declare ssid int; -- 自定义变量1
  5. declare ssname varchar(50); -- 自定义变量2
  6. DECLARE done INT DEFAULT FALSE;
  7.  
  8. DECLARE my_cursor CURSOR FOR select sid,sname from student;
  9. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  10.  
  11. open my_cursor;
  12. xxoo: LOOP
  13. fetch my_cursor into ssid,ssname;
  14. if done then
  15. leave xxoo;
  16. END IF;
  17. insert into teacher(tname) values(ssname);
  18. end loop xxoo;
  19. close my_cursor;
  20. end //
  21. delimter ;

4. 游标

  1. delimiter \\
  2. CREATE PROCEDURE p4 (
  3. in nid int
  4. )
  5. BEGIN
  6. PREPARE prod FROM 'select * from student where sid > ?';
  7. EXECUTE prod USING @nid;
  8. DEALLOCATE prepare prod;
  9. END\\
  10. delimiter ;

5. 动态执行SQL

2、删除存储过程

  1. drop procedure proc_name;

3、执行存储过程

  1. -- 无参数
  2. call proc_name()
  3.  
  4. -- 有参数,全in
  5. call proc_name(1,2)
  6.  
  7. -- 有参数,有inoutinout
  8. set @t1=0;
  9. set @t2=3;
  10. call proc_name(1,2,@t1,@t2)

执行存储过程

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

pymysql执行存储过程

四、函数

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

部分内置函数

  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 ;

自定义函数

  1. drop function func_name;

删除函数

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

执行函数

五、事务

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

  1. delimiter \\
  2. create PROCEDURE p1(
  3. OUT p_return_code tinyint
  4. )
  5. BEGIN
  6. DECLARE exit handler for sqlexception
  7. BEGIN
  8. -- ERROR
  9. set p_return_code = 1;
  10. rollback;
  11. END;
  12.  
  13. DECLARE exit handler for sqlwarning
  14. BEGIN
  15. -- WARNING
  16. set p_return_code = 2;
  17. rollback;
  18. END;
  19.  
  20. START TRANSACTION;
  21. DELETE from tb1;
  22. insert into tb2(name)values('seven');
  23. COMMIT;
  24.  
  25. -- SUCCESS
  26. set p_return_code = 0;
  27.  
  28. END\\
  29. delimiter ;
  30.  
  31. set @i =0;
  32. call p1(@i);
  33. select @i;

支持事务的存储过程

六、索引

  索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。

MySQL中常见索引有:

  • 普通索引
  • 唯一索引
  • 主键索引
  • 组合索引

1、普通索引

普通索引仅有一个功能:加速查询

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. index ix_name (name)
  7. )

创建表 + 索引

  1. create index index_name on table_name(column_name)

创建索引

  1. drop index_name on table_name;

删除索引

  1. show index from table_name;

查看索引

注意:对于创建索引时如果是BLOB 和 TEXT 类型,必须指定length。

  1. create index ix_extra on in1(extra(32));

2.唯一索引

唯一索引有两个功能:加速查询 和 唯一约束(可含null)

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. unique ix_name (name)
  7. )

创建表 + 唯一索引

  1. create unique index 索引名 on 表名(列名)

创建唯一索引

  1. drop unique index 索引名 on 表名

删除唯一索引

3、主键索引

主键有两个功能:加速查询 和 唯一约束(不可含null)

  1. create table in1(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text,
  6. index ix_name (name)
  7. )
  8.  
  9. OR
  10.  
  11. create table in1(
  12. nid int not null auto_increment,
  13. name varchar(32) not null,
  14. email varchar(64) not null,
  15. extra text,
  16. primary key(ni1),
  17. index ix_name (name)
  18. )

创建表 + 创建主键

  1. alter table 表名 add primary key(列名);

创建主键

  1. alter table 表名 drop primary key;
  2. alter table 表名 modify 列名 int, drop primary key;

删除主键

4、组合索引

组合索引是将n个列组合成一个索引

其应用场景为:频繁的同时使用n列来进行查询,如:where n1 = 'alisa' and n2 = 666。

  1. create table in3(
  2. nid int not null auto_increment primary key,
  3. name varchar(32) not null,
  4. email varchar(64) not null,
  5. extra text
  6. )

创建表

  1. create index ix_name_email on in3(name,email);

创建组合索引

如上创建组合索引之后,查询:

  • name and email  -- 使用索引
  • name                 -- 使用索引
  • email                 -- 不使用索引

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

七、索引补充

1、索引
  索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。

2、索引种类

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

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

3、相关命令

  1. - 查看表结构
  2. desc 表名
  3.  
  4. - 查看生成表的SQL
  5. show create table 表名
  6.  
  7. - 查看索引
  8. show index from 表名
  9.  
  10. - 查看执行时间
  11. set profiling = 1;
  12. SQL...
  13. show profiles;

4、使用索引和不使用索引

  1. 由于索引是专门用于加速搜索而生,所以加上索引之后,查询效率会快到飞起来。
  2.  
  3. # 有索引
  4. mysql> select * from tb1 where name = 'wupeiqi-888';
  5. +-----+-------------+---------------------+----------------------------------+---------------------+
  6. | nid | name | email | radom | ctime |
  7. +-----+-------------+---------------------+----------------------------------+---------------------+
  8. | 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
  9. +-----+-------------+---------------------+----------------------------------+---------------------+
  10. 1 row in set (0.00 sec)
  11.  
  12. # 无索引
  13. mysql> select * from tb1 where email = 'wupeiqi888@live.com';
  14. +-----+-------------+---------------------+----------------------------------+---------------------+
  15. | nid | name | email | radom | ctime |
  16. +-----+-------------+---------------------+----------------------------------+---------------------+
  17. | 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
  18. +-----+-------------+---------------------+----------------------------------+---------------------+
  19. 1 row in set (1.23 sec)

5、正确使用索引

数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。
即使建立索引,索引也不会生效:

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

6、其他注意事项

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

7、limit分页

无论是否有索引,limit分页是一个值得关注的问题

  1. 每页显示10条:
  2. 当前 118 120 125
  3.  
  4. 倒序:

  5. 970 7 6 6 5 54 43 32
  6. 19 98
  7. 下一页:
  8.  
  9. select
  10. *
  11. from
  12. tb1
  13. where
  14. nid < (select nid from (select nid from tb1 where nid < 当前页最小值 order by nid desc limit 每页数据 *【页码-当前页】) A order by A.nid asc limit 1)
  15. order by
  16. nid desc
  17. limit 10;
  18.  
  19. select
  20. *
  21. from
  22. tb1
  23. where
  24. nid < (select nid from (select nid from tb1 where nid < 970 order by nid desc limit 40) A order by A.nid asc limit 1)
  25. order by
  26. nid desc
  27. limit 10;
  28.  
  29. 上一页:
  30.  
  31. select
  32. *
  33. from
  34. tb1
  35. where
  36. nid < (select nid from (select nid from tb1 where nid > 当前页最大值 order by nid asc limit 每页数据 *【当前页-页码】) A order by A.nid asc limit 1)
  37. order by
  38. nid desc
  39. limit 10;
  40.  
  41. select
  42. *
  43. from
  44. tb1
  45. where
  46. nid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by A.nid desc limit 1)
  47. order by
  48. nid desc
  49. limit 10;

8、执行计划

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

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

详细

9、慢日志查询

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

  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.    show variables like '%query%'
  7. 修改当前配置:
  8.     set global 变量名 =

b、查看MySQL慢日志

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

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

八、其它

1、条件语句

  1. delimiter \\
  2. CREATE PROCEDURE proc_if ()
  3. BEGIN
  4.  
  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.  
  14. END\\
  15. delimiter ;

if条件语句

2、循环语句

  1. delimiter \\
  2. CREATE PROCEDURE proc_while ()
  3. BEGIN
  4.  
  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.  
  13. END\\
  14. delimiter ;

while循环

  1. delimiter \\
  2. CREATE PROCEDURE proc_repeat ()
  3. BEGIN
  4.  
  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.  
  13. END\\
  14. delimiter ;

repeat循环

  1. BEGIN
  2.  
  3. declare i int default 0;
  4. loop_label: loop
  5.  
  6. set i=i+1;
  7. if i<8 then
  8. iterate loop_label;
  9. end if;
  10. if i>=10 then
  11. leave loop_label;
  12. end if;
  13. select i;
  14. end loop loop_label;
  15.  
  16. END

loop

3、动态执行SQL语句

  1. delimiter \\
  2. DROP PROCEDURE IF EXISTS proc_sql \\
  3. CREATE PROCEDURE proc_sql ()
  4. BEGIN
  5. declare p1 int;
  6. set p1 = 11;
  7. set @p1 = p1;
  8.  
  9. PREPARE prod FROM 'select * from tb2 where nid > ?';
  10. EXECUTE prod USING @p1;
  11. DEALLOCATE prepare prod;
  12.  
  13. END\\
  14. delimiter ;

动态执行SQL

036--MySQL扩展的更多相关文章

  1. PHP基础Mysql扩展库

    mysql扩展库操作步骤如下: 1.连接数据库 2.选择数据库 3.设置操作编码 4.发送指令sql,并返回结果集     ddl:数据定义语句     dml:数据操作语句     dql:数据查询 ...

  2. mysql扩展库-1

    启用mysql扩展库 在php.ini文件中去配置mysql扩展库 extension=php_mysql.dll 可以通过 phpinfo() 查看当前php支持什么扩展库. 在sql扩展库中创建一 ...

  3. 您的 PHP 似乎没有安装运行 WordPress 所必需的 MySQL 扩展”处理方法

    转自:http://www.xuebuyuan.com/1549022.html 这已经是一个老掉牙的问题了,部分人使用自己的服务器安装WordPress程序之后,会出现“您的 PHP 似乎没有安装运 ...

  4. Centos中安装PHP的PDO MySQL扩展的教程

    PHP Data Objects(PDO)扩展为 PHP 访问数据库定义了一个轻量级的一致接口.实现 PDO 接口的每个数据库驱动可以公开具体数据库的特性作为标准扩展功能.注意利用 PDO 扩展自身并 ...

  5. PHP的MySQL扩展:MySQL数据库概述

    来源:http://www.ido321.com/1023.html 一.SQL:结构化查询语言 SQL(Structured Query Language)是高级的非过程化变成语言,专门用于查询和修 ...

  6. php笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库

    1.使用php的MySQL扩展库操作MySQL数据库: php有3种方式操作MySQL数据库 (1)mysql扩展库 (2)mysqli扩展库 (3)pdo     mysql扩展库与mysql数据库 ...

  7. mysql扩展库操作mysql数据库

    环境搭建 启用mysql扩展库,在php.ini文件中去配置mysql扩展库 extension=php_mysql.dll 查询数据库 1.建库建表 //建库testcreate database ...

  8. 【小结】有关mysql扩展库和mysqli扩展库的crud操作封装

    现阶段php如果要操作mysql数据库 php给我们提供了3套库 1.mysql扩展库   面向过程操作 2.mysqli扩展库  面向对象操作和面向过程操作并存  安全性和效率高于mysql扩展库 ...

  9. php使用mysql扩展库链接mysql数据库(查询)

    php链接数据库可以使用mysql扩展库,mysqli,pdo这几种方式,相比java而言要麻烦一点,因为它不像java那么统一.从代码的难易程度来说php的确要简单许多.步骤大体如下 1.打开数据库 ...

  10. 在python3中安装mysql扩展,No module named 'ConfigParser'

    在python2.7中,我们安装的是 MySqldb或这 MySQL-python,能够正却安装,但在python3中,由于 其使用的扩展  ConfigParser 已经改名为 configpars ...

随机推荐

  1. BUPT 2012复试机考 4T

    题目描述 我们都学习过计算机网络,知道网络层IP协议数据包的头部格式如下: 其中IHL表示IP头的长度,单位是4字节:总长表示整个数据包的长度,单位是1字节.传输层的TCP协议数据段的头部格式如下:  ...

  2. Ubuntu Desktop 常用软件

    IDE: eclipse ***: firefox,登陆账号可以同步书签,我用了全球账号. firefox插件:FireGestures(手势), NoSquint(全局缩放),Url to QRco ...

  3. outlook 2010 自动密送Email

    以下功能请勿非法使用: 密抄到多人这个需要用到宏 方法一: 1.在Outlook里面键入ALT+F11打开VBA编辑器 2.展开“Project (VbaProject.OTM)/Microsoft ...

  4. mysqldbcopy 数据库复制工具

    命令参考 mysqldbcopy --source=root:'xxxxxxx'@database s --destination=root:'^%xxxxxz'@databases orange:o ...

  5. RESTful Web Service

  6. 【转载】lvs为何不能完全替代DNS轮询

    上一篇文章"一分钟了解负载均衡的一切"引起了不少同学的关注,评论中大家争论的比较多的一个技术点是接入层负载均衡技术,部分同学持这样的观点: 1)nginx前端加入lvs和keepa ...

  7. 使用DWR实现自己主动补全 相似百度搜索框的自己主动显示效果

    使用DWR实现自己主动补全 自己主动补全:是指用户在文本框中输入前几个字母或汉字的时候,自己主动在存放数据的文件或数据库中将全部以这些字母或汉字开头的数据提示给用户供用户选择 在日常上网过程中,我们常 ...

  8. Vue生命周期方法。

  9. nyoj 题目10 skiing —— 南阳oj

    题目信息例如以下: skiing 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描写叙述 Michael喜欢滑雪百这并不奇怪, 由于滑雪的确非常刺激.但是为了获得速度,滑的区 ...

  10. SpringMVC实战(注解)

    1.前言 前面几篇介绍了SpringMVC中的控制器以及视图之间的映射方式,这篇来解说一下SpringMVC中的注解,通过注解能够非常方便的訪问到控制器中的某个方法. 2.配置文件配置 2.1 注解驱 ...