MySQL学习笔记十四:优化(1)

SQL优化

1.查看各种SQL执行的频率

mysql> show status like ‘Com_select‘;--Com_insert,Com_delete,connections(试图连接mysql服务的次数),uptime(mysql工作时间),slow_queries(慢查询次数)等等

2.定位执行效率较低的SQL语句

通过慢查询日志,定位查询效率低下的SQL语句,然后分析语句进行优化

3.通过explain或desc分析SQL语句的执行计划,如要查看所访问的分区使用explain partitions

mysql> desc select email from users\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: users
         type: index //扫描方式,效率由低到最好 all(全表)->index(索引全扫描)->range(索引范围扫描)->ref(非唯一索引)->eq_ref(唯一索引)->const/system->null
possible_keys: NULL
          key: email
      key_len: 153
          ref: NULL
         rows: 59
        Extra: Using index
1 row in set (0.00 sec)

4.使用profile分析SQL,profile就是详细地列出SQL语句执行过程

查看是否开启/支持profile

mysql> show variables like ‘profiling‘; --使用select @@have_profiling也可以
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling     | OFF   |
+---------------+-------+
mysql> set profiling=on --开启 OFF--关闭

查看所有查询分别执行的时间

mysql> show profiles;
+----------+------------+---------------------------------+
| Query_ID | Duration   | Query                           |
+----------+------------+---------------------------------+
|        1 | 0.00079925 | show variables like ‘profiling‘ |
|        2 | 0.00050700 | select * from users             |
|        3 | 0.36104925 | select * from tb_5              |
+----------+------------+---------------------------------+

查看某个查询语句执行过程每个状态以及消耗的时间

mysql> show profile for query 3;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000059 |
| checking permissions | 0.000010 |
| Opening tables       | 0.042742 |
| System lock          | 0.000018 |
| init                 | 0.000017 |
| optimizing           | 0.000004 |
| statistics           | 0.000162 |
| preparing            | 0.000010 |
| executing            | 0.000003 |
| Sending data         | 0.317929 |  --主要时间花费在将数据发送到客户端
| end                  | 0.000011 |
| query end            | 0.000007 |
| closing tables       | 0.000013 |
| freeing items        | 0.000058 |
| logging slow query   | 0.000005 |
| cleaning up          | 0.000004 |
+----------------------+----------+

5. 使用optimizer_trace分析优化器查看SQL语句执行计划(5.6版本以上)

mysql> show variables like ‘optimizer_trace‘;
+-----------------+--------------------------+
| Variable_name   | Value                    |
+-----------------+--------------------------+
| optimizer_trace | enabled=off,one_line=off |
+-----------------+--------------------------+

开启trace分析器,并调整最大可用内存

mysql> set optimizer_trace=‘enabled=on‘,end_markers_in_json=on; --以JSON格式显示
Query OK, 0 rows affected (0.05 sec)

mysql> set optimizer_trace_max_mem_size=1000000;
Query OK, 0 rows affected (0.16 sec)

通过information_schema库的optimizer_trace视图查看trace信息

