现在的位置: 首页 > 综合 > 正文

mysql 的优化(如何查询mysql中执行效率低的sql语句)

2013年08月31日 ⁄ 综合 ⁄ 共 10655字 ⁄ 字号 评论关闭

配置my.cnf/my.ini,增加 --log-slow-queries 配置,记录所有的slow query,然后挨个优化
本文来源于 WEB开发网

select @a=DRClass1, @b=DRClass2, @c=DRClass3, @d=DRClass4, @e=DRClass5 from Teacher Where TeacherID = @TeacherID

create table classname(classname char(50)) 
insert into classname (classname) values (@a) 
if (@b is not null) 
begin 
insert into classname (classname) values (@b)

if (@c is not null) 
begin 
insert into classname (classname) values (@c)

if (@d is not null) 
begin 
insert into classname (classname) values (@d) 
if (@e is not null) 
begin 
insert into classname (classname) values (@e) 
end 
end 
end 
end

select * from classname

以上这些SQL语句能不能转成一个存储过程?我自己试了下 
ALTER PROCEDURE Pr_GetClass

@TeacherID int, 
@a char(50), 
@b char(50), 
@c char(50), 
@d char(50), 
@e char(50) 
as

select @a=DRClass1, @b=DRClass2, @c=DRClass3, @d=DRClass4, @e=DRClass5 from Teacher Where TeacherID = @TeacherID 
DROP TABLE classname 
create table classname(classname char(50))

insert into classname (classname) values (@a) 
if (@b is not null) 
begin 
insert into classname (classname) values (@b)

if (@c is not null) 
begin 
insert into classname (classname) values (@c)

if (@d is not null) 
begin 
insert into classname (classname) values (@d) 
if (@e is not null) 
begin 
insert into classname (classname) values (@e) 
end 
end 
end 
end

select * from classname 
但是这样的话,这个存储过程就有6个变量,实际上应该只提供一个变量就可以了

主要的问题就是自己没搞清楚 @a,@b,@C,@d 等是临时变量,是放在as后面重新做一些申明的,而不是放在开头整个存储过程的变量定义。

(标准化越来越近了):namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

实战SQL语句收集(不断更新中--)

前言:这里将我编程实践中遇到的有价值的sql语句一路记下来,一方面方便自己查用,一方面也夯实下即将遗忘的回忆。整个过程中我会不断更新,直到不能再加为止,同时,这里只记录最实用的咚咚,不效仿学院派的那一套。

 

一、常用SQL语句荟萃

1,查询:

1.1,简单查询:select * from table where

1.2,连接查询:

什么是连接查询?顾名释义,就是查询时涉及多个表的查询。是以说到连接,废话一下,要知道连接还是关系数据库的主要特点呢。

连接查询分为三种:外连接(OUTER JOIN),内连接(INNER JOIN),交叉连接(CROSS JOIN)。

(标准化越来越近了):namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1.2.1,内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

1.2.2,外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。

1.2.3,交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。

1.2.4,无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info
FROM pub_info AS p1 INNER JOIN pub_info AS p2
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

1.2.5,使用WHERE子句设置查询条件

WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:

SELECT *

FROM usertable

WHERE age>20

WHERE子句可包括各种条件运算符:

比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!<

范围运算符(表达式值是否在指定的范围):BETWEEN…AND…

NOT BETWEEN…AND…

列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……)

NOT IN (项1,项2……)

模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE

空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL

逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR

1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30

2、列表运算符例:country IN ('Germany','China')

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、varchar、text、ntext、datetime和smalldatetime等类型查询。

可使用以下通配字符:

百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。

下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。

方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。

例如:

限制以Publishing结尾,使用LIKE '%Publishing'

限制以A开头:LIKE '[A]%'

限制以A开头外:LIKE '[^A]%'

空值判断符例:WHERE age IS NULL

2,更新:update table

 

3,插入:

3.1,一般插入:

INSERT INTO publishers
(pub_id, pub_name, city, state)
VALUES
('9001', 'Acme Publishing', 'New York', 'NY')

3.2,插入多行

使用 INSERT 语句可以向表添加多行数据。这些多行数据是从已经存有这些数据的另一个表中选取的。本例中,向 pubhold 表中添加有关在加利福尼亚和德克萨斯州的出版商的数据。这些数据可从 publishers 表中获得。

INSERT pubhpold SELECT * FROM publishers
WHERE state = 'CA' OR state = 'TX'

 

4,删除:

4.1,Delete语句联合删除:

DELETE FROM uu_SuiteToMinClassroomSect

