sql优化一 (sql优化的一般步骤)

当面对一个有 SQL性能问题的数据库时,我们应该从何处入手来进行系统的分析,使得能够尽快定位问题 SQL 并尽快解决问题 。

 

优化sql语句的一般步骤

一、通过 show status 命令了解各种SQL的执行频率

通过 show [session | global] status 命令可以提供服务器状态信息,也可以在操作系统上使用 mysqladmin extended-status 命令获取这些消息。

show [session|global] status 可以根据需要加上参数“session”或者“global”来显示 session 级(当 前连接)的统计结果和 global 级(自数据库上次启动至今)的统计结果。如果不写,默认使 用参数是“session”。

显示session中所有的统计参数值:

mysql> show status like ‘Com_%‘;

+---------------------------+-------+

| Variable_name                   | Value |

+---------------------------+-------+

| Com_admin_commands       | 0     |

| Com_assign_to_keycache    | 0     |

| Com_alter_db                     | 0     |

| Com_alter_db_upgrade        | 0     |

| Com_alter_event                 | 0     |

| Com_alter_function             | 0     |

| Com_alter_procedure          | 0     |

| Com_alter_server                | 0     |

| Com_alter_table                  | 0     |

............

Com_xxx 表示每个xxx语句执行的次数,我们通常比较关心的是以下几个统计参数。

* Com_select :执行 select 操作的次数,一次查询只累加1。

* Com_insert  : 执行 insert 操作的次数,对于批量插入的 insert 操作,只累加一次。

* Com_update :执行update操作次数。

* Com_delete :执行delete操作次数。

上面这些参数对于所有存储引擎的表操作都会进行累计。下面这几个参数只针对innoDB存储引擎的,累加的算法也略有不同。

* innodb_rows_read : select 查询返回的行数。

* innodb_rows_inserted : 执行 insert 操作插入的行数。

* innodb_rows_updated : 执行 update 操作更新的行数。

* innodb_rows_deleted : 执行 delete 操作删除的行数。

通过以上几个参数我们可以了解到?

(1)当前数据库的应用是以插入更新为主还是以查询操作为主

(2) 各种类型的sql大致执行的比例是多少。对于更新操作的计数,是对执行 次数的计数,不论提交还是回滚都会进行累加。

对于事务型的应用

* Com_commit 事务提交

* Com_rollback 事务回滚

对于回滚操作非常频繁的数据库,可能意味着应用编写存在问题。

对于了解数据库的基本情况

* Connections :试图连接mysql 服务器的次数。

* uptime :服务器工作时间。

* slow_queries :慢查询的次数。

二、定位执行效率低的sql语句

(1)通过慢查询日志定位执行效率低的sql语句

(2)使用 show processlist 命令查看当前 MySQL 在进行的线程

慢查询日志在查询结束以后才纪录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用 show processlist 命令查看当前 MySQL 在进行的线程, 包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操 作进行优化。

三、通过 explain 分析低效 sql 的执行计划

执行一条sql:

mysql> explain select sum(age) from sales a,company b where a.company_id = b.id and age = 20\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: a

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 65913

Extra: Using where

*************************** 2. row ***************************

id: 1

select_type: SIMPLE

table: b

type: eq_ref

possible_keys: PRIMARY

key: PRIMARY

key_len: 4

ref: test1.a.company_id

rows: 1

Extra: Using index

2 rows in set (0.00 sec)

每个列的简单解释如下:

* select_type :表示 select 的类型,常用的取值有

simple (简单表,即不使用表连接或者子查询)、

primary (主查询,即外层的查询),

union (union 中的第二个或者后面的查询语句)、

primary (主查询,即外层的查询)、

union (union 中的第二个或者后面的查询语句)、

subquery (子查询中的第一个select)等。

* table :输出结果集的表。

* type :表式表的连接类型,性能由好到差的连接类型为

system (表中仅有一行,即常量表)、

const(单表中最多有一个匹配行,例如 primary key 或者 unique index)、

eq_ref(对于前面的每一行,在此表中只查询一条记录,简单来说,就是多表连接中使用 primary key 或者 unique index)、

ref(与 eq_ref 类似,区别在于不使用 primary key 或者 unique index,而是普通的索引)、

ref_or_null (与 ref 类似,区别在于条件中包含对 null 的查询)、

index_merge (索引合并优化)、

unique_subquery (in 的后面是一个查询主键字段的子查询)、

index_subquery (与 unque_subquery 类似,区别在于 in 的后面是查询非唯一索引字段的子查询)、

range (单表范围中的查询)、

index (对于前面的每一行,都通过查询索引来得到数据)、

all (对于前面的每一行,都通过全表扫描来得到数据)。

* possible_key :表示查询时,可能使用的索引。

* key :表示实际使用的索引。

* key_len : 索引字段的长度。

* rows :扫描行的数量。

* extra :执行情况的说明和描述

四、确定问题并采取相应的措施

经过以上步骤,基本就可以确认问题出现的原因。此时用户可以根据情况采取相应的措施,进行优化提高执行的效率。

在上面的例子中,已经可以确认是对 a 表的全表扫描导致效率的不理想,那么对 a 表的 age 字段创建索引,具体如下:

mysql> create index ind_sales_age on sales(age);

Query OK, 0 rows affected (0.11 sec)

Records: 0  Duplicates: 0  Warnings: 0

创建索引后,再看一下这条语句的执行计划,具体如下:

mysql> explain select sum(age) from sales a,company b where a.company_id = b.id and age = 20\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: a