mysql> select query,trace from optimizer_trace\G
*************************** 1. row ***************************
query: select * from test.stu
trace: {
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `test`.`stu`.`sno` AS `sno`,`test`.`stu`.`sname` AS `sname`,`test`.`stu`.`sclass` AS `sclass` from `test`.`stu`"-------------------只截取了部分信息,通过分析这些信息可用对SQL语句进行相应优化---------------------

6.使用索引优化查询性能

索引是数据库优化中最常用的最要种的手段,索引可以分为以下4中:

HASH索引:只有MEMORY引擎支持;  B-TREE索引:平衡树索引,最常用的索引  R-TREE索引:MyISAM引擎特殊索引  FULL-TREE全文索引:MyISAM特殊索引。

创建索引:

mysql> create index idx_name on stu(sname);
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

查看某表的所有索引

mysql> show index from stu\G
*************************** 2. row ***************************
        Table: stu
   Non_unique: 1
     Key_name: idx_name
 Seq_in_index: 1
  Column_name: sname
    Collation: A
  Cardinality: 4
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE

MySQL能够使用索引的一些情况:匹配索引全值,匹配值的范围查询,匹配最左前缀等等。

查看索引使用情况,如果handle_read_key值很高,说明查询效率很高,如Handler_read_rnd_next值很高,说明查询效率并不理想。

mysql> show status like ‘Handler_read%‘;
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 25 |
+-----------------------+-------+

7.定期检查表和分析表,以及优化表

检查表就是检查一个或多个表是否有错误

mysql> check table stu;
+--------+-------+----------+----------+
| Table  | Op    | Msg_type | Msg_text |
+--------+-------+----------+----------+
| zz.stu | check | status   | OK       |
+--------+-------+----------+----------+

分析表主要作用是让SQL生成正确的执行计划

mysql> analyze table stu;
+--------+---------+----------+----------+
| Table  | Op      | Msg_type | Msg_text |
+--------+---------+----------+----------+
| zz.stu | analyze | status   | OK       |
+--------+---------+----------+----------+

优化表的作用主要是对表空间的碎片进行合并以及回收删除或更新造成浪费的空间

mysql> optimize table t1; --对于InnoDB的表,会有Table does not support optimize, doing recreate + analyze instead提示,可以在启动mysql服务时,指定--skip-new或--safe-mode即可
+---------+----------+----------+----------+
| Table   | Op       | Msg_type | Msg_text |
+---------+----------+----------+----------+
| test.t1 | optimize | status   | OK       |
+---------+----------+----------+----------+
1 row in set (0.04 sec)

8.常用SQL优化

加载大量数据时,关闭非唯一索引,取消唯一性检查,以及取消自动提交以提高插入速度

set unique_checks=0
alter table stu disable keys
set autocommit=0
load load infile........
alter table stu enable keys
set unique_checks=1
set autocommit =1

insert语句优化,一次性插入多条记录

mysql> insert into stu values (4010409,‘钟小兆‘,‘A1114‘,22,0),(4010408,‘肖小杰‘,‘A1114‘,21,1).....;

order by语句排序优化,优化思路就是尽可能的减少额外的排序(filesort),通过索引直接返回有序数据,例如

mysql> explain select sno from stu order by sname desc;
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+
|  1 | SIMPLE      | stu   | index | NULL          | idx_name | 93      | NULL |    6 | Using index |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-------------+

where条件和order by 字段使用相同的索引,并且order by的顺序和索引顺序相同,还有order by的字段都是降序或者升序。例如:

以下情况会使用索引,前提(key-part1,key_part2)为联合索引

select * from tbl_name order by key_part1,key_part2....;
select * from tbl_name where key_part1=xxx order by key_part1,key_part2....;
select * from tbl_name order by key_part1 asc,key_part2 asc....;

以下情况则不会使用索引,(key1,key2分别建立索引)

select * from tbl_name order by key1,key2....;
select * from tbl_name where key1=xxx order by  key2;
select * from tbl_name order by key_part1 asc,key_part2 desc....;

SELECT查询时最好指定具体的字段名,SELECT * 会选择所有字段,会增加排序区的使用,降低SQL性能

group by语句优化

MySQL默认情况下对group by col1,col2..的字段进行排序,可以通过指定order by null来消除这种排序

or条件优化

用到OR的查询,如果要使用索引,那OR之间的每个条件必须是索引,并且要分别建立索引,不能使用联合索引。

时间: 2024-10-28 14:27:09

MySQL学习笔记十四:优化(1)的相关文章

mysql学习笔记 第四天

mysql引擎: archive(档案)[数据插入以后不能被修改,只读] blackhole[这种写操作是删除数据,读操作是返回空白记录] CSV[在储存数据时以逗号作为数据项之间的分隔符] example[示例(存根)储存引擎] Falcon[用来进行处理事务的储存类型] federated[用来访问远程数据表的储存引擎] InnoDB[具备外键支持功能的事务处理引擎] memory[内存里的数据表] merge[用来管理多个MyISAM数据表构成的数据表集合(merg-myisam)] my

Swift学习笔记十四:构造(Initialization)

类和结构体在实例创建时,必须为所有存储型属性设置合适的初始值.存储型属性的值不能处于一个未知的状态. 你可以在构造器中为存储型属性赋初值,也可以在定义属性时为其设置默认值.以下章节将详细介绍这两种方法. 注意: 当你为存储型属性设置默认值或者在构造器中为其赋值时,它们的值是被直接设置的,不会触发任何属性观测器(property observers). 一.基本语法 class Human{ var name :String init(){ name = "human" } init(n

laravel3学习笔记(十四)

原作者博客:ieqi.net ==================================================================================================== 运行时配置 在 Laravel3 中很多地方我们都可以看到“约定大于配置”的影子,我本人也很喜欢这种工程哲学尤其是在框架领域,当然这并不能代替所有的配置.我们知道 Laravel3 中,主要配置都写在 application/config 文件夹下,在应用逻辑中,往往

Mysql学习笔记(四)字符串函数

PS:终于看完了字符串函数,心都快碎了...涉及的函数真是太多了...感觉这里的字符串函数和JAVA里的基本都差不多了...基本上算是掌握了,但是想全记住那是不太可能的... 学习内容: 字符串函数的掌握和应用.. ASCii(str) 返回字符串的最左边的ascii码值..如果str为NULL,那么返回NULL...如果字符串为0,那么返回也为0... mysql>select ascii('2'); mysql>select ascii('dx'); ORD(str)函数 如果字符串最左边

MYSQL学习笔记——sql语句优化之索引

上一篇博客讲了可以使用慢查询日志定位耗时sql,使用explain命令查看mysql的执行计划,以及使用profiling工具查看语句执行真正耗时的地方,当定位了耗时之后怎样优化呢?这篇博客会介绍mysql中最简单快速的优化方法——添加索引. 一.索引的添加                                                                              mysql一共有四类索引,分别是主键索引.唯一索引.普通索引以及全文索引. 1.1.主

MYSQL学习笔记——sql语句优化工具

前面讲解了很多mysql的基础知识,这一章讲解mysql的语句优化. 一.定位慢查询                                                                                 我们要对sql语句进行优化,第一步肯定是找到执行速度较慢的语句,那么怎么在一个项目里面定位这些执行速度较慢的sql语句呢?下面就介绍一种定位慢查询的方法. 1.1.数据库准备 首先创建一个数据库表: CREATE TABLE emp (empno MED

MySQL学习笔记十二:数据备份与恢复

数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql服务器,或者对需要备份的对象进行锁定,要不很容易造成备份的不一致性,恢复时可能会丢失数据.物理备份的方式有很多,如操作系统命令copy(cp),scp,mysqlbackup,以及MyISAM表的mysqlhotcopy. 逻辑备份 逻辑备份是对数据库的逻辑结构(create database,cr

MySQL学习笔记(四)

一.索引 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可以提高数据库中特定数据的查询速度. 索引的分类: 1.普通索引,允许在定义索引的列中插入重复值和空值. 唯一索引,索引列的值必须是唯一,但允许有空值. 2.单列索引,一个索引只包含单个列,一个表可以有多个单列索引. 组合索引,指在表的多个字段组合上创建索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用.使用组合索引时遵循最左前缀集合. 3.全文索引,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值

Mysql学习笔记(四)聊聊数据库索引

小心情(可直接跳到分割线后) 今天心情好些了.一些浓的化不开的坏情绪,也渐渐的在晚上解决掉一个复杂的逻辑问题后,渐渐消散了. 今天中午去吃饭的时候,坤哥漫不经心的说:'我这么多年终于悟出了一个道理,人年轻的时候不要那么拼命,都没有时间做其他事情了' 我问什么其他事情,坤哥看了我一眼,又继续漫不经心的说,那么忙,都没有时间谈恋爱了. 我想不那么拼命可以嘛?房价每年都涨,生活的成本与日俱增.如果不努力让自己的价值所赚取的金钱,超过经济增速.那么只能继续成为一个社会底层的loser,继续在青春的美好时