`

Sql查询语句优化心得MySQL优化

 
阅读更多

2010-12-24 14:31

作为一个互联网开发工程师,数据库的知识是必不可少的,要是写几条查询效率很差的SQL,当数据库的数据到达一定级别以后,没几个人同时访问你的网 站,就能把你的一台服务器高挂啦!【个人认为:最为简单的测试方法就是把SQL语句在命令行下运行,若查询的语句需要0.03秒以上的SQL语句都需要优 化。】

 

如下的大多都来自网络:终归起来、都是一些简单SQL优化,不敢保证这说法绝对的权威哦。phpma

 

1、用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能 够分开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;算法的结构尽量简单;在查询时,不要过多地使 用通配符如SELECT * FROM T1语句,要用到几列就选择几列如:SELECT COL1,COL2 FROM T1;在可能的情况下尽量限制尽量结果集行数如:SELECT TOP 300 COL1,COL2,COL3 FROM T1,因为某些情况下用户是不需要那么多的数据的。不要在应用中使用数据库游标,游标是非常有用的工具,但比使用常规的、面向集的SQL语句需要更大的开 销;按照特定顺序提取数据的查找。

 

2、避免使用不兼容的数据类型。例如floatintcharvarcharbinaryvarbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如: 

SELECT name FROM employee WHERE salary 60000 

在这条语句中,salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。 phpma.com

 

3 尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: 

SELECT * FROM T1 WHERE F1/2=100 应改为:  SELECT * FROM T1 WHERE F1=100*2

 

SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=5378’应改为:SELECT * FROM RECORD WHERE CARD_NO LIKE 5378%

 

SELECT member_number, first_name, last_name FROM members WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21 应改为:SELECT member_number, first_name, last_name FROM members WHERE dateofbirth < DATEADD(yy,-21,GETDATE())

 

即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

 

4 避免使用!=或<>、IS NULLIS NOT NULLIN NOT IN等这样的操作符,因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如:  SELECT id FROM employee WHERE id != "B%" 优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。

 

5 尽量使用数字型字段,一部分开发人员和数据库管理人员喜欢把包含数值信息的字段

设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

 

6 合理使用EXISTS,NOT EXISTS子句。如下所示:

1.SELECT SUM(T1.C1)FROM T1 WHERE(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)

2.SELECT SUM(T1.C1) FROM T1WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)

两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。如果你想校验表里是否存在某条纪录,不要用count(*)那样效率很低,而且浪费服务器资源。可以用EXISTS代替。如:

IF (SELECT COUNT(*) FROM table_name WHERE column_name = 'xxx')可以写成:IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx')

 

经常需要写一个T_SQL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中没有的记录,如:

1.SELECT a.hdr_key FROM hdr_tbl a---- tbl a 表示tbl用别名a代替 WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)

 

2.SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL

 

3.SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl) 

  三种写法都可以得到同样正确的结果,但是效率依次降低。

 

7 尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。  

见如下例子:

SELECT * FROM T1 WHERE NAME LIKE ‘%L%’

SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’

SELECT * FROM T1 WHERE NAME LIKE ‘L%’

即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。51ruan.com

 

8 分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,这时在 WHERE 子句中将连接条件完整的写上,有可能大大提高查询速度。例:

SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO 

SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO=B.ACCOUNT_NO

第二句将比第一句执行快得多。

 

9 消除对大型表行数据的顺序存取

  尽管在所有的检查列上都有索引,但某些形式的WHERE子句强迫优化器使用顺序存取。如:

SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR  order_num=1008

解决办法可以使用并集来避免顺序存取:

SELECT FROM orders WHERE customer_num=104 AND order_num>1001  UNION  SELECT FROM orders WHERE order_num=1008 

这样就能利用索引路径处理查询。【jacking 数据结果集很多,但查询条件限定后结果集不大的情况下,后面的语句快】

 

 

11 能够用BETWEEN的就不要用IN

SELECT * FROM T1 WHERE ID IN (10,11,12,13,14)改成:SELECT * FROM T1 WHERE ID BETWEEN 10 AND 14

因为IN会使系统无法使用索引,而只能直接搜索表中的数据。

 

12 DISTINCT的就不用GROUP BY

  SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID 可改为:SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10

  

 

13 能用UNION ALL就不要用UNION

UNION ALL不执行SELECT DISTINCT函数,这样就会减少很多不必要的资源

 

14 不要写一些不做任何事的查询

如:SELECT COL1 FROM T1 WHERE 1=0 SELECT COL1 FROM T1 WHERE COL1=1 AND COL1=2

这类死码不会返回任何结果集,但是会消耗系统资源。

 

15 尽量不要用SELECT INTO语句。

SELECT INTO 语句会导致表锁定,阻止其他用户访问该表。

 

16 必要时强制查询优化器使用某个索引

  SELECT * FROM T1 WHERE nextprocess = 1 AND processid IN (8,32,45)  改成:

SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess = 1 AND processid IN (8,32,45)

则查询优化器将会强行利用索引IX_ProcessID 执行查询。

    

17 虽然UPDATEDELETE语句的写法基本固定,但是还是对UPDATE语句给点建议:

a) 尽量不要修改主键字段。

b) 当修改VARCHAR型字段时,尽量使用相同长度内容的值代替。

c) 尽量最小化对于含有UPDATE触发器的表的UPDATE操作。

d) 避免UPDATE将要复制到其他数据库的列。

e) 避免UPDATE建有很多索引的列。

f) 避免UPDATEWHERE子句条件中的列。

分享到:
评论

相关推荐

    sql语句优化心得

    ### SQL语句优化心得 #### 引言 在软件开发过程中,SQL语句的编写往往直接关系到应用程序的性能表现。特别是在系统初期阶段,由于数据量较小,即使编写了一些效率较低的SQL语句,也可能不会立即暴露出来。然而,...

    mysql数据库优化的学习心得

    尽管我们可以使用子查询、连接和联合来创建各种各样的查询,但不是所有的数据库操作都可以只用一条或少数几条 SQL 语句就可以完成的。更多的时候是需要用到一系列的语句来完成某种工作。但是在这种情况下,当这个...

    经典SQL语句学习总结

    此外,学习SQL还应关注数据库的设计原则,如范式理论,以及优化查询性能的技巧,如索引的创建和使用。SQL语句的学习并非一蹴而就,需要通过实际操作和练习不断巩固。对于每个概念,理解其背后的逻辑和应用场景至关...

    数据库优化语句以及心得

    数据库优化是提升应用性能的关键环节,尤其是在大数据量和高并发的场景下。本文主要讨论了SQL优化中的执行...通过理解这些原则和技巧,开发人员能够更好地编写高效、稳定的SQL语句,以应对各种复杂的数据库应用场景。

    MySQL性能优化心得1

    2. **查询设计**: 查询优化涉及SQL语句的编写,应避免全表扫描,尽可能使用索引,减少子查询和不必要的联接操作。使用EXPLAIN来分析查询执行计划,找出性能瓶颈。 **三、服务器端优化** 1. **MySQL安装**: 安装时...

    SQL之SELECT相关语句使用实验.doc

    在本实验中,我们将使用商用数据库 SQL Server 或 MySQL,实现对教务系统数据的存储、查询和更新。实验要求包括建立学生选课数据库、进行实际操作、练习各类查询语句、增加、删除、修改、视图等语句,并学习、掌握...

    MySQL 查询语句

    ### MySQL 查询语句详解 #### 1. 使用 `SHOW` 语句找出在服务器上当前存在的数据库 **命令示例**: ```sql SHOW DATABASES; ``` **用途**:此命令用于显示当前 MySQL 服务器上所有可用的数据库列表。 #### 2. ...

    SQL从基础到深入——本人心得

    5. 存储过程:预编译的SQL语句集合,可以接受参数,执行复杂的业务逻辑,并返回结果。 6. 触发器(Trigger):在特定事件(如INSERT、UPDATE、DELETE)发生时自动执行的代码,用于实现业务规则或数据验证。 7. ...

    mysql的使用心得

    - MySQL 5.0.13开始,等待超时的锁只会回滚最近的SQL语句而非整个事务。 - **优点** - 减少了因锁等待超时而导致的数据一致性问题。 **7. InnoDB与MyISAM表中TEXT字段索引顺序的变化** - **变更点** - MySQL ...

    MySQL查询语句大全集锦.docx

    ### MySQL查询语句大全及管理心得详解 #### 一、MySQL基本操作命令 **1. 查找当前服务器上的所有数据库** - 命令:`SHOW DATABASES;` - 描述:此命令用于列出MySQL服务器上当前存在的所有数据库。 **2. 创建...

    1. 熟悉数据库的交互式SQL工具:如SQL Server2000查询分析器。

    数据库交互式SQL工具是数据库管理系统中的一种重要工具,能够帮助用户交互式地执行SQL语句,快速地查询和操作数据库。熟悉数据库的交互式SQL工具可以提高用户的工作效率和数据处理能力。本文将介绍数据库交互式SQL...

    手工注入常用SQL语句笔记.docx

    手工注入常用 SQL 语句笔记 ...手工注入常用 SQL 语句笔记对 MySQL 和 MSSQL 两种数据库管理系统进行了详细的介绍,涵盖了注入原理、实战心得、判断数据库类型、常用内置函数使用、数据库的扩展存储过程等方面的内容。

    Mysql优化、MyCat搭建、分库分表、读写分离、负载均衡

    "一日一记.doc"可能是关于MySQL优化的日记或笔记,记录了每天的优化过程和心得。"跨库表连接.txt"可能包含关于跨库查询的技巧和注意事项,而"测试SQL.txt"则是用于测试优化效果的SQL语句。"虚拟机列表.txt"可能列出...

    MySQL常用经典查询语句大全集锦.pdf

    ### MySQL常用经典查询语句详解 #### 1. 使用`SHOW`语句找出在服务器上当前存在的数据库 - **命令**: `SHOW DATABASES;` - **功能**: 列出当前MySQL服务器上所有可用的数据库。 - **应用场景**: 当需要了解服务器上...

    Mysql使用技巧心得

    ### MySQL使用技巧心得 在日常使用MySQL的过程中,我们经常会遇到各种各样的问题,这些问题往往需要花费大量的时间和精力去解决。本文将分享一些我在使用MySQL时的心得体会和技术要点,希望能够帮助到正在学习或...

    MySQL开发实战:电子商务订单系统数据库开发的实验心得与案例解析

    - 优化查询语句,避免性能瓶颈。 - **测试与优化**: - 彻底测试所有的数据库操作; - 分析慢查询日志,优化慢查询; - 考虑读写分离和数据库集群方案以进一步优化系统性能。 ##### 3.3 代码示例 - **创建...

    MySQL数据库应用与开发实训报告.doc

    此外,还可以通过相关SQL语句查询数据库的结构信息,了解其内部构成。 接下来是【表及数据完整性】的学习。这部分涵盖如何创建、修改和管理数据表,以及如何实现数据完整性。数据完整性是数据库管理的核心,确保...

    mysql的相关学习心得.zip

    了解如何通过优化查询、合理设计索引、调整服务器参数等方式提升MySQL性能。 10. **安全性**:学习如何创建和管理用户,设置访问权限,以及使用GRANT和REVOKE语句进行权限控制,确保数据安全。 11. **复制和集群**...

    MySQL命令大全

    以下是无意中在网络看到的使用MySql的管理心得, 在windows中MySql以服务形式存在,在使用前应确保此服务已经启动,未启动可用net start mysql命令启动。而Linux中启动时可用“/etc/rc.d/init.d/mysqld start”...

Global site tag (gtag.js) - Google Analytics