type: ref

possible_keys: ind_sales_age

key: ind_sales_age

key_len: 2

ref: const

rows: 1

Extra: NULL

*************************** 2. row ***************************

id: 1

select_type: SIMPLE

table: b

type: eq_ref

possible_keys: PRIMARY

key: PRIMARY

key_len: 4

ref: test1.a.company_id

rows: 1

Extra: Using index

2 rows in set (0.00 sec)

可以发现建立索引后a表需要扫描的行数明显减少(从65913行减少到1行),可见索引的使用可以大大提高数据库的访问速度,尤其在表很庞大的时候这种优势更为明显。

时间: 2024-08-03 16:25:36

sql优化一 (sql优化的一般步骤)的相关文章

SQL业务审核与优化

审核   什么是业务审核 类似与code review 评审业务Schema和SQL设计 偏重关注性能 是业务优化的主要入口之一 审核提前发现问题,进行优化 上线后通过监控或巡检发现问题,进行优化 Schema设计审核 表和字段命名是否合规 字段类型,长度设计是否适当 表关联关系是否合理 主键,更新时间保留字段等是否符合要求 约束,默认值等配置是否恰当 了解业务,表数据量,增长模式 数据访问模式,均衡度 根据业务需求,表是否需要分区,是否有数据什么周期 SQL语句审核 SQL语句的执行频率 表上

SQL Server数据库性能优化之SQL语句篇(转载)

SQL Server数据库性能优化之SQL语句篇 原文地址:http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 期项目需要,做了一段时间的SQL Server性能优化,遇到了一些问题,也积累了一些经验,现总结一下,与君共享.SQL Server性能优化涉及到许多方面,如良好的系统和数据库设计,优质的SQL编写,合适的数据表索引设计,甚至各种硬件因素:网络性能.服务器的性能.操作系统的性能,甚至网卡.交换机等.这篇文章主

mysql优化-数据库优化、SQL优化

我有一张表w1000,里面有1000万条数据,这张表结构如下:CREATE TABLE `w1000` ( `id` varchar(36) NOT NULL, `name` varchar(10) DEFAULT NULL, `age` int(3) DEFAULT NULL, `money` double(8,2) DEFAULT NULL, `address` varchar(100) DEFAULT NULL, `create_date` datetime(3) DEFAULT NULL

Mysql性能优化----SQL语句优化、索引优化、数据库结构优化、系统配置优化、服务器硬件优化

一.SQL语句优化 1-1.MySQL慢日志 1).慢日志开启方式和存储格式 如何发现有问题的SQL? 使用Mysql慢日志对有效率问题的SQL进行监控 前期准备 mysql> show variables like '%log_queri%'; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_no

ORACLE性能优化之SQL语句优化

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 操作环境:AIX +11g+PLSQL 包含以下内容: 1.  SQL语句执行过程 2.  优化器及执行计划 3.  合理应用Hints 4.  索引及应用实例 5.   其他优化技术及应用 1.SQL语句执行过程 1.1 SQL语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. 3)视图转换,将涉及视图的查询语句转

SQL常见的可优化点

此文章系在SQL代码文件中写的... # ########################################### # 索引相关 # ########################################### – 查询(或更新,删除,可以转换为查询)没有用到索引 这是最基础的步骤,需要对sql执行explain查看执行计划中是否用到了索引,需要重点关注type=ALL, key=NULL的字段. – 在索引字段上施加函数 to_char(gmt_created, ‘mm

mysql基础操作、sql技巧和sql的常见优化

一.常见操作 1.复制表结构create table t2 like t1 复制表数据insert into t2 select * from t1 2.mysql索引 alter table用来创建普通索引.unique索引或primary key索引 alter table t add index index_name(column_list) alter table t add unique(column_list) alter table t add primary key(column

数据库高并发情况下重复值写入的避免 字段组合约束+ SQL SERVER 的SQL语句优化方式小结(转)

10线程同时操作,频繁出现插入同样数据的问题.虽然在插入数据的时候使用了: insert inti tablename(fields....) select @t1,@t2,@t3 from tablename where not exists (select id from tablename where [email protected],[email protected],[email protected]) 当时还是在高并发的情况下无效.此语句也包含在存储过程中.(之前也尝试线判断有无记

SQL优化笔记—CPU优化

补充:常规服务器动态管理对象包括,下面有些资料可能会应用到 dm_db_*:数据库和数据库对象dm_exec_*:执行用户代码和关联的连接dm_os_*:内存.锁定和时间安排dm_tran_*:事务和隔离dm_io_*:网络和磁盘的输入/输出 优化性能的常用方法是检索速度最慢的查询构成您 SQL Server 实例上的正常. 每日工作负载的一部分,然后调整它们,一个接一个的"Top 10"列表. 跟踪会话. 请求 和 SQL Server 基础架构中的最耗费大量资源,查询和执行时间最长

SQL Server数据库性能优化之SQL语句篇

SQL Server数据库性能优化之SQL语句篇 近期项目需要,做了一段时间的SQL Server性能优化,遇到了一些问题,也积累了一些经验,现总结一下,与君共享.SQL Server性能优化涉及到许多方面,如良好的系统和数据库设计,优质的SQL编写,合适的数据表索引设计,甚至各种硬件因素:网络性能.服务器的性能.操作系统的性能,甚至网卡.交换机等.这篇文章主要讲到如何改善SQL语句,还将有另一篇讨论如何改善索引.如何改善SQL语句的一些原则: 1. 按需索取字段,跟“SELECT *”说拜拜