`

编写高性能的mysql语法

    博客分类:
  • db2
阅读更多
编写高性能的mysql语法
在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性。

在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。

二、SQL语句编写注意问题
下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。

1. IS NULL 与 IS NOT NULL
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。

任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。
  补充:对db2好像这个不成立,我用了      is not null   db2还是使用索引的,mysql没有试过

2. 联接列

对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。我们一起来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),现在要查询一个叫比尔.克林顿(Bill Cliton)的职工。

下面是一个采用联接查询的SQL语句,

select * from employss
where
first_name||''||last_name ='Beill Cliton'

上面这条语句完全可以查询出是否有Bill Cliton这个员工,但是这里需要注意,系统优化器对基于last_name创建的索引没有使用。

当采用下面这种SQL语句的编写,Oracle系统就可以采用基于last_name创建的索引。

Select * from employee
where
first_name ='Beill' and last_name ='Cliton'

遇到下面这种情况又如何处理呢?如果一个变量(name)中存放着Bill Cliton这个员工的姓名,对于这种情况我们又如何避免全程遍历,使用索引呢?可以使用一个函数,将变量name中的姓和名分开就可以了,但是有一点需要注意,这个函数是不能作用在索引列上。下面是SQL查询脚本:

select * from employee
where
first_name = SUBSTR('&&name',1,INSTR('&&name',' ')-1)
and
last_name = SUBSTR('&&name',INSTR('&&name’,' ')+1)
 

3. 带通配符(%)的like语句

同样以上面的例子来看这种情况。目前的需求是这样的,要求在职工表中查询名字中包含cliton的人。可以采用如下的查询SQL语句:

select * from employee where last_name like '%cliton%'

这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串其他位置时,优化器就能利用索引。在下面的查询中索引得到了使用:

select * from employee where last_name like 'c%'
  补充: 这点对于db2是有点差别的,如果索引是asc的,那么用用 like 'c%'是可以用索引的,如果索引是desc的,那么用‘%c’是可以用索引的,当然用'%c%'     db2也是不会用索引的

4. Order by语句

ORDER BY语句决定了Oracle如何将返回的查询结果排序。Order by语句对要排序的列没有什么特别的限制,也可以将函数加入列中(象联接或者附加等)。任何在Order by语句的非索引项或者有计算表达式都将降低查询速度。

仔细检查order by语句以找出非索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by子句中使用表达式。

5. NOT

我们在查询时经常在where子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用and(与)、or(或)以及not(非)。NOT可用来对任何逻辑运算符号取反。下面是一个NOT子句的例子:

... where not (status ='VALID')

如果要使用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符。NOT运算符包含在另外一个逻辑运算符中,这就是不等于(<>)运算符。换句话说,即使不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例:

... where status <>'INVALID'

再看下面这个例子:

select * from employee where salary<>3000;

对这个查询,可以改写为不使用NOT:

select * from employee where salary<3000 or salary>3000;

虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。

6. IN和EXISTS

有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种格式的子查询。

第一种格式是使用IN操作符:

... where column in(select * from ... where ...);

第二种格式是使用EXIST操作符:

... where exists (select 'X' from ...where ...);

我相信绝大多数人会使用第一种格式,因为它比较容易编写,而实际上第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。

第二种格式中,子查询以‘select 'X'开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化器就不必遍历整个表而仅根据索引就可完成工作(这里假定在where语句中使用的列存在索引)。相对于IN子句来说,EXISTS使用相连子查询,构造起来要比IN子查询困难一些。

通过使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。

同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。

 

 原文地址 http://www.phpchina.cn/viewarticle.php?id=4507
分享到:
评论

相关推荐

    教你编写高质量、高性能的MySQL语法

    ### 编写高质量、高性能MySQL语法的关键点 在软件开发领域,尤其是在系统逐渐承载大量数据之后,编写高质量、高性能的SQL语句变得至关重要。本文旨在深入探讨如何优化MySQL语法,以提升系统的响应速度和整体性能。 ...

    教你编写高质量 高性能的MySQL语法

    ### 编写高质量、高性能的MySQL语法指南 #### 引言 在软件开发过程中,数据库性能往往是决定系统响应时间和用户体验的关键因素之一。特别是在面对大量数据处理时,优化SQL语句显得尤为重要。本文将深入探讨如何编写...

    如何编写高质量、高性能的MySQL语法

    综上所述,编写高质量、高性能的MySQL语法需要考虑索引的有效利用、避免性能杀手如NULL处理、通配符使用以及优化排序等。通过理解优化器的工作原理并合理设计查询,可以显著提升数据库系统的整体性能。

    高性能MySQL第三版

    《高性能MySQL(第3版)》是一本深入探讨MySQL数据库管理、优化和设计的经典之作。这本书详尽地阐述了MySQL的各个关键领域的知识,旨在帮助读者理解和实施高性能的数据库解决方案。以下是对书中主要知识点的详细概述...

    高性能MySQL(pdf已分割)

    《高性能MySQL》是一本深入探讨MySQL数据库管理、优化与应用的经典著作。这本书涵盖了从基础到高级的诸多主题,旨在帮助读者提升MySQL服务器的性能,优化数据库设计,以及更有效地进行数据库运维。PDF版本已被分割为...

    mysql高级语法教学

    MySQL是一种广泛使用的开源关系型数据库管理系统,其高级语法是数据库管理员和开发人员必备的技能之一。本教程将深入探讨MySQL的高级特性,帮助你提升在数据处理和查询优化方面的专业能力。 1. **子查询与联接操作*...

    高性能MYSQL高清扫描中文第三版(PDF)+SQL必知必会高清非扫描第四版(PDF)

    《高性能MySQL》是一本专为数据库管理员、开发人员和系统架构师编写的权威指南。这本书深入探讨了MySQL的高级特性和最佳实践,帮助读者理解如何优化MySQL的性能,确保系统的稳定性和可扩展性。在第三版中,作者们...

    高性能Mysql学习笔记.zip

    《高性能MySQL学习笔记》是一份全面探讨MySQL数据库优化与高效运用的资料集合,旨在帮助读者深入理解MySQL的内部机制,并掌握提升数据库性能的各种策略和技术。这份笔记可能包含了多个章节,涵盖了从基础概念到高级...

    MySQL书籍(高性能MySQL(第3版).pdf+MYSQL与MARIADB学习指南.pdf及示例代码)

    本资料包包含两本重要的MySQL相关书籍——《高性能MySQL(第3版)》和《MYSQL与MARIADB学习指南》,以及《MySQL与MariaDB学习指南》的示例数据库与表。 《高性能MySQL(第3版)》是一本权威的MySQL性能优化指南。...

    《高性能 MySQL》第三版学习笔记.zip

    《高性能 MySQL》第三版是一本深受数据库管理员、开发者和系统架构师喜爱的经典著作,它深入探讨了MySQL的各种优化策略和最佳实践,旨在帮助读者构建和维护高性能的数据库系统。本书涵盖了从基础到高级的众多主题,...

    mysql和Oracle性能比较.pdf

    1. **INSERT操作**:在插入数据时,Oracle数据库通过其自身的高性能特性,如PL/SQL块,可以更好地处理批量数据插入。MySQL通常依赖于单条SQL语句或者使用INSERT语句的优化技巧,比如使用INSERT ... SELECT或LOAD ...

    mysql学习网站和sql的语法比较

    因此,了解特定数据库的语法特点对于高效地编写SQL至关重要。 总的来说,学习MySQL不仅需要理解SQL的基本概念,还要掌握MySQL特有的语法和特性。通过各种在线学习资源,可以逐步熟悉和精通这个强大的数据库系统。在...

    MySQL管理之道 性能调优、高可用与监控.part2.rar

    《mysql管理之道:性能调优、高可用与监控》由资深mysql专家撰写,以最新的mysql版本为基础,以构建高性能mysql服务器为核心,从故障诊断、表设计、sql优化、性能参数调优、mydumper逻辑、xtrabackup热备份与恢复、...

    go-mysql-transfer是一款MySQL数据库实时增量同步工具.rar

    从而在数据库和接收端之间形成一个高性能、低延迟的增量数据同步更新管道。 特性 1、简单,不依赖其它组件,一键部署 2、集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ、...

    mysql学习资料(9本)

    2. **高性能MySQL(第3版).pdf**:这是一部经典之作,深入探讨了如何优化MySQL以实现高性能。内容可能包括查询优化、存储引擎的选择、复制技术、性能监控和调优策略等,对于希望提升MySQL性能的开发者来说非常有价值...

    MySql.Data.Entity.6.10.9 + MySql.Data.6.10.9

    1. **简化数据库操作**:通过EF的Linq-to-Entities,开发者可以使用C#或VB.NET的查询语法来操作数据库,无需关心底层SQL语句的编写。 2. **自动迁移**:使用Code First时,EF提供了一个方便的迁移机制,允许开发者...

    mysql性能优化与架构设计

    MySQL性能优化与架构设计是数据库管理员和开发人员必须掌握的关键技能之一。MySQL作为一个广泛使用的开源关系型数据库管理系统,其性能优化对于提升应用的整体性能至关重要。本资料主要关注MySQL的架构理解、性能...

Global site tag (gtag.js) - Google Analytics