`
sqe_james
  • 浏览: 264827 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MySQL SQL优化小结

阅读更多

优化是一个综合复杂的问题,涉及到硬软件平台。这里仅就MySQL5.0 SQL 查询语句方面作个小结。先举个例子:

现在表register(PRIMARY KEY regId),service(PRIMARY KEY servId, index serviceId )和subscribe(PRIMARY KEY subId,FOREIGN KEY regId/servId),且前两表跟后张表均为一对多关联,假设有如下表格结构:

CREATE TABLE `subscribe` (
  `subId` int(10) unsigned NOT NULL auto_increment,
  `subcribeTime` datetime NOT NULL,
  `expireTime` datetime NOT NULL,
  `cancelTime` datetime default NULL,
  `paymoney` double NOT NULL,
  `paymentTime` datetime NOT NULL,
  `payWay` tinyint(3) unsigned NOT NULL,
  `subcribeStatus` tinyint(3) unsigned NOT NULL,
  `paymentStatus` tinyint(3) unsigned NOT NULL,
  `createTime` datetime NOT NULL,
  `regId` int(10) default NULL,
  `servId` int(10) default NULL,
  PRIMARY KEY  (`subId`),
  KEY `FK_REGID` (`regId`),
  KEY `FK_SERVID` (`servId`),
  CONSTRAINT `FK_REGID` FOREIGN KEY (`regId`) REFERENCES `register` (`regId`) 
ON DELETE CASCADE,
  CONSTRAINT `FK_SERVID` FOREIGN KEY (`servId`) REFERENCES `service` (`servId`) 
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在一业务根据条件subscribe.subcribeStatus=1 或 >=3 AND subscribe.expireTime <= now() 要取得subscribe.subId,register.phoneNum,service.serviceId 三个字段信息列表。测试中三表中各有三条数据具结果亦为3,初始sql 语句及执行结果如下:

这是一条最容易想到的SQL 语句,虽然优化器默认采用type 快速的indexeq_ref 类型,但suref 均为NULL 意味着将全表扫描,并 产生一个笛卡尔乘积。对于这个实例由于各表都有3行数据,即扫描3*3*1=9 行。如果表中数据是99999,那么将是99999*99999*1=? ,你可以想象它将花多长时间……,如果是关键业务这将是一场恶梦。 那有没什么办法尽最大可能地减少这个笛卡尔乘积呢?先看看优化器对上面最终执行的语句:

可以看到优化器将使用内连接来执行这个语句,这将是一个考虑的优化点,再看看这有许多WHERE 条件,这可不可以做反应优化呢?

分析一下,可以看到这些WHERE 条件中起实质限定作用的 均与subscribe 这张表有关 ,那就从这开始吧, u.subcribeStatus>=3 OR u.subcribeStatus=1 这个语句看起来有点不顺眼 (可能是因为有个OR,呵呵 ~),既然1到3中只2除外,那有没可能去掉这个OR 呢? 看一下业务需求,原来subscribeStatus 只有1至4的值,很明显这个写法不妥。 可以改为u.subcribeStatus <>2 其它条件看起来没什么问题。再来看看联接查询方面的。 既然所有限定条件都是u 表的,那么自然想到查询应该从u 表开始搜索,这可以使用左/右联接,看个人爱好。 看一下最终语句的执行结果:

可看到笛卡尔积变成了:3*1*1=3 ,相对前者多了个ref 引用,虽然已经很“完美”了,但不可避免有个表type=all 意味着将根据条件进行全表扫描。再看看优化器的执行方式:

很显然,它按我们优化方向执行,先从u 开始再联接s /r (这两次序无所谓)查询。就这个示例,我们也只能优化到这里,看看笛卡积,效果还是相当不错的,少了一个数量级的扫描。根据SHOW WARNINGS 最终SQL 为(ON 条件中也可以不用括号):

SELECT u.subId, r.phoneNum, s.serviceId FROM subscribe as u LEFT JOIN service as s
 ON (s.servId=u.servId) LEFT JOIN register as r ON (r.regId=u.regId)
 WHERE u.subcribeStatus<>=? AND u.expireTime <= now() LIMIT ?,?

 

通过上面示例,可以知道MySQL 提供的一些工具非常实用,下面介绍一下刚才用过的:

1. GRANT 语句尽量简单,以降低不必要的许可检查开销;
2. 如果问题与具体MYSQL表达式或函数有关,可使用BENCHMARK() 函数执行定时测试,语法:BENCHMARK(loop_count,expression) ;
3. EXPLAIN可作为DESCRIBE的同义词,它将解释MySQL如何处理SELECT语句,提供有关表如何联接和联接的次序信息,这对优化SQL 语句特别是级联查询时特别有用。

4. SHOW WARNINGS 可以浏览EXTENDED 产生的附加信息,输出优化器重写并优化后的SELECT语句,可能还包括优化过程的其它注解。
EXPLAIN 语法及等价SQL 语句如下:
EXPLAIN tbl_name / EXPLAIN [EXTENDED] SELECT select_options
EXPLAIN tbl_name = DESCRIBE tbl_name = SHOW COLUMNS FROM tbl_name


          何时须为表加入索引以得到更快的SELECT
         /
主要用途:
         \
          知道优化器是否以一个最佳次序联接表

 

 

WHERE子句优化

1. MySQL能更高效地在声明具有相同类型和尺寸的列上使用索引,所以在类型相同时尽量保持相同尺寸(如对于固定大小的使用char类型),如果数据经常修改的话CHAR要优于VARCHAR。因为定长的行并不会有存储残片。对于非常短的列,CHAR要比VARCHAR高效。

 

2.去除不必要的括号

e.g. ((a AND b) AND c OR (((a AND b) AND (c AND d))))
   -> (a AND b AND c) OR (a AND b AND c AND d)

 

3. 常量重叠

e.g. (a < b AND b = c) AND a = 5
   -> b > 5 AND b = c AND a = 5

 

4. 去除常量条件(由于常量重叠需要):

 e.g. (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
   -> B=5 OR B=6

 

5. 如果不使用GROUP BY或分组函数(COUNT()、MIN()……),HAVING与WHERE合并。

 

6. 对于联接内的每个表,构造一个更简单的WHERE以便更快地对表进行WHERE计算并且也尽快跳过记录。

 

7. 所有常数的表在查询中比其它表先读出。常数表为:
   空表或只有1行的表。
   与在一个PRIMARY KEY或UNIQUE索引的WHERE子句一起使用的表,这里所有的索引部分使用常数表达式并且索引部分被定义为NOT NULL。


e.g.下列的所有表用作常数表:
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id

 

 

待续。。。。

 

分享到:
评论

相关推荐

    MySQL常用基本SQL语句小结[参考].pdf

    以下是关于MySQL常用基本SQL语句的小结: 1. **数据定义语言 (DDL)**: DDL用于创建、修改和删除数据库结构。在MySQL中,这包括: - `CREATE DATABASE`: 用于创建新的数据库,例如`CREATE DATABASE database-name`...

    mysql配置和优化

    #### 五、小结 MySQL配置和优化是一项细致而复杂的工作,需要根据具体的应用场景进行定制化的设置。通过合理的配置,不仅可以提高数据库的性能,还能确保数据库的安全性和稳定性。希望本文能够为MySQL的使用者提供...

    2021年MySQL高级教程视频.rar

    16.MySQL高级锁MyISAM表锁小结.avi 17.MySQL高级锁MyISAM表锁查看锁争用情况.avi 18.MySQL高级锁InnoDB行锁介绍及背景知识.avi 18.MySQL高级锁InnoDB行锁类型.avi 19.MySQL高级锁InnoDB行锁基本演示.avi 20.MySQL...

    SQL Server的链接服务器技术小结

    SQL Server 链接服务器技术小结 链接服务器技术是 SQL Server 中的一种功能,允许用户从一个 SQL Server 数据库访问其他数据库管理系统中的数据。这种技术可以帮助用户实现数据集成和数据交换,提高数据共享和协作...

    MySql数据库性能优化

    小结 MySql 数据库性能优化是指通过调整和优化数据库的各种参数、结构和查询语句,提高数据库的运行速度和效率,减少资源占用和系统瓶颈。通过了解 MySql 数据库性能优化的相关知识点,可以提高数据库的运行速度和...

    SQL SERVER 的SQL语句优化方式小结

    1、SQL SERVER 2005的性能工具中有SQL Server Profiler和数据库引擎优化顾问,极好的东东,必须熟练使用。 2、查询SQL语句时打开“显示估计的执行计划”,分析每个步骤的情况 3、初级做法,在CPU占用率高的时候,...

    2017最新老男孩MySQL高级专业DBA实战课程全套【清晰不加密】,看完教程月入40万没毛病

    8-MySQL数据库SQL优化生产方案及细节精讲04.avi 9-MySQL数据库架构优化生产方案及细节精讲05.avi 第十六部 MySQL业务变更流程与安全管理思想(7节) 01-安全优化-项目开发流程及数据库更新流程.avi 02-DBA参与项目...

    Mysql数据库之sql基本语句小结

    MySQL是世界上最流行的关系型数据库管理系统之一,其SQL(Structured Query Language)语法是管理和操作数据库的基础。本文将对MySQL中的SQL基本语句进行详尽的解释和总结。 首先,登录和退出MySQL是数据库操作的...

    MySQL InnoDB小结1

    总的来说,MySQL的InnoDB存储引擎通过其强大的事务处理能力和各种优化机制,确保了数据库的高效稳定运行。了解和掌握InnoDB的特性对于优化数据库性能和设计高可用性系统至关重要。在实际应用中,根据业务需求选择...

    MySQL中Nested-Loop Join算法小结

    MySQL中的Nested-Loop Join(NLJ)是一种基本的JOIN操作实现方式,主要用于处理两个或多个表之间的...通过深入理解NLJ的工作原理、变形和优化策略,我们可以更好地设计和调优复杂的SQL查询,提高数据库系统的整体性能。

    mysql和oracle的区别小结(功能性能、选择、使用它们时的sql等对比)

    MySQL 和 Oracle 是两种广泛应用的关系型数据库管理系统,它们在功能、性能、并发性、一致性、事务处理、数据持久性、提交方式、逻辑备份、热备份、SQL 扩展性、复制机制、性能诊断、权限安全、分区表和索引、管理...

    MYSQL表优化方法小结 讲的挺全面

    MySQL数据库在面对高并发、大数据量的场景时,性能优化显得尤为重要。本文主要总结了一些针对MySQL表优化的方法,旨在帮助解决服务器性能瓶颈,提升数据库的响应速度和稳定性。 首先,MySQL的配置文件对于性能有着...

    MySql的存储过程学习小结 附pdf文档下载

    MySQL的存储过程是数据库管理中的一个重要概念,它允许开发者在数据库中预定义一系列的SQL语句,形成一个可重用的程序单元。这样可以提高效率,减少网络流量,并且有利于数据库的安全性和一致性。本篇文章主要介绍了...

    MySQL5.1性能调优与架构设计.mobi

    如MySQL Schema设计的技巧,Query语句的性能优化方式方法及MySQL Server中SQL层和存储引擎层的优化思路。同时还分析了MySQL数据库中主要存储引擎的锁定机制 ●架构设计篇则主要以设计一个高可用可扩展的分布式企业级...

    实验报告六 MYSQL备份与恢复.docx

    - `mysql -u root -p &lt; all.sql`: 恢复所有数据库。 - `mysql -u root -p database_name &lt; database.sql`: 恢复指定数据库。 #### 2. 增量备份 - **备份步骤**: - 使用`mysqldump`命令备份数据库到文件(如`stm....

    六条比较有用的MySQL数据库操作的SQL语句小结

    在MySQL数据库操作中,SQL(Structured Query Language)是不可或缺的工具,它用于管理关系数据库系统。以下是六个实用的SQL语句,对初学者尤其有帮助: 1. **计算年数** 当需要根据生日计算年龄时,可以使用以下...

    mysql -参数thread_cache_size优化方法 小结

    此外,定期检查并优化SQL语句,避免全表扫描,合理使用索引,以及对数据进行分区等都是提升MySQL性能的有效手段。 在日常运维中,我们还应注意监控MySQL服务器的线程状态,通过`SHOW GLOBAL STATUS LIKE 'Thread%'`...

Global site tag (gtag.js) - Google Analytics