WHERE min_classroom_sect_id IN

   (SELECT min_classroom_sect_id

   FROM uu_MinClassroomSect

   WHERE min_classroom_id = '112')

二、视图使用细则

1,一个典型的视图

CREATE VIEW View_uuGroupTaxis

AS

SELECT uu_GroupInfo.group_id, uu_GroupInfo.group_name,

      uu_GroupType.main_type, uu_GroupType.group_type_name,

      uu_GroupInfo.group_icon_url, ISNULL

          ((SELECT COUNT(*)

          FROM uu_GroupUser

          WHERE uu_GroupInfo.group_id = uu_GroupUser.group_id), 0)

      * 50 + ISNULL(uu_GroupInfo.fundCount, 0) + ISNULL

          ((SELECT COUNT(*)

          FROM Dv_Topic

          WHERE Dv_Topic.BoardID = uu_GroupInfo.subforum_id), 0) * 5 + ISNULL

          ((SELECT COUNT(*)

          FROM uu_GroupPhotos

          WHERE uu_GroupPhotos.group_id = uu_GroupInfo.group_id), 0)

      * 10 + ISNULL(uu_GroupInfo.topic_account, 0)

      * 2 + ISNULL(uu_GroupInfo.hit_account, 0) AS group_ActiveDegree,

      ISNULL

          ((SELECT COUNT(*)

          FROM uu_GroupUser

          WHERE uu_GroupInfo.group_id = uu_GroupUser.group_id), 0)

      AS group_memberNum, ISNULL(uu_GroupInfo.fundCount, 0) AS fundCount,

          (SELECT COUNT(*)

         FROM Dv_Topic

         WHERE Dv_Topic.BoardID = uu_GroupInfo.subforum_id) AS group_articleNum,

          (SELECT COUNT(*)

         FROM uu_GroupPhotos

         WHERE uu_GroupPhotos.group_id = uu_GroupInfo.group_id) AS group_PhotoNum,

      uu_GroupInfo.topic_account, uu_GroupInfo.hit_account,

          (SELECT user_name

         FROM uu_RegisterUser

         WHERE uu_RegisterUser.user_id = uu_GroupInfo.creator_id)

      AS group_CreatorName, uu_GroupInfo.create_time

FROM uu_GroupInfo INNER JOIN

      uu_GroupType ON

      uu_GroupInfo.group_type_id = uu_GroupType.group_type_id

三,存储过程的创建和调用

1,存储过程的调用

Execute procedureName @param=’value’

2,一个典型的带参数存储过程

CREATE PROCEDURE P_delMiniclassProc

@miniClassroom_id int

AS

declare @billtag varchar(4)

set nocount on

IF @miniClassroom_id is null

         begin

                   return(-1)

         end

else

                   BEGIN TRANSACTION

                   --删除套餐信息

                   DELETE FROM uu_SuiteToMinClassroomSect

                   WHERE min_classroom_sect_id IN

                      (SELECT min_classroom_sect_id

                      FROM uu_MinClassroomSect

                      WHERE min_classroom_id =@miniClassroom_id)

                   --删除小课堂段信息

                   delete from uu_MinClassroomSect

                   where min_classroom_id = @miniClassroom_id

                   --删除小课堂用户购买记录

                   delete from uu_UserBuyMinClassroom

                   where min_classroom_id = @miniClassroom_id

                   --删除对应小课堂年级学科信息

                   delete from uu_MinClassroomToGradeClass

                   where min_classroom_id = @miniClassroom_id

                   --删除小课堂发言

                   delete from uu_MinClassroomDiscuss

                   where min_classroom_id = @miniClassroom_id

                   --删除课程讨论

                   DELETE FROM uu_CourseDiscuss

                   WHERE course_id IN

                      (SELECT course_id

                      FROM uu_CourseInfo

                      WHERE min_classroom_id = @miniClassroom_id)

                   --删除用户课程收藏

