精华内容
下载资源
问答
  • Oracle数据库查询之分页查询

    千次阅读 2020-11-20 14:42:02
    在对数据库执行查询操作,有时候会涉及到大量的数据,这些查到的数据如果就显示在同一页页面,过大的数据让人读起来就头疼。试想一下,当我们某度搜索关键字是,如果,某度将查询的结果不进行分页,就一个网页房...

    分页查询

    在对数据库执行查询操作时,有时候会涉及到大量的数据,这些查到的数据如果就显示在同一页页面,过大的数据让人读起来就头疼。试想一下,当我们某度搜索关键字是,如果,某度将查询的结果不进行分页,就一个网页房大量的数据,那将会极大地影响你的使用体验。所以,分页查询在各项目中是很有用的。基于分页查询还可以写一些组合查询并且降低数据库的访问量。
    以一张表为例,如果我们要查前两行数据怎么办?
    这时候要引入一个 rownum(行序号),它是由oracle提供的,动态生成的,并不是表种存在的,生成时间为执行sql之时;并且试讲查询结果生成行序号。默认从1开始; 记录的是 select查询结果集的序号, 有1才2, 有2才3 有3才4…它的值只能是小于等于或小于某个数,不能大于或等于。我们可以这样查

    select * from 表名 where rownum<=2;
    select * from 表名 where rownum<2;
    

    在这里插入图片描述
    在这里插入图片描述但是如果查大于,都会查不到
    在这里插入图片描述
    在这里插入图片描述

    在知道这个概念之后,我们可也以进行分页查询了。
    分页的逻辑:
    需要知道当前页的页码通常记为 pageIndex
    和容量 记为pageSize
    总记录数 也就是查询结果的总行数
    总页数要通过计算
    总页数=总记录数%页容量==0?总记录数%页容量:总记录数%页容量+1。
    -------------------------------------------------------------------------
    先举个例子 假设一张 stu表 有18行数据,现在想要每五行数据为一页进行查询
    分析:页容量pageSize=5

    		开始序号     结束序号
    第一页	   1	       5  
    第二页	   6           10
    第三页	   11          15
    第四页	   16          20
    数据不可能每次都满足存满,对于这张表,行数到18就结束了 
    由此可知 每一页的开始序号为 (pageIndex-1)*pageSize+1
    	    结束序号为    pageSize*pageInde
    查第一页:
    select * from stu where rownum <=5;
    查第二页
    select * from stu where rownum <=10 and rownum>=6;
    此时该查询语句并不会查到结果。我们需要将两个查询语句嵌套使用。
    把荣威num的值固定下来
    select * ,rownum rn from stu
    

    在这里插入图片描述

    第一页
    select * from (select * ,rownum rn from stu )t
    where t.rn>=1 and t.rn<=5;
    第二页
    select * from (select * ,rownum rn from stu )t
    where t.rn>=5 and t.rn<=10;
    

    以此类推 查第三页、第四页,但是这样的话,每次都要先执行,(select * ,rownum rn from stu )t ,把整张表结果查一遍,效率并不高。
    因此,还可以优化sql语句,思路就是将结束序号的条件放入子查询语句中,这样子查询只用查到结束位置而不用讲整张表都查一遍。
    (给列取别名是不能直接在该语句中使用的)

    --查第二页
    select t.* from
    (select s.* ,rownum rn from stu s where rownum<=10)t
    where t.rn>=6
    

    但是这样还有一个缺点,那就是不能进行排序,- 排序, 一定使用三层子查询, 三层子查询所有情况都能使用的。

    执行顺序,先对整张表排序,再分页,依然以查询第二页为例

    select t.* from
    	(select e.*,rownum rn from
    		(select * from stu order by id)e
    	 where rownum<=10)t
    where t.rn>=6;
    

    最推荐的 三层子查询

    select t.* from
    	(select e.*,rownum rn from
    		(select * from stu order by id)e
    	 where rownum<=(pageIndex*pageSize))t
    where t.rn>=(pageIndex-1*pageSize+1;
    
    展开全文
  • DM达梦数据库--查询优化

    千次阅读 2020-05-18 18:27:54
    查询 优化器分析语句运行的所有因素,选择最优的方式去执行,提高了查询效率。因此,查询 优化数据库执行SQL语句的重要过程,决定了数据库查询性能。 1、优化目标 达梦数据库查询优化器的优化目标为最快响应...

    数据库执行一条语句有多种方式,为了选择最优的执行方式,产生了查询优化器。查询 优化器分析语句运行时的所有因素,选择最优的方式去执行,提高了查询效率。因此,查询 优化是数据库执行SQL语句的重要过程,决定了数据库的查询性能。
    1、优化目标
    达梦数据库查询优化器的优化目标为最快响应时间。通过设置参数FIRST_ROWS来决 定优先返回多少条记录给用户,而不需要等待全部结果确定后再输出,FIRST_ROWS设置 范围为1~1000,单位为行。例如:FIRST_ROWS = 10,意思是查询出10条结果就立即 返回给用户。可以根据实际情况,调整参数值。
    2、查询优化器
    查询优化器通过分析可用的执行方式和查询所涉及的对象统计信息来生成最优的执行 计划。此外,如果存在HINT优化提示,优化器还需要考虑优化提示的因素。
    查询优化器的处理过程包括:
    1.优化器生成所有可能的执行计划集合;
    2. 优化器基于字典信息的数据分布统计值、执行语句涉及到的表、索引和分区的存储 特点来估算每个执行计划的代价。代价是指SQL语句使用某种执行方式所消耗的 系统资源的估算值。其中,系统资源消耗包括I/O、CPU使用情况、内存消耗等;
    3. 优化器选择代价最小的执行方式作为该条语句的最终执行计划。
    优化器所做的操作有:查询转换、估算代价、生成计划
    1>查询转换
    查询转换是指把经过语法、语义分析的查询块之间的连接类型、嵌套关系进行调整,生 成一个更好的查询计划。常用的查询转换技术包括过滤条件的下放、相关子查询的去相关性。
    1.过滤条件下放:在连接查询中,把部分表的过滤条件下移,在连接之前先过滤,可 以减少连接操作的数据量,提升语句性能;
    2. 相关子查询的去相关性:把与子查询相关的外表与内表采用半连接的方式执行,放 弃默认采取的嵌套连接方式,对性能有较大提升。
    2>估算代价
    估算代价是指对执行计划的成本进行估算。执行节点之间的代价值相关性较强,一个执 行节点的代价包括该节点包含的子节点代价。代价衡量指标包括选择率、基数、代价。 选择率是指满足条件的记录占总记录数的百分比。记录集可以是基表、视图、连接或分
    组操作的结果集。选择率和查询谓词相关,如name =‘韩梅梅’;或者是谓词的连接,如 name ='韩梅梅’and no =‘0123’。一个谓词可以看作是一个过滤器,过滤掉结果集中 不满足条件的记录。选择率的范围从0到1。其中,0表示没有记录被选中,1表示行集中 所有记录都被选中。
    如果没有统计信息,则优化器依据过滤条件的类型来设置对应的选择率。例如,等值条 件的选择率低于范围条件选择率。这些假定是根据经验值,认为等值条件返回的结果集最少。
    如果有统计信息,则可以使用统计信息来估算选择率。例如,对于等值谓词(name =‘韩 梅梅’),如果name列有N个不同值,那么,选择率是N分之一。
    基数是指整个行集的行数,该行集可以是基表、视图、连接或分组操作的结果集。 代价表示资源的使用情况。查询优化器使用磁盘I/O、CPU占用和内存使用作为代价 计算的依据,所以代价可以用I/O数、CPU使用率和内存使用一组值来表示。所有操作都 可以进行代价计算,例如扫描基表、索引扫描、连接操作或者对结果集排序等。
    访问路径决定了从一个基表中获取数据所需要的代价。访问路径可以是基表扫描、索引 扫描等。在进行基表扫描或索引扫描时,一次I/O读多个页,所以,基表扫描或索引全扫 描的代价依赖于表的数据页数和多页读的参数值。二级索引扫描的代价依赖于B树的层次、 需扫描的叶子块树以及根据rowid访问聚集索引的记录数。
    连接代价是指访问两个连接的结果集代价与连接操作的代价之和。
    3、生成计划
    生成计划指计划生成器对给定的查询按照连接方式、连接顺序、访问路径生成不同的执 行计划,选择代价最小的一个作为最终的执行计划。
    连接顺序指不同连接项的处理顺序。连接项可以是基表、视图、或者是一个中间结果集。 例如表t1、t2、t3的连接顺序是先访问t1,再访问t2,然后对t1与t2做连接生成结 果集r1,最后把t3与r1做连接。一个查询语句可能的计划数量是与FROM语句中连接项 的数量成正比的,随着连接项的数量増加而増加。
    4、连接
    查询语句中FROM子句包含多个表时,我们称为连接查询。如SELECT * FROM t1,t2 就是连接查询。
    生成连接查询的执行计划,需要考虑三方面因素:
    1.访问路径
    对于每张表米用何种方式来获取数据。例如:全表扫描、索引扫描等。
    查询优化器会估算每种扫描方式的代价,选择代价较小的访问路径。
    2.连接方式
    确定两张表之间采用哪种连接方式。例如:哈希连接、嵌套连接、归并连接、外连接。
    等值连接条件一般会选择哈希连接;非等值连接条件会采用嵌套连接;连接列均为索引 列时,会采用归并连接。
    1)嵌套连接:两张表进行非等值连接时会选择嵌套连接。相当于两张表进行笛卡尔集 操作。此时,优化器会选择一张代价较小的表作为外表(驱动表),另一张表作为内表,外 表的每条记录与内表进行一次连接操作。
    2)哈希连接:两张表进行等值连接时会选择哈希连接。以一张表的连接列为哈希键, 构造哈希表,另张表的连接列进行哈希探测,找到满足条件的记录。由于哈希命中率高,因 此,在大数据量情况下,哈希连接的效率较高。哈希连接的代价是建立哈希表和哈希探测的 代价。
    3)归并连接:两张表的连接列均为索引列,则可以按照索引顺序进行归并,一趟归并 就可以找出满足条件的记录。如果查询列也属于索引列的子集,则归并连接只需扫描索引, 会有更好的性能表现。在两表连接条件不是等值(如<,<=,>,>=)情况下时,归并排序 连接很有用。
    4)外连接:外连接分为左外连接、右外连接、全外连接。作为外表的数据会全部返回, 如果没有与外表匹配的记录,则填充NULL值。右外连接与左外连接的处理过程类似,只是 外表不同,一个是左表,一个是右表。全外连接是进行左外连接和右外连接,返回两次外连 接的union结果集。
    例1:左外连接:*
    SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.c1=t2.d1;
    例1中t1表为外表(左表),如果t2表中不存在与t1.c1相等的记录,
    则t2表的该行记录用NULL填充。右外连接与左外类似。
    例2:全外连接*
    SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.c1=t2.d1;
    例2中分别以t1为左表进行左外和右外连接,两次结果进行union,返回最终结果。
    子查询会转换成半连接。共有四种半连接方式:哈希半连接、索引半连接、嵌套半连接、 归并半连接。等值连接条件会选择哈希\索引\归并半连接,非等值连接条件会选择嵌套半连接。
    1)哈希半连接:以外表的连接列为KEY构造哈希表,内表的连接列进行探测来查找 满足连接条件的记录;
    2)索引半连接:如果子查询的连接列为索引前导列,可采用索引半连接。处理过程为 外表的数据对子查询使用索引查找,返回满足条件的记录;
    3)归并半连接:如果相关子查询的连接条件列均为索引列,可采用归并半连接。按照 索引顺序,对外表、内表进行同步扫描,返回满足条件的记录;
    4)嵌套半连接:如果连接条件为非等值,可转换为嵌套半连接。处理过程为外表的每 条记录去遍历内表,返回满足条件的记录。
    3.连接顺序
    当超过2张表进行连接时,就需要考虑表之间的连接顺序。不合适的连接顺序对执行 效率有较大影响。一般原则是,经过连接可以产生较小结果集的表优先处理。
    一个连接查询通常会对应多个执行计划,查询优化器会根据优化规则、代价估算挑选最 优的执行计划。
    5、统计信息
    对象统计信息描述数据是如何在数据库中存储的。统计信息是优化器的代价计算的依 据,可以帮助优化器较精确地估算成本,对执行计划的选择起着至关重要的作用。
    达梦数据库的统计信息分三种类型:表统计信息、列统计信息、索引统计信息。通过直 方图来表示。统计信息生成过程分以下三个步骤:
    1.确定采样的数据:根据数据对象,确定需要分析哪些数据。
    1)表:计算表的行数、所占的页数目、平均记录长度
    2)列:统计列数据的分布情况
    3)索引:统计索引列的数据分布情况
    2.确定采样率
    根据数据对象的大小,通过内部算法,确定数据的采样率。采样率与数据量成反比。
    3.生成直方图
    有两种类型的直方图:频率直方图和等高直方图。根据算法分析表的数据分布特征, 确定直方图的类型。频率直方图的每个桶(保存统计信息的对象的高度不同,等高 直方图每个桶的高度相同。例如,对列生成统计信息,当列值分布比较均匀时,会采用等高直方图,否则,采用频率直方图。
    在执行查询时,如果数据对象存在统计信息,代价算法可以根据统计信息中的数据,比 较精确地计算出操作所需花费的成本,以此来确定连接方式、对象访问路径、连接顺序,选 择最优的执行计划。
    用户也可以通过修改OPTIMIZER_DYNAMIC_SAMPLING参数值在缺乏统计信息时进 行动态统计信息收集。
    6、执行查询
    执行计划是SQL语句的执行方式,由查询优化器为语句设计的执行方式,交给执行器
    去执行。在SQL命令行使用EXPLAIN可以打印出语句的执行计划 例如:
    建表和建索引语句:
    CREATE TABLE T1 (C1 INT,C2 CHAR);
    CREATE TABLE T2 (D1 INT,D2 CHAR);
    CREATE INDEX IDX T1 C1 ON T1(C1);
    INSERT INTO T1 VALUES(1,‘A’);
    INSERT INTO T1 VALUES(2,‘B’);
    INSERT INTO T1 VALUES(3,‘C’);
    INSERT INTO T1 VALUES(4,‘D’);
    INSERT INTO T2 VALUES(1,‘A’);
    INSERT INTO T2 VALUES(2,‘B’);
    INSERT INTO T2 VALUES(5,‘C’);
    INSERT INTO T2 VALUES(6,‘D’);
    打印执行计划:
    EXPLAIN SELECT A.C1+1,B.D2 FROM T1 A, T2 B WHERE A.C1 = B.D1;
    执行计划如下:
    1 #NSET2: [0,16,9]
    2 #PRJT2: [0,16,9]; EXP NUM(2), IS ATOM(FALSE)
    3 #NEST LOOP INDEX JOIN2: [0,16,9]
    4 #CSCN2: [0,4,5] ;INDEX33555535(B)
    5 #SSEK2: [0,4,0] ;SCAN TYPE(ASC), IDX T1 C1 (A),
    SCAN RANGE[T2.D1,T2.D1]
    这个执行计划看起来就像一棵树,执行过程为:控制流从上向下传递,数据流从下向上 传递。其中,类似[0,16,9]这样的三个数字,分别表示估算的操作符代价、处理的记录 行数和每行记录的字节数。同一层次中的操作符,如本例中的CSCN和SSEK由父节点NEST LOOP INDEX JOIN控制它们的执行顺序。
    该计划的大致执行流程如下:
    1)CSCN2:扫描T2表的聚集索引,数据传递给父节点索引连接;
    2)NEST LOOP INDEX JOIN2:当左孩子有数据返回时取右侧数据;
    3)SSEK:利用T2表当前的D1值作为二级索引IDX_T1_C1定位查找的KEY,返回 结果给父节点;
    4)NEST LOOP INDEX JOIN2:如果右孩子有数据则将结果传递给父节点PRJT2,否则继续取左孩子的下一条记录;
    5)PRJT2:进行表达式计算C1+1, D2;
    6)NSET2:输出最后结果;
    7)重复过程1) ~ 4)直至左侧CSCN2数据全部取完。
    用户如果想了解更多关于操作符的知识,请查看动态视图V$SQL_NODE_NAME,手册 的附录4给出了常用操作符的说明。
    为了提高查询效率,用户一般会在表中创建索引。查询中的条件列为索引列时,如果索 引扫描代价最小,优化器就会采用索引扫描。索引扫描有多种方式,例如,索引等值查询、 索引范围查询。如果查询列属于索引列的子集,则通过索引扫描就可以获得数据,否则,还 需要根据ROWID或者PK在聚集索引中定位记录。
    7、查询计划重用
    如果同一条语句执行频率较高,或者每次执行的语句仅仅是常量值不同,则可以考虑使 用计划重用机制。避免每次执行都需要优化器进行分析处理,可以直接从计划缓存中获取己 有的执行计划,减少了分析优化过程,提高执行率。
    对于计划重用,达梦数据库提供了 INI参数USE_PLN_POOL来控制,当置为1时,会 启用计划重用。
    8、结果集重用
    执行计划的生成与优化是一个非常依赖CPU的操作,而执行一个查询获得结果集也是一 个非常消耗资源的操作。当系统连续执行两个完全相同的SQL语句,其执行计划和结果集很 有可能是相同的,如果重新生成和执行计划,会大大浪费系统资源。这时如果使用计划重用 和结果集重用,系统的响应速度可以大大提升。
    结果集重用是基于计划重用的,如果查询的计划不能缓存,则其查询结果集必然不能缓 存。此外,当语句的游标属性为FORWARD ONLY时,默认查询不会生成结果集。而参数 BUILD_FORWARD_RS可以强制在此类查询中生成结果集,以便进行结果集重用。
    可通过设置INI参数RS_CAN_CACHE来控制结果集重用。当置为0时表示手动模式 (MANUAL),在此模式下默认不缓存查询结果集,但是DBA可以通过语句提示等方法指示系 统对必要的查询结果集进行缓存;置为1时表示强制模式(FORCE),在此模式下默认缓存 所有可缓存结果集,但是DBA也可以通过新増的配置参数以及语句提示等方法取消某些不合 适的结果集缓存。
    当RS_CAN_CACHE为1时,还可以通过设置INI参数RS_CACHE_TABLES和 RS_CACHE_MIN_TIME对缓存的结果集进行限制和过滤。RS_CACHE_TABLES指定可以缓 存结果集的基表清单,只有查询涉及的所有基表全部在参数指定范围内,此查询才会缓存结 果集。RS_CACHE_MIN_TIME则指定了缓存结果集的查询语句执行时间的下限,只有实际执 行时间不少于指定值的查询结果集才会缓存。
    DBA 可以通过在 SQL 语句中设置 “RESULT_CACHE” 或 “NO_RESULT_CACHE” HINT 手动指示查询的结果集是否缓存。如:
    select / *+ RESULT CACHE */ id, name from sysobjects;
    或者
    select / *+ NO_RESULT_CACHE */ id, name from sysobjects;
    在语句中使用HINT指定结果集缓存的优先级要高于INI中相关参数的设置。
    还可以使用系统过程SP_SET_PLN_RS_CACHE来强制设置指定计划结果集缓存的生效 及失效。这个系统过程对结果集缓存的指定高于其它所有结果集缓存的设置。
    在以下情况下,DM不支持结果缓存:
    1.必须是单纯的查询语句计划,PL脚本中包含查询语句也不能缓存结果集。
    2.查询语句的计划本身必须是缓存的。
    3.守护环境中的备机不支持结果集缓存。
    4.MPP等集群环境下不支持结果集缓存(3、4两点限制都是因为无法精确控制基表 的数据更新时戳)。
    5.查询语句中包含以下任意一项,其结果集都不能缓存:
    1)包含临时表;
    2)包含序列的CURVAL或NEXTVAL;
    3)包含非确定的SQL函数或包方法(现有逻辑是不支持所有SQL函数或包方法);
    4)包含RAND、SYSDATE等返回值实时变化的系统函数;
    5)包含其它的一些实时要素。

    展开全文
  • 提高数据库查询速度的优化方法

    千次阅读 2019-06-06 10:08:16
    2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id ...

     

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

    2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

    3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num is null

    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

    select id from t where num=0

    4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num=10 or num=20

    可以这样查询:

    select id from t where num=10

    union all

    select id from t where num=20

     

    5.下面的查询也将导致全表扫描:(不能前置百分号)

    select id from t where name like ‘%abc%’

    若要提高效率,可以考虑全文检索。

     

    6.in 和 not in 也要慎用,否则会导致全表扫描,如:

    select id from t where num in(1,2,3)

    对于连续的数值,能用 between 就不要用 in 了:

    select id from t where num between 1 and 3

     

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

    select id from t where num/2=100

    应改为:

    select id from t where num=100*2

     

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

    select id from t where substring(name,1,3)=’abc’–name以abc开头的id

    select id from t where datediff(day,createdate,’2005-11-30′)=0–’2005-11-30′生成的id

    应改为:

    select id from t where name like ‘abc%’

    select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′

     

    10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

     

    11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使 用,并且应尽可能的让字段顺序与索引顺序相一致。

     

    12.不要写一些没有意义的查询,如需要生成一个空表结构:

    select col1,col2 into #t from t where 1=0

    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

    create table #t(…)

     

    13.很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)

    用下面的语句替换:

    select num from a where exists(select 1 from b where num=a.num)

     

    14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

     

    15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

     

    16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

     

    17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

     

    18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

     

    19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

     

    20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

     

    21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

     

    22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使 用导出表。

     

    23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

     

    24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

     

    25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

     

    26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

     

    27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

     

    28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

     

    29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

     

    30.尽量避免大事务操作,提高系统并发能力。

     

    查询速度慢的原因:

     

    1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)

     

    2、I/O吞吐量小,形成了瓶颈效应。

     

    3、没有创建计算列导致查询不优化。

     

    4、内存不足

     

    5、网络速度慢

     

    6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)

     

    7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)

     

    8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。

     

    9、返回了不必要的行和列

     

    10、查询语句不好,没有优化

     

    可以通过如下方法来优化查询

     

    1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.

     

    2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)

     

    3、升级硬件

     

    4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段

     

    5、提高网速;

     

    6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。

     

    7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个 任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。

     

    8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

     

    9、DB Server 和APPLication Server 分离;OLTP和OLAP分离

     

    10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据 库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件'分区视图')

    a、在实现分区视图之前,必须先水平分区表

    b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务 器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明 的。

     

    11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。 在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的:

    1、 查询语句的词法、语法检查

    2、 将语句提交给DBMS的查询优化器

    3、 优化器做代数优化和存取路径的优化

    4、 由预编译模块生成查询规划

    5、 然后在合适的时间提交给系统处理执行

    6、 最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

     

    12、Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。

     

    13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

     

    14、SQL的注释申明对执行没有任何影响

     

    15、尽可能不使用游标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变 量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性 可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。

    有四个并发选项

    READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。

    OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新 某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获 取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。 选择这个并发选项OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有 所更改。

    在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需 比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。

    SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其 上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下 一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更 新该行。

    然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器 为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关, 则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。

    锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定 未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定 更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。

     

    16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

     

    17、注意UNion和UNion all 的区别。UNION all好

     

    18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

     

    19、查询时不要返回不需要的行、列

     

    20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

     

    21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

     

    22、在SQL2000以前,一般不要用如下的字句 “IS NULL", " <> ", "!=", "!> ", "! <", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。

    也不要在WHere字句中的列名加函数,如 Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1) = 'm'改为WHERE firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。

    NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同 的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而” <> ”等还是不能优化,用不到索引。

     

    23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

     

    24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)

     

    25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

     

    26、MIN() 和 MAX()能使用到合适的索引

     

    27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程 序质量高,并且执行的速度快。

     

    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA是否)。因为这样应用程序首先将二进 制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

     

    29、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。

     

    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

     

    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

     

    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

     

    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生 了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干 扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

     

    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。 SELECT top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345','JCNAD00333138','JCNAD00303570', 'JCNAD00303569','JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933','JCNAD00254567', 'JCNAD00254585','JCNAD00254608','JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618', 'JCNAD00279196','JCNAD00268613') order by postdate desc

     

    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数

     

    36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中SELECT * from sysobjects可以看到 SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

     

    37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快

     

    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好

     

    39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好

     

    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

     

    a、计算字段的表达是确定的

    b、不能用在TEXT,Ntext,Image数据类型

    c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….

     

    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据 库中的 SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数 的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程

     

    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快

     

    43、SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的。

     

    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量 <最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

     

    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现

     

    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。 Process:

     

    1、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。

    2、%Processor Time计数器 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。

    3、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模 式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。

    4、% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。

     

    47、分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使 用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换

     

    附1

    分表分库后解决查询问题:

    使用第三方数据库中间件(MyCat、Sharding-jdbc)实现分表分库的查询

    实现原理:使用数据库中间件向分表分库执行查询,在交给数据库中间件进行整合数据返回给客户端。

    附2

    哪些情况需要创建索引:

    主键自动建立唯一索引

    频繁作为查询条件的字段应创建索引

    查询与其他表关联的字段,外键关系建立索引

    查询中排序的字段,排序的字段若通过索引去访问将会大大提高排序速度

    查询中统计或分组的字段

     

    不需要创建索引:

    频繁更新的字段不适合建立索引,因为每次更新不单单是更新记录,还会更新索引

    where条件中用不到的字段不需要创建索引

    表记录太少

    经常增删改的表

    如果某个数据列包含许多重复的内容,为他建立索引就没有太大的实际效果

    展开全文
  • 数据库优化查询方法总结

    千次阅读 2018-11-09 19:17:27
    处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或&lt;&gt;操作符,否则将引擎放弃使用索引而进行全表扫描。 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及...

    处理百万级以上的数据提高查询速度的方法:

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

    2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order_by 涉及的列上建立索引

    3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num is null

    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

    select id from t where num=0

    4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num=10 or num=20

    可以这样查询:

    select id from t where num=10
    
    union all -- Union all实现把前后两个select集合的数据联合起来,组成一个结果集查询输出。
    
    select id from t where num=20

    5.下面的查询也将导致全表扫描:(不能前置百分号)

    select id from t where name like ‘%abc%’

    若要提高效率,可以考虑全文检索。

    6.in 和 not in 也要慎用,否则会导致全表扫描,如:

    select id from t where num in(1, 2, 3)

    对于连续的数值,能用 between 就不要用 in 了:

    select id from t where num between 1 and 3

    7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

    select id from t where num=@num 可以改为强制查询使用索引:

    select id from t with(index(索引名)) where num=@num

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

    select id from t where num/2=100

    应改为:

    select id from t where num=100*2

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

    select id from t where substring(name,1,3)=’abc’–name以abc开头的id

    select id from t where datediff(day,createdate,’2005-11-30′)=0–’2005-11-30′生成的id

    应改为:

    select id from t where name like ‘abc%’

    select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′

    10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使 用,并且应尽可能的让字段顺序与索引顺序相一致。

    12.不要写一些没有意义的查询,如需要生成一个空表结构:

    select col1,col2 into #t from t where 1=0

    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

    create table #t(…)

    13.很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)

    用下面的语句替换:

    select num from a where exists(select 1 from b where num=a.num)

    14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

    15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

    16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

    17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

    21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

    22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使 用导出表。

    23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

    24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

    25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

    26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

    27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

    28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

    29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

    30.尽量避免大事务操作,提高系统并发能力。

    查询速度慢的原因:

    1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)

    2、I/O吞吐量小,形成了瓶颈效应。

    3、没有创建计算列导致查询不优化。

    4、内存不足

    5、网络速度慢

    6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)

    7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)

    8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。

    9、返回了不必要的行和列

    10、查询语句不好,没有优化

    可以通过如下方法来优化查询

    1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.

    2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)

    3、升级硬件

    4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段

    5、提高网速;

    6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。

    7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。

    8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

    9、DB Server 和APPLication Server 分离;OLTP和OLAP分离

    10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件'分区视图')

    a、在实现分区视图之前,必须先水平分区表

    b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。

    11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。 在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的:

    1、 查询语句的词法、语法检查

    2、 将语句提交给DBMS的查询优化器

    3、 优化器做代数优化和存取路径的优化

    4、 由预编译模块生成查询规划

    5、 然后在合适的时间提交给系统处理执行

    6、 最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

    12、Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。

    13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

    14、SQL的注释申明对执行没有任何影响

    15、尽可能不使用游标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性 可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。

    有四个并发选项

    READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。

    OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。 选择这个并发选项?OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。

    在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。

    SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。

    然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。

    锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定 未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定 更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。

    16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

    17、注意UNion和UNion all 的区别。UNION all好

    18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

    19、查询时不要返回不需要的行、列

    20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

    21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

    22、在SQL2000以前,一般不要用如下的字句 “IS NULL", " <> ", "!=", "!> ", "! <", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。

    也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1) = 'm'改为WHERE firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。

    NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而” <> ”等还是不能优化,用不到索引。

    23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

    24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)

    25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

    26、MIN() 和 MAX()能使用到合适的索引

    27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知Java是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

    29、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。

    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。 SELECT top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345','JCNAD00333138','JCNAD00303570', 'JCNAD00303569','JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933','JCNAD00254567', 'JCNAD00254585','JCNAD00254608','JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618', 'JCNAD00279196','JCNAD00268613') order by postdate desc

    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数

    36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中SELECT * from sysobjects可以看到 SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

    37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快

    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好

    39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好

    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

    a、计算字段的表达是确定的

    b、不能用在TEXT,Ntext,Image数据类型

    c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….

    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的 SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程

    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快

    43、SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的。

    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量 <最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现

    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。 Process:

    1、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。

    2、%Processor Time计数器如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。

    3、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。

    4、% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。

    47、分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。

    展开全文
  • 可以通过单表优化、限定数据的范围、表分区、读写分离等方法进行优化。这篇文章主要内容是转载的博主manong,原文传送门 ,然后自己进行了一些修改。单表优化这块方法不是太全可以翻阅我的其它相关博文-----《MySQL...
  • C++编译器优化-返回值优化

    千次阅读 2015-04-25 19:57:05
    当编译器判断出函数的返回值是通过temp返回,就可以将temp对象优化掉,而把在temp身上做的所有操作直接操做于外层的那个匿名临时变量身上,这样最后return所产生的copy操作就可以省掉了。 而在(2)的第二种写法...
  • 数据库查询慢的分析   查询速度慢的原因:   1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)    2、I/O吞吐量小,形成了瓶颈效应。   3、没有创建计算列导致查询优化。  ...
  • 索引是提高数据查询最有效的方法,也是最难全面掌握的技术,因为正确的索引可能使效率提高10000倍,而无效的索引可能是浪费了数据库空间,甚至大大降低查询性能。 索引的管理成本 1、存储索引的磁盘空间 2、...
  • 数据量中的模糊查询优化方案

    万次阅读 2016-09-19 22:21:10
    对工作单使用 like模糊查询时,实际上 数据库内部索引无法使用 ,需要逐条比较查询内容,效率比较低在数据量很多情况下, 提供模糊查询性能,我们可以使用lucene全文索引库技术。本文示例是在SSH框架中进行使用。...
  • 数据库性能优化

    千次阅读 2019-01-18 16:46:45
    1.单机优化 1.1.表结构设计 1.1.1.范式(规范) 什么样的表才是符合3NF (范式) 表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF 1)1NF 1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要...
  • 感谢weixin_39730671的文章,文章原链接:https://blog.csdn.net/weixin_39730671/article/details/111271468 ...6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。 7、锁或者死锁...
  • 一 核心配置文件二实体类三数据库属性配置文件四dao层sql语句映射五测试类(以及工具类)准备工作:配置config文件格式和mapper文件格式(复制到新建的xml文件第一行)或者进行myeclips设置自动生成&lt;?xml ...
  •   一、 mysql分区简介 ...虽然分区技术可以实现很多效果,但其主要目的是为了在特定的SQL操作中减少数据读写的总量以缩减sql语句的响应时间,同时对于应用来说分区完全是透明的。 MYSQL的分区主要有两种形
  • 提高数据库查询速度的方法

    万次阅读 2017-12-25 13:03:42
    处理百万级以上的数据提高查询速度的方法:  1.应尽量避免在 where 子句中使用!=或  2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。  3.应尽量避免在 where ...
  • MySql数据库优化可以从哪几个方面进行?

    万次阅读 多人点赞 2017-05-01 23:44:37
    1、数据库优化可以从以下几个方面进行:2、项目中,优化mysql之前,首先要开启慢查询日志,在分析慢查询日志.1,查看所有日志状态: show variables like '%quer%';2,查看慢查询状态:show variables like 'show%...
  • 比如银行交易流水记录的查询  限盐少许,上实际实验过程,以下是在实验的过程中做一些操作,以及踩过的一些坑,我觉得坑对于读者来讲是非常有用的。 首先:建立一个现金流量表,交易历史是各个金融体系下使用率...
  • sql_isnull对查询结果无返回值的处理

    千次阅读 2018-03-28 16:59:54
    如果查询结果无返回值查询不到数据),可用 case when + count() 进行处理 select isnull((SELECT a.status FROM t_a a WHERE a.id = tc.id AND a.flag = 1),0) SELECT a.status FROM t_a a WHERE a.id = tc....
  • 数据库优化设计方案

    千次阅读 2008-06-19 00:02:00
    数据库优化设计方案本文首先讨论了基于第三范式的数据库表的基本设计,着重论述了建立主键和索引的策略和方案,然后从数据库表的扩展设计和库表对象的放置等角度概述了数据库管理系统的优化方案。 1 引言 数据库优化...
  • sqlserver大批量数据查询优化方式

    千次阅读 2019-01-18 15:50:16
    2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id ...
  • 数据库的海量数据的存储解析

    千次阅读 2021-11-04 19:43:40
    本篇文章会从数据的概念和分类,以及数据的处理思路 及如何使用分区去提高性能,使用分区过后的优缺点。我常用来处理大数据存储问题的分库分表;会解析关系型数据库和nosql数据库的区别及优缺点。 ...
  • 什么是存储过程 如果你接触过其他的编程语言,那么就好理解了,存储过程就像是方法...4.在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程5.可极大地改善SQL语句的性
  • blog.csdn.net/LJFPHP/article/details/84400400一、前言二、关于count的优化三、使用explain获取行数1、关于explain2、关于返回值一、前言这个问题是今天朋友提出来的,关于查询一个1200w的数据表的总行数,用count...
  • 下面是网络中流传最广的一篇sql查询速度慢的原因及解决方法的文章,其对于处理mysql的慢查询有借鉴作用。由于此文转载多次,很难找到最开始的原文链接,就附送本人最先看到此文的链接:...
  • 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死。严重影响业务。 问题前提:老系统,当时设计系统的人...
  • (转)数据库查询速度慢的原因

    千次阅读 2010-11-01 11:32:00
      4、内存不足  5、网络速度慢  6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)  7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,...
  • 数据库查询与视图

    万次阅读 2012-05-28 20:13:03
    第4章 数据库查询和视图 4.1.1 选择列 通过SELECT语句的项组成结果表的列。 ::= SELECT [ ALL |DISTINCT ] [ TOP n [ PERCENT ] [ WITH TIES ] ] { * /*选择当前表或视图的所有列*/ | { table_name |view_...
  • 手上的工作需要实现从数据库查询大量的数据,然后将数据整合进行分页,于是了解使用ForkJoin框架,进行优化 ForkJoin框架 从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成...
  • 优化SQL Server数据库 查询速度慢的原因很多,常见如下几种: 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有创建计算列导致查询优化。 ...
  • mysql的count(*)的优化,获取千万级数据表的总行数

    万次阅读 热门讨论 2018-11-23 17:04:02
    这个问题是今天朋友提出来的,关于查询一个1200w的数据表的总行数,用count(*)的速度一直提不上去。找了很多优化方案,最后另辟蹊径,选择了用explain来获取总行数。 二、关于count的优化 &amp;amp;amp;n
  • MySQL 8.0 中 4 个默认的系统数据库

    千次阅读 2020-06-11 22:11:02
    information_schema 提供了访问数据库数据的各种视图,包括数据库、表、字段类型以及访问权限等; performance_schema 为 MySQL 服务器的运行状态提供了一个底层的监控功能;sys 包含了一系列方便 DBA 和开发...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,027
精华内容 28,410
关键字:

数据库查询时返回值数据优化