<
SQL语句的优化是将性能低下的SQL语句转换成目的相同的性能优异的SQL语句。

  人工智能自动SQL优化就是使用人工智能技术,自动对SQL语句进行重写,从而找到性能最好的等效SQL语句。

  数据库性能的优化


  一个数据库系统的生命周期可以分成:设计、开发和成品三个阶段。在设计阶段进行数据库性能优化的成本最低,收益最大。在成品阶段进行数据库性能优化的成本最高,收益最小。

  数据库的优化通常可以通过对网络、硬件、操作系统、数据库参数和应用程序的优化来进行。最常见的优化手段就是对硬件的升级。根据统计,对网络、硬件、操作系统、数据库参数进行优化所获得的性能提升,全部加起来只占数据库系统性能提升的40%左右,其余的60%系统性能提升来自对应用程序的优化。许多优化专家认为,对应用程序的优化可以得到80%的系统性能的提升。

  应用程序的优化

  应用程序的优化通常可分为两个方面:源代码和SQL语句。由于涉及到对程序逻辑的改变,源代码的优化在时间成本和风险上代价很高,而对数据库系统性能的提升收效有限。

  为什么要优化SQL语句

  . SQL语句是对数据库进行操作的惟一途径,对数据库系统的性能起着决定性的作用。

  . SQL语句消耗了70%至90%的数据库资源。

  . SQL语句独立于程序设计逻辑,对SQL语句进行优化不会影响程序逻辑。

  . SQL语句有不同的写法,在性能上的差异非常大。

  . SQL语句易学,但难精通。

  优化SQL语句的传统方法是通过手工重写来对SQL语句进行优化。DBA或资深程序员通过对SQL语句执行计划的分析,依靠经验,尝试重写SQL语句,然后对结果和性能进行比较,以试图找到性能较佳的SQL语句。这种传统上的作法无法找出SQL语句的所有可能写法,且依赖于人的经验,非常耗费时间。

  SQL优化技术的发展历程

  第一代SQL优化工具是执行计划分析工具。这类工具针对输入的SQL语句,从数据库提取执行计划,并解释执行计划中关键字的含义。

  第二代SQL优化工具只能提供增加索引的建议,它通过对输入的SQL语句的执行计划的分析,来产生是否要增加索引的建议。

  第三代SQL优化工具不仅分析输入SQL语句的执行计划,还对输入的SQL语句本身进行语法分析,经过分析产生写法上的改进建议。

  人工智能自动SQL优化

SQL语句性能优化--LECCO SQL Expert
图1 人工智能自动SQL优化示意图

  人工智能自动SQL优化出现在90年代末。目前在商用数据库领域,LECCO Technology Limited(灵高科研有限公司)拥有该技术,并提供使用该技术的自动优化产品LECCO SQL Expert,它支持Oracle(大型网站数据库平台)、Sybase、MS sql server(WINDOWS平台上强大的数据库平台)和IBM DB2数据库平台。该产品针对数据库应用的开发和维护阶段提供的模块有:SQL语法优化器、PL/SQL集成化开发调试环境(IDE)、扫描器、数据库监视器等。其核心模块SQL 语法优化器的工作原理为:①输入一条源SQL语句;②“人工智能反馈式搜索引擎”对输入的SQL语句,结合检测到的数据库结构和索引进行重写,产生N条等效的SQL语句输出;③产生的N条等效SQL语句再送入“人工智能反馈式搜索引擎”进行重写,直至无法产生新的输出或搜索限额满;④对输出的SQL语句进行过滤,选出具有不同执行计划的SQL语句;⑤对得到的SQL语句进行批量测试,找出性能最好的SQL语句。

  LECCO SQL Expert自动优化实例

  假设我们从源代码中抽取出这条SQL语句(也可以通过内带的扫描器或监视器获得SQL语句):

  SELECT COUNT(*)

   FROM EMPLOYEE

  swheresEXISTS (SELECT 'X'

   FROM DEPARTMENT

  swheresEMP_DEPT=DPT_ID

   AND DPT_NAME LIKE 'AC%')

  AND EMP_ID IN (SELECT SAL_EMP_ID

   FROM EMP_SAL_HIST B

  swheresSAL_SALARY > 70000)

  按下“优化”按钮后,经过10几秒,SQL Expert就完成了优化的过程,并在这10几秒的时间里重写产生了2267 条等价的SQL语句,其中136条SQL语句有不同的执行计划。

  接下来,我们可以对自动重写产生的136条SQL语句进行批运行测试,以选出性能最佳的等效SQL语句。按下“批运行” 按钮,在“终止条件” 页选择“最佳运行时间SQL语句”,按“确定”。

  经过几分钟的测试运行后,我们可以发现SQL124的运行时间和反应时间最短。运行速度约有22.75倍的提升(源SQL语句运行时间为2.73秒,SQL124运行时间为0.12秒)。现在我们就可以把SQL124放入源代码中,结束一条SQL语句的优化工作了。

  “边做边学式训练”提升SQL开发水平

  LECCO SQL Expert不仅能够找到最佳的SQL语句,它所提供的“边做边学式训练”还能够教开发人员和数据库管理员如何写出性能最好的SQL语句。LECCO SQL Expert的“SQL比较器”可以标明源SQL和待选SQL间的不同之处。

  以上面优化的结果为例,为了查看源SQL语句和SQL124在写法上有什么不同,我们可以按下“比较器” 按钮,对SQL124和源SQL语句进行比较。“SQL 比较器”将SQL124相对于源SQL语句的不同之处以蓝颜色表示了出来。如果选择“双向比较”复选框,“SQL 比较器”可以将两条SQL语句的不同之处以蓝色表示。当然,我们也可以从源语句和重写后的SQL 语句中任选两条进行比较。

  从比较的结果可以看到,重写后的SQL124把第一个Exists改写成了In;在字段DPT_ID上进行了合并空字符串的操作,以诱导数据库先执行子查询中的

  (SELECT DPT_ID||''

  FROM DEPARTMENT

  WHERE DPT_NAME LIKE 'AC%')

  在子查询完成后,再与EMPLOYEE表进行嵌套循环连接(Nested Loop Join)。

  如果觉得对写法的改变难以理解,还可以点中“执行计划”复选框,通过比较两条SQL语句的执行计划的不同,来了解其中的差异。在查看执行计划过程中,如果有什么不明白的地方,可以点中“SQL信息按钮”,再点击执行计划看不明白的地方,LECCO SQL Expert的上下文敏感帮助系统将提供执行计划该处的解释。

  在“SQL比较器”中,选中“统计信息”复选框后,可得到详细的两条SQL语句运行时的统计信息比较,这对于学习不同的SQL写法对数据库资源的消耗很有帮助。

  LECCO SQL Expert优化模块的特点

  LECCO SQL Expert优化模块的特点主要表现为:自动优化SQL语句;以独家的人工智能知识库“反馈式搜索引擎”来重写性能优异的SQL语句;找出所有等效的SQL语句及可能的执行计划;保证产生相同的结果;先进的SQL语法分析器能处理最复杂的SQL语句;可以重写SELECT、SELECT INTO、UPDATE、INSERT和DELETE语句;通过测试运行,为应用程序和数据库自动找到性能最好的SQL语句;提供微秒级的计时,能够优化Web应用程序和有大量用户的在线事务处理中运行时间很短的SQL语句;为开发人员提供“边做边学式训练”,迅速提高开发人员的SQL编程技能;提供上下文敏感的执行计划帮助系统和SQL运行状态帮助;不是猜测或建议,而是独一无二的SQL重写解决方案。

  写出专家级的SQL语句

  LECCO SQL Expert的出现,使SQL的优化变得极其简单,只要能够写出SQL语句,它就能帮用户找到最好性能的写法。LECCO SQL Expert不仅能在很短的时间内找到所有可能的优化方案,而且能够通过实际测试,确定最有效的优化方案。同以往的数据库优化手段相比较,LECCO SQL Expert将数据库优化技术带到了一个崭新的技术高度,依赖人的经验、耗费大量时间、受人的思维束缚的数据库优化手段已经被高效、省时且准确的自动优化软件所取代了。通过内建的“LECCO小助手”的帮助,即使是SQL的开发新手,也能快速且简单地写出专家级的SQL语句。

比如现在有一人员表 (表名:peosons) 
若想将姓名、身份证号、住址这三个字段完全相同的记录查询出来

select   p1.*   from   persons   p1,persons   p2   where   p1.id<>p2.id   and   p1.cardid   =   p2.cardid   and   p1.pname   =   p2.pname   and   p1.address   =   p2.address

可以实现上述效果.

  select语句前加:
declare @d datetime
set @d=getdate()
并在select语句后加:
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())

Transact_SQL小手册

*******************Transact_SQL********************

--语 句                                功 能
--数据操作
SELECT      --从数据库表中检索数据行和列
INSERT      --向数据库表添加新数据行
DELETE      --从数据库表中删除数据行
UPDATE      --更新数据库表中的数据
--数据定义
CREATE TABLE    --创建一个数据库表
DROP TABLE     --从数据库中删除表
ALTER TABLE     --修改数据库表结构
CREATE VIEW     --创建一个视图
DROP VIEW     --从数据库中删除视图
CREATE INDEX    --为数据库表创建一个索引
DROP INDEX     --从数据库中删除索引
CREATE PROCEDURE   --创建一个存储过程
DROP PROCEDURE    --从数据库中删除存储过程
CREATE TRIGGER    --创建一个触发器
DROP TRIGGER    --从数据库中删除触发器
CREATE SCHEMA    --向数据库添加一个新模式
DROP SCHEMA     --从数据库中删除一个模式
CREATE DOMAIN    --创建一个数据值域
ALTER DOMAIN    --改变域定义
DROP DOMAIN     --从数据库中

抱歉!评论已关闭.