当前位置:文档之家› PLSQL程序优化和性能分析方法

PLSQL程序优化和性能分析方法

PLSQL程序优化和性能分析方法
PLSQL程序优化和性能分析方法

1.前言 (3)

1.1目的 (3)

1.2文档说明 (3)

1.3词汇表 (3)

1.4参考资料 (3)

2. PLSQL程序优化原则 (4)

2.1导致性能问题的内在原因 (4)

2.2PLSQL优化的核心思想 (4)

2.3ORACLE优化器 (4)

2.4PLSQL优化 (5)

2.4.1选择最有效率的表名顺序 (5)

2.4.2 WHERE子句中的连接顺序 (6)

2.4.3 SELECT子句中避免使用‘ * ‘ (6)

2.4.4用EXISTS替代IN (6)

2.4.5用NOT EXISTS替代NOT IN (7)

2.4.6用表连接替换EXISTS (7)

2.4.7用EXISTS替换DISTINCT (8)

2.4.8减少对表的查询 (8)

2.4.9避免循环(游标)里面嵌查询 (9)

2.4.10尽量用union all替换union (11)

2.4.11使用DECODE函数来减少处理时间 (11)

2.4.12 group by优化 (11)

2.4.13尽量避免用order by (12)

2.4.14用Where子句替换HAVING子句 (12)

2.4.15使用表的别名(Alias) (12)

2.4.16删除重复记录 (12)

2.4.17 COMMIT使用 (13)

2.4.18减少多表关联 (13)

2.4.19批量数据插入 (13)

2.5索引使用优化 (14)

2.5.1避免在索引列上使用函数或运算 (14)

2.5.2避免改变索引列的类型. (15)

2.5.3避免在索引列上使用NOT (15)

2.5.4用>=替代> (16)

2.5.5避免在索引列上使用IS NULL和IS NOT NULL (16)

2.5.6带通配符(%)的like语句 (16)

2.5.7总是使用索引的第一个列 (17)

2.5.8多个平等的索引 (17)

2.5.9不明确的索引等级 (17)

2.5.10自动选择索引 (17)

2.5.11使用提示(Hints) (17)

2.5.12表上存在过旧的分析 (18)

2.5.14关于索引建立 (19)

3. PLSQL程序性能问题测试方法 (19)

3.1性能问题分析 (19)

3.2E XP A IN P LA N分析索引使用 (20)

3.3TOPSQL分析 (22)

3.4针对性语句搜索 (26)

3.5后台存储过程跟踪 (27)

3.6性能监控 (28)

4.性能测试工具设计思想 (29)

1. 前言

1.1 目的

性能测试是测试中比较重要的工作,性能测试应分为压力的测试和性能的测试,其中性能问题中绝大部分都是由于程序编写的不合理、不规范造成的。本文档说明了程序中常见的不优化的脚本编写,导致的性能问题,并且在也描述了怎样去跟踪和解决程序上的性能问题的方法。

在最后一章里面描述了做一个白盒测试工具测试性能问题的设计思想。

1.2 文档说明

本文档只说明PLSQL编写的优化问题,不包括ORACLE本身的性能优化(内存SGA、系统参数、表空间等)、操作系统的性能问题和硬件的性能问题。对于PLSQL程序优化方面的内容有很多,本文档列出在我们实际工作中一些常见的情况。本文档难免有不正确的地方,也需要大家给予指正。

本文档举例说明的问题语句不是实际程序中真正存在的,只是让大家能看起来更容易理解,但这些语句也不代表在我们程序中其他部分语句不存在这些问题。

举例说明中的语句采用的是社保核心平台的数据字典,在举例描述中没有标明表名和字段名的含义,还需单独参考。

1.3 词汇表

1.4 参考资料

2. PLSQL程序优化原则

2.1 导致性能问题的内在原因

导致系统性能出现问题从系统底层分析也就是如下几个原因:

●CPU占用率过高,资源争用导致等待

●内存使用率过高,内存不足需要磁盘虚拟内存

●IO占用率过高,磁盘访问需要等待

2.2 PLSQL优化的核心思想

PLSQL优化实际上就是避免出现“导致性能问题的内在原因”,实际上编写程序,以及性能问题跟踪应该本着这个核心思想去考虑和解决问题。

●PLSQL程序占用CPU的情况

?系统解析SQL语句执行,会消耗CPU的使用

?运算(计算)会消耗CPU的使用

●PLSQL程序占用内存的情况

?读写数据都需要访问内存

?内存不足时,也会使用磁盘

●PLSQL程序增大IO的情况

?读写数据都需要访问磁盘IO

?读取的数据越多,IO就越大

大家都知道CPU现在都很高,计算速度非常快;访问内存的速度也很快;但磁盘的访问相对前两个相比速度就差的非常大了,因此PLSQL性能优化的重点也就是减少IO的瓶颈,换句话说就是尽量减少IO的访问。

性能的优先级CPU->内存->IO,影响性能的因素依次递增。根据上面的分析,PLSQL优化的核心思想为:

1.避免过多复杂的SQL脚本,减少系统的解析过程

2.避免过多的无用的计算,例如:死循环

3.避免浪费内存空间没有必要的SQL脚本,导致内存不足

4.内存中计算和访问速度很快

5.尽可能的减少磁盘的访问的数据量,该原则是PLSQL优化中重要思想。

6.尽可能的减少磁盘的访问的次数,该原则是PLSQL优化中重要思想。

下面的章节具体介绍常见影响性能的SQL语句情况。

2.3 ORACLE优化器

ORACLE的优化器:

a. RULE (基于规则)

b. COST (基于成本)

c. CHOOSE (选择性)

设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖.

为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性.

如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器.

在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.

在oracle10g前默认的优化模式是CHOOSE,10g默认是ALL_ROWS,我不建议大家去改动ORACLE的默认优化模式。

2.4 PLSQL优化

主要说明了在SQL编写上和PLSQL程序编写上可以优化的地方。

2.4.1 选择最有效率的表名顺序

只在基于规则的优化器rule中有效,目前我们oracle选择的优化器基本都不选择rule,因此该问题基本不会出现,但为了安全和规范起见,建议编程习惯采用该规则。

ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.

例如:

表ac01有16,384 条记录

表ab01 有1 条记录

选择ab01作为基础表(好的方法)

select count(*) from ac01,ab01 执行时间0.96秒

选择ac01作为基础表(不好的方法)

select count(*) from ab01,ac01 执行时间26.09秒

2.4.2 WHERE子句中的连接顺序

ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE 条件之前

例如:

(低效)

SELECT ab01.aab001,ab02.aab051

FROM ab01,ab02

WHERE ab02.aae140=’31’

AND ab01.aab001=ab02.aab001;

(高效)

SELECT ab01.aab001,ab02.aab051

FROM ab01,ab02

WHERE ab01.aab001=ab02.aab001

AND ab02.aae140=’31’;

2.4.3 SELECT子句中避免使用‘ * ‘

当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*' 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。

2.4.4 用EXISTS替代IN

实际情况看,使用exists替换in效果不是很明显,基本一样。

在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.

低效:

SELECT *

FROM ac01

Where aac001 in (select aac001 from ac02 where aab001=str_aab001 and aae140=’31’);

SELECT *

FROM ac01

Where aac001 in (select distinct aac001 from ac02 where aab001=str_aab001 and aae140=’31’);

注意使用distinct也会影响速度

高效:

SELECT *

FROM ac01

Where exists (select 1 from ac02 where aac001=ac01.aac001 and aab001=str_aab001 and aae140=’31’);

in的常量列表是优化的(例如:aab019 in (‘20’,’30’)),不用exists替换;in列表相当于or

2.4.5 用NOT EXISTS替代NOT IN

Oracle在10g之前版本not in都是最低效的语句,虽然在10g上not in做到了一些改进,但仍然还是存在一些问题,因此我们一定要使用not exists来替代not in的写法。

在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成NOT EXISTS.

例如:

SELECT *

FROM ac01

WHERE aab001 NOT IN (SELECT aab001 from ab01 where aab020=’100’);

为了提高效率.改写为:

SELECT *

FROM ac01

WHERE not exists (SELECT 1 from ab01 where aab001=ac01.aab001 and aab020=’100’);

2.4.6 用表连接替换EXISTS

在子查询的表和主表查询是多对一的情况,一般采用表连接的方式比EXISTS更有效率。

例如:

低效:

SELECT ac01.*

FROM ac01

Where exists (select 1 from ac02

where aac001=ac01.aac001

and aab001=ac01.aab001

and aae140='31'

and aae041='200801');

高效:

SELECT ac01.*

FROM ac02,ac01

Where ac02.aac001=ac01.aac001

and ac02.aab001=ac01.aab001

and ac02.aae140='31'

and aae041='200801';

到底exists和表关联哪种效率高,其实是根据两个表之间的数据量差别大小是有关的,如果差别不大实际上速度基本差不多。

2.4.7 用EXISTS替换DISTINCT

当提交一个包含一对多表信息(比如个人基本信息表和个人参保信息表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXISTS替换

例如:

低效:

select distinct ac01.aac001

from ac02,ac01

where ac02.aac001 = ac01.aac001

and ac02.aae140='31'

and ac01.aab001='100100';

高效:

select ac01.aac001

from ac01

where exists(select 1 from ac02 where aac001 = ac01.aac001

and aae140='31')

and ac01.aab001='100100';

EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。因此如果不是特别研究和追求速度的话(例如:数据转换),查询一个表的数据需要关联其他表的这种情况查询,建议采用EXISTS的方式。

2.4.8 减少对表的查询

该问题是我们编程中出现过的问题,请大家一定注意,并且该类问题优化可以带来较大性能的提升。例如:

低效

cursor cur_kc24_mz is

Select akc260

from kc24

where akb020 =str_akb020

and aka130=’11’;

cursor cur_kc24_zy is

Select akc260

from kc24

where akb020 =str_akb020

and aka130=’21’;

for rec_mz in cur_kc24_mz loop

门诊处理…..

end loop;

for rec_mz in cur_kc24_zy loop

住院处理…..

end loop;

高效

cursor cur_kc24 is

Select akc260,aka130

from kc24

where akb020 =str_akb020

and aka130 in (’11’,’21’);

for rec_kc24 in cur_kc24 loop

if rec_kc24.aka130=’11’ then

门诊处理…..

end if;

if rec_kc24.aka130=’21’ then

住院处理…..

end if;

end loop;

高效的做法使用同样的条件(或者说是索引)只访问一次磁盘,低效的做法访问了2次磁盘,这样速度差别将近2倍。

2.4.9 避免循环(游标)里面嵌查询

游标里面不能嵌入查询(或者再嵌游标),其实也不能有update delete等语句,只能有insert语句。但在实际的编程情况下是不可能完全避免的,但我们一定要尽量避免。该类问题也是我们程序中出现过的问题,该类问题也可以大大提升程序效率,请大家一定注意。

例如:

低效:

Cursor cur_ac04 is

Select aac001,akc010

From ac04

Where aab001= prm_aab001;

……

For rec_ac04 in cur_ac04 loop

Select aac008

Into str_aac008

from ac01

where aac001=rec_ac04.aac001;

if str_aac008=’1’ then

n_jfje := rec_ac04.akc010*0.08;

end if;

if str_aac008=’2’ then

n_jfje := rec_ac04.akc010*0.1;

end if;

End loop;

高效:

Cursor cur_ac04 is

Select ac01.aac001,ac04.akc010,ac01.aac008

From ac04,ac01

Where ac04.aac001=ac01.aac001

and aab001= prm_aab001;

……

For rec_ac04 in cur_ac04 loop

if rec.aac008=’1’ then

n_jfje := rec_ac04.akc010*0.08;

end if;

if rec.aac008=’2’ then

n_jfje := rec_ac04.akc010*0.1;

end if;

end loop;

优化的方法是尽量把游标循环中的查询语句放到游标查询中一起查询出来,这样相当于只访问了1次磁盘读到内存;如果放到游标中的话,假如游标有100万数据量,那么程序需要100万次磁盘,可以想象浪费了多少IO的访问。

如果在程序编写上没有办法避免游标中有查询语句的话(一般情况是可以避免的),那么也要保证游标中的查询使用的索引(即查询速度非常快),例如:游标100万数据量,游标中的查询语句执行需要0.02秒,从这个速度上来说是很快的,但总体上看100万*0.02秒=2万秒=5小时33分钟,如果写一个不够优化的语句需要1秒,那么需要几天能执行完呢?

2.4.10 尽量用union all替换union

Union会去掉重复的记录,会有排序的动作,会浪费时间。因此在没有重复记录的情况下或可以允许有重复记录的话,要尽量采用union all来关联。

2.4.11 使用DECODE函数来减少处理时间

使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.

例如:

(低效)

select count(1) from ac01 where aab001=’100001’ and aac008=’1’;

select count(1) from ac01 where aab001=’100001’ and aac008=’2’;

(低效)

Select count(1),aac008

From ac01

Where aab001=’100001’

and aac008 in (’1’,’2’)

group by aac008;

(高效)

select count(decode(aac008,’1’,’1’,null)) zz,

count(decode(aac008,’2’,’1’,null)) tx

from ac01

where aab001=’100001’;

特别说明:

group by和order by 都会影响性能,编程时尽量避免没有必要的分组和排序,或者通过其他的有效的编程办法去替换,比如上面的处理办法。

2.4.12 group by优化

Group by需要查询后排序,速度慢影响性能,如果查询数据量大,并且分组复杂,这样的查询语句在性能上是有问题的。

尽量避免使用分组或者采用上面的一节的办法去代替。

采用group by的也一定要进行优化。

例如:

低效

select ac04.aac001,ac01.aac002,ac01.aac003,sum(aac040),ac01.aab001

from ac04,ac01

where ac04.aac001=ac01.aac001 and ac01.aab001='1000000370'

group by ac04.aac001,ac01.aac002,ac01.aac003,ac01.aab001;

高效:

select ac04.aac001,ac01.aac002,ac01.aac003,gzze,ac01.aab001

from (select aac001,sum(aac040) gzze from ac04 group by aac001) ac04,ac01

where ac04.aac001=ac01.aac001

and aab001='1000000370';

2.4.13 尽量避免用order by

Order by需要查询后排序,速度慢影响性能,如果查询数据量大,排序的时间就很长。但我们也不能避免不使用,这样大家一定注意一点的是如果使用order by那么排序的列表必须符合索引,这样在速度上会得到很大的提升。

2.4.14 用Where子句替换HA VING子句

避免使用HA VING子句, HA VING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销.

例如:

低效:

SELECT aac008,count(1)

FROM ac01

GROUP BY aac008

HA VING aac008 in (‘1’,’2’);

高效

SELECT aac008,count(1)

FROM ac01

Where aac008 in (‘1’,’2’)

GROUP BY aac008 ;

HA VING 中的条件一般用于对一些集合函数的比较,如COUNT() 等等. 除此而外,一般的条件应该写在WHERE子句中

2.4.15 使用表的别名(Alias)

当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.

2.4.16 删除重复记录

一般数据转换的程序经常会使用到该方法。

最高效的删除重复记录方法( 因为使用了ROWID)

DELETE FROM ac01 a

WHERE a.rowid > (SELECT MIN(b.rowid)

FROM ac01 b

WHERE a.aac002=b.aac002

and a.aac003=b.aac003 );

2.4.17 COMMIT使用

数据转换的程序需要关注这一点。

https://www.doczj.com/doc/d8465349.html,mit执行也是有时间的,不过时间特别短,但提交频率特别大,必然也会浪费时间。

https://www.doczj.com/doc/d8465349.html,mit可以释放资源,在大量数据更新时,必须及时提交。

a. 回滚段上用于恢复数据的信息.

b. 被程序语句获得的锁

c. redo log buffer 中的空间

d. ORACLE为管理上述3种资源中的内部花费

例如:

Cur_ac20有5000万数据

n_count :=0;

For arec in cur_ac20 loop

Insert into ac20 ……

n_count := n_count + 1;

If n_count = = 100000 then --10万一提交

commit;

n_count := 0;

End if;

End loop;

Commit;

如果1条一提交,需要提交5000万必然浪费时间;如果整体提交,资源不能释放,性能必须下降。

在实际编程时,应注意提交的次数和提交的数据量的平衡关系。

2.4.18 减少多表关联

表关联的越多,查询速度就越慢,尽量减少多个表的关联,建议表关联不要超过3个(子查询也属于表关联)。

数据转换上会存在大数据量表的关联,关联多了会影响索引的效率,可以采用建立临时表的办法,有时更能提高速度。

2.4.19 批量数据插入

数据转换时或者大业务数据插入时,有以下几种办法进行数据插入(不包括imp、impdp和sqlloader)

Insert into …select 方式

将查询的结果一次插入到目标表中。

Insert into ac01_bak select * from ac01;

由于是一次查询一次插入,并且最后一次提交,他的速度要比下面描述的curosr的方式速度要快。但查询插入的数据量过大必然会占用更多的内存和undo表空间,只能在插入完成后提交,这样资源不能释放,会导致回滚表空间不足和快照过旧的问题,另外一旦失败需要全部回滚。因此建议小数据量(例如:300万以下)的导入采用该种方式。

●Insert /*+append */ into … select方式

该种方式同上种方式,不过由于有append的提示,这种语句不走回滚段直接插入数据文件,速度非常快。注意系统开发编程不能使用该种方式,数据转换可以灵活使用。

●Cursor方式

定义游标,然后逐行进行插入,然后定量提交。

例如:

Cusor cur_ac20 is

Select * from ac20;

….

n_count :=0;

For rec_ac20 in cur_ac20 loop

Insert into ac20_bak

(aac001,

…….)

V alues

(rec_ac20.aac001,

….);

If n_count :==100000 then

Commit;

n_count :=0;

End if;

End loop;

●批绑定的方式

通过游标查询将数据逐行写到数组里(实际上就是内存),然后通过批绑定的语句forall …in…insert into…values…;将内存的数据一次写入到数据文件中。相比cursor的方式减少了对io的访问次数,提高了速度,但注意内存别溢出了。

2.5 索引使用优化

在实际的应用系统中索引问题导致性能问题可能能占到80%,在程序优化上索引问题是需要我们特别关注的。本节主要描述什么情况索引会不生效。

2.5.1 避免在索引列上使用函数或运算

这个问题是在我们实际编程中出现过的,请大家一定注意。在索引列上使用函数或运算,查询条件都不会使用索引。

例如:

不使用索引

Select * from ka02 where aka060=’10001000’ and to_char(aae030,’yyyymm’)=’200801’;

Select * from ka02 where aka060=’10001000’ and aae030=to_date(’200801’,’yyyymm’);

不使用索引

Select * from ka02 where aka060=’10001000’ and aae031+1=sysdate;

使用索引

Select * from ac04 where aac001=’10001000’ and aae031=sysdate -1;

如果一定要对使用函数的列启用索引, ORACLE新的功能: 基于函数的索引(Function-Based Index)

CREA TE INDEX IDX_KA02_AKA066 ON KA02 (UPPER(AKA066)); /*建立基于函数的索引*/

SELECT * FROM KA02 WHERE UPPER(AKA066) = ‘ASPL’; /*将使用索引*/

不是极特殊情况,建议不要使用。

2.5.2 避免改变索引列的类型.

索引列的条件如果类型不匹配,则不能使用索引。

例如:

不使用索引

Select * from ac01 where aac001=10001000;

使用索引

Select * from ac01 where aac001=’10001000’;

2.5.3 避免在索引列上使用NOT

避免在索引列上使用NOT, NOT不会使查询条件使用索引。对于!=这样的判断也是不能使用索引的,索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中

例如:

低效: (这里,不使用索引)

select *

From ac02

Where not aab019=’10’;

高效: (这里,使用了索引)

select *

From ac02

Where aab019 in (’20’,’30’);

2.5.4 用>=替代>

虽然效果不是特别明显,但建议采用这种方式

低效:

SELECT *

FROM ab01

WHERE aab019 > ‘10’

高效:

SELECT *

FROM ab01

WHERE aab019 >=’20’

两者的区别在于, 前者DBMS首先定位到aab019=10的记录并且向前扫描到第一个aab019大于10的记录,而后者DBMS将直接跳到第一个aab019等于10的记录

2.5.5 避免在索引列上使用IS NULL和IS NOT NULL

对于索引列使用is null或is not null不会使用上索引.因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引.

举例:

低效: (索引失效)

select * from ab01 where aab019 is not null;

高效: (索引有效)

select * from ab01 where aab019 in(‘10’,’20’,’30’);

在实际开发中,对于这类的问题很难避免,如果不是特别影响速度或者要求速度的,可以忽略。

2.5.6 带通配符(%)的like语句

%在常量前面索引就不会使用。

例如:

不使用索引

Select * from ac01 where aac002 like ‘%210104’;

Select * from ac01 where aac002 like ‘%210104%’;

使用索引

Select * from ac01 where aac002 like ‘210104%’;

2.5.7 总是使用索引的第一个列

如果索引是建立在多个列上, 只有在它的第一个列被where子句引用时,优化器才会选择使用该索引。

例如:

Ac02的复合索引:aac001、aae140、aae041

Select * from ac02 where aae140=’31’ and aae041=’200801’; --不会使用索引

Select * from ac02 where aac001=’10001000’; --可以使用索引

如果不使用索引第一列基本上不会使用索引,使用索引要按照索引的顺序使用,另外使用复合索引的列越多,查询的速度就越快

2.5.8 多个平等的索引

当SQL语句的执行路径可以使用分布在多个表上的多个索引时, ORACLE会同时使用多个索引并在运行时对它们的记录进行合并, 检索出仅对全部索引有效的记录.

在ORACLE选择执行路径时,唯一性索引的等级高于非唯一性索引. 然而这个规则只有

当WHERE子句中索引列和常量比较才有效.如果索引列和其他表的索引类相比较. 这种子句在优化器中的等级是非常低的.

如果不同表中两个相同等级的索引将被引用, FROM子句中表的顺序将决定哪个会被率先使用. FROM子句中最后的表的索引将有最高的优先级.

如果同一表中有两个相同等级的索引被引用,oracle会分析最有效的索引去引用,其他的索引不会使用,如果这些相同等级的索引效果差不多,oracle可能会自动合并进行使用。

2.5.9 不明确的索引等级

当ORACLE无法判断索引的等级高低差别,优化器将只使用一个索引,它就是在WHERE子句中被列在最前面的.

2.5.10 自动选择索引

如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性.

在这种情况下,ORACLE将使用唯一性索引而完全忽略非唯一性索引.

2.5.11 使用提示(Hints)

对于表的访问,可以使用两种Hints. FULL 和ROWID

FULL hint 告诉ORACLE使用全表扫描的方式访问指定表.

例如:

SELECT /*+ FULL(AC01) */ *

FROM AC01

WHERE AAC001 = ‘10001000’;

如果一个大表没有被设定为缓存(CACHED)表而你希望它的数据在查询结束是仍然停留

在SGA中,你就可以使用CACHE hint 来告诉优化器把数据保留在SGA中. 通常CACHE hint 和FULL hint 一起使用.

例如:

SELECT /*+ FULL(AC01) CACHE(AC01)*/ *

FROM AC01;

ROWID hint 告诉ORACLE使用TABLE ACCESS BY ROWID的操作访问表.

采用TABLE ACCESS BY ROWID的方式特别是当访问大表的时候, 使用这种方式, 你需要知道ROIWD的值或者使用索引.

索引hint 告诉ORACLE使用基于索引的扫描方式. 你不必说明具体的索引名称

例如:

SELECT /*+index(IDX_AC01_AAC002)*/ aac001

FROM AC01

WHERE aac002='2101111111111111111';

在不使用hint的情况下, 以上的查询应该也会使用索引,然而,如果该索引的重复值过多而你的优化器是CBO, 优化器就可能忽略索引. 在这种情况下, 你可以用INDEX hint强制ORACLE使用该索引.

ORACLE hints 还包括ALL_ROWS, FIRST_ROWS, RULE,USE_NL, USE_MERGE, USE_HASH 等等.

使用hint , 表示我们对ORACLE优化器缺省的执行路径不满意,需要手工修改.

这是一个很有技巧性的工作. 除非特定的情况,例如:数据转换,其他情况最好不用.

2.5.12 表上存在过旧的分析

我们现在很多项目都存在性能问题,其中有很多种情况都是由于分析过旧导致ORACLE判断索引级别和资源成本上出现问题,会导致ORACLE判断错误不使用索引。我个人觉得这是ORACLE不够完善的地方。

解决办法:

第一种办法:删除分析,停止oracle10g的自动分析,但不使用分析,oracle访问数据的CPU消耗就过大。

第二种办法:重新分析,但过长时间后,索引是否会再次失效,没有验证过。

2.5.13 表上存在并行

表上存在并行,ORACLE判断索引级别和资源成本上出现问题,会导致ORACLE判断错误不使用索引。

这个问题我不知道有什么好的处理办法,从现场实际应用速度角度比较,我还是选择去掉并行,因为不使用索引进行全表扫描肯定是不能忍受的。

2.5.14 关于索引建立

索引的使用是肯定会大大提高查询的速度,但索引其实也是一种数据,它也是存放的用户类型的表空间下的,索引建立的越多越大,占用的空间也越大,从用户的环境来说这也不是问题,但如果一个表有过多过大的查询,必然会影响insert、delete和update索引列的速度,因为这些操作改变了整个表的索引顺序,oracle 需要进行调整,这样性能就下降了。因此我们一定要合理的建立好有效的索引,编程也要符合索引的规则,而不能是索引符合编程的规则。

案例:

某项目数据转换,采用游标循环insert的方式,总共2000万的数据,总共用了4个小时,原因就是目标表里面有很多索引。解决方法是先删除索引再执行转换脚本,结果不用1小时就完成了,建立全部的索引不到半个小时。

原因就是第一种方式每次insert都改变索引顺序,共执行改变2000万次,而第二种方式整体上执行索引顺序就一次。

3. PLSQL程序性能问题分析方法

本章主要介绍怎样找到出现性能问题PLSQL程序或语句的方法。

3.1 性能问题分析

出现性能问题,我先要从整体进行分析,一般总体上会有几种现象:

●整个系统运行速度都慢

?在业务不忙的时候,所有模块都慢

?只有在业务繁忙的时候,所有模块都慢

?时快时慢

●个别业务模块运行速度慢

?在业务不忙的时候,该模块就慢

?只有在业务繁忙的时候,该模块才慢

?时快时慢

一般导致系统性能慢的因素:

●硬件:客户端、服务器CPU、内存和存储设备配置不符合应用系统要求

●网络:网速低、丢包

●操作系统参数设置:参数设置不合理

●受到其他软件干扰:例如:防火墙、病毒

●Weblogic设置:参数设置不合理

●Oracle设置:内存、表空间、redolog、系统参数设置不合理等

●PLSQL程序:plsql不优化、未使用索引、锁表

在不同现象下,可能导致性能问题的因素:

1.一般来说,如果在不办理业务的情况下,整个系统性能就慢的话,应该和PLSQL程序优化是没

有关系的。可能的因素为硬件、网络、操作系统、其他软件干扰、ORACLE设置。

2.只有在业务繁忙的时候,整体系统性能都慢,有可能的因素有硬件、操作系统设置、WEBLOGIC

设置、ORACLE设置、PLSQL程序。如果在sqlplus下做查询都慢,那么就和weblogic没有关系。

3.一般来说,如果在不办理业务的情况下,个别业务模块速度就慢的话,那么基本上就是PLSQL

程序不优化或未使用索引造成的。

4.只有在业务繁忙的时候,个别模块慢,有可能的因素有硬件、操作系统设置、WEBLOGIC设置、

ORACLE设置、PLSQL程序、锁表。

这里我们重点是说明PLSQL优化、索引优化的问题,其他例如:硬件、网络、操作系统和oracle设置等因素我们不进行说明。

PLSQL优化、索引不使用的问题产生的影响:

1.对于某段不优化的程序或语句频繁或者全表扫描一个表时,它访问磁盘的时间和占用的吞吐量是

很高的,这就导致系统IO长时间处于忙的状态,导致整个系统性能下降。

2.对于某段不优化的程序或语句频繁或者全表扫描一个表时,其他的业务程序也访问同一个表时,

速度将大大下降。

3.如果是更新表操作时间长,还可能会导致锁等待,导致会话堵塞,weblogic端也出现压力问题,

导致这个系统性能下降。

我们一般根据这些现象、以及一些方法判断,来初步分析产生性能问题的大致原因的范围。不过对于这一点,还是比较困难的,因为产生问题的原因是多种的,并且还有一定的关联。下面的章节介绍我们已经断定是PLSQL优化、索引不使用的问题,我们通过什么方法来具体定位问题。

3.2 Expain Plan分析索引使用

在PL/SQL Developer等工具有一个Expain Plan分析的功能,这个功能可以帮助我们分析SQL语句是否使用了索引、使用哪些索引和使用索引的效果。

1.选择explain plan的窗口

小程序说明

小程序说明 Company Document number:WTUT-WT88Y-W8BBGB-BWYTT-19998

微信小程序介绍 一,产品概述 产品简介 客户丰富场景,持续支持 提供各种行业解决方案,深挖需求,解决行业痛点,持续更新功能,不断提升用户体验 百变魔方,自由组合 提供了更多想象空间,提供了更多运营可能,模块间搭配使用,自由组合,让思路更开阔 独立后台,自主编辑 后台可以对自己账户下面每个小程序进行管理和编辑,小程序端及时更新。 并且方便打包更新审核 资料全面,方便学习 不仅提供图文教学,更有视频教程,方便代理和终端用户快速掌握平台的使用方法和技巧。并且会有更多的成功案例分享,成功运营经验分享 模块概览 图 1 模块概览 二,模块介绍 内容管理 模块介绍

小程序的内容管理系统,主要适用于资讯发布和公告发布板块,可以进行二级分类。支持内容留言、点赞功能。将产品与内容进行深度融合,未来内容营销趋势不可缺少的模块。 图 2 内容管理 微商城 模块介绍 微商城类似于手机淘宝,可实现商品展示,搜索,下单,功能齐全,可通过微信二维码直接进入,支持优惠券,分销管理推广,模块化设置,商家只需简单设置即可拥有自己的商城,省时省力! 图 3 微商城

模块介绍 微名片是基于微信平台的个人商务电子名片,优点在于可在微信聊天窗口里直接分享,并且融入了排名等激励机制,促使用户尽可能多的分享名片,迅速曝光,通过交换个人电子名片可是无限制沉淀自己人脉关系。 图 4 微名片 微拼团 模块介绍 微商拼团是商品营销和售卖的一种方式,通过社交关系链分享传播,可自由设置开团人数,开团价格。用户在分享时,小程序卡片上可以做到实时显示当前的拼团信息,比如已经有多少人参与拼团,现在的价格是多少等,比传统h5 有更好的传播效果。 图 5 微拼团 功能说明

SAP程序性能优化解析

For all entries The for all entries creates a where clause, where all the entries in the driver table are combined with OR. If the number of entries in the driver table is larger than rsdb/max_blocking_factor, several similar SQL statements are executed to limit the length of the WHERE clause. The plus ?Large amount of data ?Mixing processing and reading of data ?Fast internal reprocessing of data ?Fast The Minus ?Difficult to program/understand ?Memory could be critical (use FREE or PACKAGE size Some steps that might make FOR ALL ENTRIES more efficient: ?Removing duplicates from the driver table ?Sorting the driver table ?If possible, convert the data in the driver table to ranges so a BETWEEN statement is used instead of and OR statement: FOR ALL ENTRIES IN i_tab WHERE mykey >= i_tab-low and mykey <= i_tab-high.

智昂小程序商城使用手册

智昂小程序商城使用手册 什么是智昂 智昂基于云服务模式向商户提供强大的小程序商城系统和完整的移动零售解决方案,并致力于为广大商家、消费者提供好用、强大的品牌展示工具。携手智昂小程序商城共掘万亿市场。 企业为什么使用小程序 移动互联网的趋势 据微信官方数据,2017年微信用户数达8.89亿,涵盖各年龄阶层的人群。腾讯自2017年1月份推出微信小程序以来,一直将其作为重点扶持对象,小程序独有的稳定性及兼容性为用户提供了完美流畅的体验。 除此之外,腾讯为小程序开放多个流量入口,打破了以往用户只能通过公众号了解商家的局限。许多商家及开发者纷纷转战小程序市场。 智昂平台优势 操作简洁 智昂小程序商城平台的管理界面简单易用、操作方便,大量人性化设计,一分钟开启微信营销,无需安装任何软件,全自动“云”平台。 功能强大 通过智昂平台,商家可以收集小程序商城日常访客数据、首页装修版块不受限,彻底打破常规手机端商城装修通俗单一的传统,让商家能够更完美的展示品牌价值。 专业团队 一站式管理,平台支持,强大精英团队提供专业的技术支持,专属客服7*12小时实时在线为您提供专业指导。 常见问题 使用智昂小程序商城需要什么条件? 首先您需要注册一个微信小程序账号,并确保其已通过认证,同时开通微信支付功能,如您的商城不需要支付功能,则无需开通微信支付功能。(微信官方收取小程序账号认证服务费为300元/年,微信支付功能服务费为300元/年) 智昂商城是否收取交易手续费? 客户在您商城中交易的一切资金,均为实时直达您的微信账户,智昂小程序商城平台只保证您的交易安全,不做交易干涉,更不收取任何交易手续费。(微信官方收取%0.6资金提现手续费)

营销中心小程序使用说明

营销中心小程序使用说 明 Company number:【WTUT-WT88Y-W8BBGB-BWYTT-19998】

营销中心小程序使用说明 超级顾问 1.名词解释 营销中心小程序:超级顾问为企业客户定制的营销中心,以小程序的形式呈现,目前支持对接驷惠系统的订单管理、优惠券领取与转介绍功能,后续将加入微信会员等级制度,并支持线上充值与消费。 小程序界面截图 展示企业地址与工作时间,点击首图可进入企业介绍页。并提供优惠券领取的列表,客户领取之后可以直接使用。 领取的优惠券会在这里展示 包含已领取优惠券的入口、我的订单和一键导航。 目前我们已对接驷惠系统,凡是企业有安装驷惠系统且将客户信息记录在案,客户下单之后,就能在这里找到自己的订单明细。并且能直接联系客服。如果是主流物流公司配送的订单,比如德邦,会自动同步物流信息。 小程序入口 目前主流入口有四个:发现入口、公众号入口、微信首页入口、线下小程序二维码入口。 打开微信-发现-小程序,进入小程序列表,只会展示你打开过的小程序,根据打开的时间先后顺序排列。 也可以直接通过搜索小程序名字找到对应的小程序,但是有时候会搜索不到。

公众号介绍页和自定义菜单可配置小程序链接,点击即可进入小程序。 在微信首页往下拉会显示最近使用过的小程序,点击即可进入 也可以直接搜索使用过的小程序的名字找到小程序。 从小程序后台获取专属的二维码,制作成海报并彩印出来,张贴在线下门店显眼位置,引导客户扫码进入,这也是最重要的入口。 2.优惠券 添加优惠券 打开超级助理APP点击服务—营销中心—优惠券管理—添加优惠券 编辑优惠券 输入相应的优惠券信息点击提交即可。 优惠券类型分为四种:优惠券、计次券、结伴券和折扣券。 需要注意的是目前推广方式仅支持用户领取 优惠券也可以称之为满减券,是最常用的优惠券类型。可以满足企业营销最基本的需要。比如可设置若干100元的新客体验券,满388减100。 面额:优惠券可抵扣的额度 满元使用:满足多少额度才能使用的限制条件。 推广方式:目前只支持用户领取,后续将支持二维码发放,让客户扫码领取。开始领取时间和结束领取时间:能够领取优惠券的时间,领取之后,即使过了优惠券领取时间,依然可以使用。 生效时间和失效时间:一般生效时间等于领取时间,但失效时间一定要比结束时间晚一点。 领取页面在小程序首页

资兴消费小程序操作指南商户端

“资兴消费”小程序操作指南(商户端) 说明: 1.“资兴消费”小程序是基于微信APP使用,使用前请确保手机已经安装微信,并且能够正常使用。 2.小程序的使用群体为资兴市公职人员、在资兴市注册登记的商户(主要为餐饮住宿、商业零售、扶贫惠农、家政服务、教育培训等第三产业领域商户)及资兴市贫困户使用。 3.以下功能介绍仅从商户者及贫困户(收款者)角度介绍小程序使用方法。 使用说明: 商户端“资兴消费”小程序主要功能有:激活、固定收款码、设置金额收款、收入明细、结算明细、个人信息等信息。 一、进入小程序 进入小程序主要有五种途径: (一)首页搜索 打开微信首页,点击右上角放大镜图标,输入“资兴消费”,点击下边自动出现的“搜一搜”搜索“资兴消费”,会跳出搜索结果,选择“资兴消费-小程序”,即可进入小程序

页面。 (二)发现页搜索 打开微信,点击微信下方的发现,点击“搜一搜”,进入搜一搜页面,在文本框中输入“资兴消费”后点击搜索,进入搜索结果页面,选择“资兴消费-小程序”,即可进入小程序页面。 (三)直接扫码 打开微信扫一扫,直接扫码下面小程序码或二维码,即

可打开“资兴消费”小程序。 (四)若之前使用过“资兴消费”小程序,可以直接在微信首页向下拉动列表,即可打开最近使用过的小程序页面,点击对应的“资兴消费”小程序即可进入小程序。 (五)若之前使用过“资兴消费”小程序,可以在“发现”页,点击“小程序”进入小程序列表,点击对应的“资兴消费”小程序即可进入小程序。

二、激活 首次打开小程序后,会提示用户公开信息授权,请点击“确定”按钮,提示申请获取权限时,请点击“授权登录”按钮,提示获取昵称与头像时,请点击“允许”按钮,提示获取位置信息时,请点击允许,同意以上授权后,方可正常使用小程序。

sql优化方案讲解

Sql优化方案 一.数据库优化技术 1.索引(强烈建议使用) 1.1优点 创建索引可以大大提高系统的性能。 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 1.2 缺点 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 1.3 使用准则 索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 一般来说,应该在这些列上创建索引。 第一,在经常需要搜索的列上,可以加快搜索的速度;

第二,在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 第三,在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;第四,在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 第五,在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 第六,在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。 1.4 总结 1)索引提高了数据库的检索性能,但一定程度上牺牲了修改性能。因此适用于“多查询少修改”(insert,update,delete)的表。 2)对此类表中的外键,需要分组,排序或作为检索条件的字段建立索引 3)对此类表中查询使用少,字段取值少,字段数据量大的不应创建索引

微信小程序设计规范

微信小程序设计规 范

概要 微信小程序设计的基本原则是微信设计中心针对在微信内上线的小程序页面总结的设计指南及建议。以下设计原则都是基于对用户的尊重的基础上的,旨在微信生态内建立友好、高效、一致的用户体验的同时,最大程度顺应和支持各业务需求设计,实现用户与程序的共赢。 一、友好礼貌 为了避免用户在微信中使用小程序服务时,注意力被周围复杂环境干扰,小程序在设计时应该注意减少无关的设计元素对用户目标的干扰,礼貌地向用户展示程序侧提供的服务,友好地引导用户进行操作。 1. 重点突出 每个页面都应有明确的重点,以便于用户每进入一个新页面的时候都能快速地理解页面内容,在确定了重点的前提下,应尽量避免页面上出现其它干扰项影响用户的决策和操作。 反例示意 此页面的主题是查询,却添加了诸多与查询不相关的业务入口,与用户的预期不符,易造成用户的迷失。

纠正示意 去掉任何与用户目标不相关的内容,明确页面主题,在技术和页面控件允许的前提下提供有助于用户目标的帮助内容,比如最近搜索词,常见搜索词等。 反例示意 操作没有主次,让用户无从选择

纠正示意 首先要避免并列过多操作让用户选额,在不得不并列多个操作时,需区分操作主次,减轻用户的选择难度。

2. 流程明确 为了让用户顺畅地使用页面,在用户进行某一个操作流程时,应避免出现用户目标流程之外的内容而打断用户。 反例示意 用户本打算进行搜索,在进入页面时却被突如其来的抽奖弹窗所打断;对于抽奖没有兴趣的用户是非常不友好的干扰,平添一份对开发团队的恼怒;而即便有部分用户确实被“诱人”的抽奖活动所吸引,离开主流程去抽奖之后可能就遗忘了原本的目标,进而失去了对产品真正价值的利用和认识。 二、清晰明确 作为一个负责任的开发者,一旦用户进入我们的小程序页面,就有责任和义务清晰明确地告知用户身在何处、又能够往何

常用SQL优化知识点

SQL语句调优 1. SQL语句中IN包含的值不应过多 MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between 就不要用in 了;再或者使用连接来替换。 2. SELECT语句务必指明字段名称 SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。 3. 当只需要一条数据的时候,使用limit 1 这是为了使EXPLAIN中type列达到const类型 4. 如果排序字段没有用到索引,就尽量少排序 5. 如果限制条件中其他字段没有索引,尽量少用or or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all 或者是union(必要的时候)的方式来代替“or”会得到更好的效果

6. 区分in和exists,not in和not exists ?select * from表A where id in (select id from表B) 上面sql语句相当于: ?select * from表A where exists(select * from表B where表B.id=表A.id)区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN 适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。 关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的sql语句? 原sql语句: ?select colname … from A表where a.id not in (select b.id from B表) 高效的sql语句: ?select colname … from A表Left join B表on where a.id = b.id where b.id is null 7. 分段查询

微信小程序的计指南和建议

微信小程序的计指南和建议 基于微信小程序轻快的特点,拟定了小程序界面设计指南和建议。设计指南建立在充分尊重用户知情权与操作权的基础之上。旨在微信生态体系内,建立友好、高效、一致的用户体验,同时最大程度适应和支持不同需求,实现用户与小程序服务方的共赢。 一、友好礼貌 为了避免用户在微信中使用小程序服务时,注意力被周围复杂环境干扰,小程序在设计时应该注意减少无关的设计元素对用户目标的干扰,礼貌地向用户展示程序提供的服务,友好地引导用户进行操作。 重点突出 每个页面都应有明确的重点,以便于用户每进入一个新页面的时候都能快速地理解页面内容,在确定了重点的前提下,应尽量避免页面上出现其他干扰项影响用户的决策和操作。 二、清晰明确 一旦用户进入我们的小程序页面,我们就有责任和义务清晰明确地告知用户身在何处、又可以往何处去,确保用户在页面中游刃有余地穿梭而不迷路,这样才能为用户提供安全的愉悦的使用体验。 导航明确,来去自如

导航是确保用户在网页中浏览跳转时不迷路的最关键因素。导航需要告诉用户,我在哪,我可以去哪,如何回去等问题。首先在微信系统内的所有小程序的全部页面,均会自带微信提供的导航栏,统一解决我在哪,如何回去的问题。在微信层级导航保持体验一致,有助于用户在微信内形成统一的体验和交互认知,无需在各小程序和微信切换中新增学习成本或改变使用习惯。 三、便捷优雅 从PC时代的物理键盘鼠标到移动端时代手指,虽然输入设备极大精简,但是手指操作的准确性却大大不如键盘鼠标精确。为了适应这个变化,需要开发者在设计过程中充分利用手机特性,让用户便捷优雅的操控界面。 减少输入 由于手机键盘区域小且密集,输入困难的同时还易引起输入错误,因此在设计小程序页面时因尽量减少用户输入,利用现有接口或其他一些易于操作的选择控件来改善用户输入的体验。 统一稳定 除了以上所提到的种种原则,建议接入微信的小程序还应该时刻注意不同页面间的统一性和延续性,在不同的页面尽量使用一致的控件和交互方式。

提高程序性能

https://www.doczj.com/doc/d8465349.html,中提高程序性能的方法研究 (13级教育技术学王霞 20131212) 摘要:文章从程序编码优化、数据操作优化和配置优化三个方面简要介绍了网站优化的基本方法,以便提高程序性能,为网站设计者提供参考。 关键字:提高程序性能;网站优化;https://www.doczj.com/doc/d8465349.html,网站 一、引言 众所周知,网站程序的运行效果直接影响着网站的质量和推广,网站性能差,致使用户访问网页时等待时间过长、响应过慢、均会成为用户流失的潜在因素。因此网站优化就显得尤为重要。如何提高程序性能也就成为了需要网站设计者深入细致研究的重要问题。文章从程序编码优化、数据操作优化和配置优化三个方面对如何提高程序性能做了基本介绍,具体方法如下: 二、程序编码优化 从编码方面优化程序性能主要从三方面入手: (一)集合操作 .NET 框架提供了诸如ArrayList、Hashtable、Dictionary 等集合类型。要了解各个集合的特性,选择合适的集合。在所有的集合中数组是性能最高的,如果要存储的数据类型一致和容量固定,特别是对值类型的数组进行操作时没有装箱和拆箱操作,效率极高。在集合数目固定的情况下,数组的存取效率最高,泛型次之,ArrayList 最慢。 在选择集合类型时应考虑几点: 1.集合中的元素类型是否是一致的,比如集合中将要存储的元素都是int或者都是string 类型的就可以考虑使用数组或者泛型集合,这样在存储数值类型元素就可以避免装箱拆箱操作,即使是引用类型的元素也可以避免类型转换操作。 2.集合中的元素个数是否是固定的,如果集合中存储的元素是固定的并且元素类型是一致的就可以使用数组来存储。 3.将来对集合的操作集中在那些方面,如果对集合的操作以查找居多可以考虑HashTable或者Dictionary这样的集合,因为在.NET Framework中对这类集合采用了特殊机制,所以在查找时比较的次数比其它集合要少。 另外,在使用可变集合时如果不制定初始容量大小,系统会使用一个默认值来指定可变集合的初始容量大小,如果将来元素个数超过初始容量大小就会先在内部重新构建一个集合,再将原来集合中的元素复制到新集合中,可以在实例化可变集合时指定一个相对较大的初始容量,这样在向可变集合中添加大量元素时就可以避免集合扩充容量带来的性能损失。(二)字符串操作 在.NET Framework中String类是一个比较特殊的类,我们知道值类型变量直接在栈中分配内存来存储变量的值,并且不需要垃圾回收器来回收,大部分引用类型变量是在堆中分配内存来存储变量的值,在不再使用的情况下会被垃圾回收器回收所占用的内存。String 类型的变量虽然是引用类型变量(常用的赋值方式却很类似于值类型变量的赋值方式,如string a=”123”),但是CLR(Common Language Runtime,通用语言运行时)通过了一种特

优化 SQL SELECT 语句性能的 6 个简单技巧

SELECT语句的性能调优有时是一个非常耗时的任务,在我看来它遵循帕累托原则。20%的努力很可能会给你带来80%的性能提升,而为了获得另外20%的性能提升你可能需要花费80%的时间。除非你在金星工作,那里的每一天都等于地球上的243天,否则交付期限很有可能使你没有足够的时间来调优SQL查询。 根据我多年编写和运行SQL语句的经验,我开始开发一个检查列表,当我试图提高查询性能时供我参考。在进行查询计划和阅读我使用的数据库文档之前,我会参考其中的内容,数据库文档有时会很复杂。我的检查列表绝对说不上全面或科学,它更像是一个保守计算,但我可以说,遵循这些简单的步骤大部分时间我确实能得到性能提升。检查列表如下。 检查索引 在SQL语句的WHERE和JOIN部分中用到的所有字段上,都应该加上索引。进行这个3分钟SQL性能测试。不管你的成绩如何,一定要阅读那些带有信息的结果。 限制工作数据集的大小 检查那些SELECT语句中用到的表,看看你是否可以应用WHERE子句进行过滤。一个典型的例子是,当表中只有几千行记录时,一个查询能够很好地执行。但随着应用程序的成长,查询慢了下来。解决方案或许非常简单,限制查询来查看当前月的数据即可。 当你的查询语句带有子查询时,注意在子查询的内部语句上使用过滤,而不是在外部语句上。 只选择你需要的字段 额外的字段通常会增加返回数据的纹理,从而导致更多的数据被返回到SQL客户端。另外: •使用带有报告和分析功能的应用程序时,有时报告性能低是因为报告工具必须对收到的、带有详细形式的数据做聚合操作。 •偶尔查询也可能运行地足够快,但你的问题可能是一个网络相关的问题,因为大量的详细数据通过网络发送到报告服务器。 •当使用一个面向列的DBMS时,只有你选择的列会从磁盘读取。在你的查询中包含的列越少,IO开销就越小。 移除不必要的表 移除不必要的表的原因,和移除查询语句中不需要的字段的原因一致。 编写SQL语句是一个过程,通常需要大量编写和测试SQL语句的迭代过程。在开发过程中,你可能将表添加到查询中,而这对于SQL代码返回的数据可能不会有任何影响。一旦SQL运行正确,我发现许多人不会回顾他们的脚本,不会删除那些对最终的返回数据没有任何影响和作用的表。通过移除与那些不必要表的JOINS操作,你减少了大量数据库必须执行的流程。有时,就像移除列一样,你会发现你减少的数据又通过数据库返回来了。 移除外部连接查询 这说起来容易做起来难,它取决于改变表的内容有多大的影响。一个解决办法是通过在两个表的行中放置占位符来删除OUTER JOINS操作。假设你有以下的表,它们通过定义OUTER JOINS来确保返回所有的数据: customer_idcustomer_name 1John Doe 2Mary Jane 3Peter Pan 4Joe Soap

程序性能分析《一》

//程序优化示例 //待优化程序: //定义一个抽象类型data_t,这里data_t可以被声明为int float double; typedef int data_t ; typedef struct { int len; data_t *data; }vec_rec ,*vec_ptr; #define IDENT 0 #define OPER + #define IDENT 1 #define OPER * //创建向量组 vec_rec new_vec(int len) { vec_ptr result=(vec_ptr) malloc(sizeof(vec_rec)); if(!result) return NULL; result->len=len; if(len>0){ data_t * data = (data_t*)calloc(len,sizeof(data_t)); if(!data){ free((void*)result); return NULL;

} result->data=data; } else result->data=NULL; return result; } //获取向量元素 int get_vec_element(vec_ptr v,int index, data_t * dest) { if(index<0 || index>=v-len) return 0; *dest = v->data[index]; return 1; } int vec_length(vec_ptr v) { return v->len; } //初始版本 void combine1(vec_ptr v,data_t * dest) { int i; *dest=IDENT; for(i=0;i

微信小程序的官方设计指南和建议(规范抢先看)

c基于微信小程序轻快的特点,我们(微信官方)拟定了小程序界面设计指南和建议。设计指南建立在充分尊重用户知情权与操作权的基础之上。旨在微信生态体系内,建立友好、高效、一致的用户体验,同时最大程度适应和支持不同需求,实现用户与小程序服务方的共赢。 一、友好礼貌 为了避免用户在微信中使用小程序服务时,注意力被周围复杂环境干扰,小程序在设计时应该注意减少无关的设计元素对用户目标的干扰,礼貌地向用户展示程序提供的服务,友好地引导用户进行操作。 重点突出 每个页面都应有明确的重点,以便于用户每进入一个新页面的时候都能快速地理解页面内容,在确定了重点的前提下,应尽量避免页面上出现其他干扰项影响用户的决策和操作。 反例示意 此页面的主题是查询,却添加了诸多与查询不相关的业务入口,与用户的预期不符,易造成用户的迷失。 纠正示意 去掉任何与用户目标不相关的内容,明确页面主题,在技术和页面控件允许的前提下提供有助于用户目标的帮助内容,比如最近搜索词,常用搜索词等。

反例示意 操作没有主次,让用户无从选择 纠正示意

首先要避免并列过多操作让用户选择,在不得不并列多个操作时,需区分操作主次,减轻用户的选择难度。 流程明确 为了让用户顺畅地使用页面,在用户进行某一个操作流程时,应避免出现用户目标流程之外的内容而打断用户。 反例示意 用户本打算进行搜索,在进入页面时却被突如其来的抽奖弹窗所打断;对于抽奖没有兴趣的用户是非常不友好的干扰;而即便有部分用户确实被“诱人”的抽奖活动所吸引,离开主流程去抽奖之后可能就遗忘了原本的目标,进而失去了对产品真正价值的利用和认识。

二、清晰明确 一旦用户进入我们的小程序页面,我们就有责任和义务清晰明确地告知用户身在何处、又可以往何处去,确保用户在页面中游刃有余地穿梭而不迷路,这样才能为用户提供安全的愉悦的使用体验。 导航明确,来去自如 导航是确保用户在网页中浏览跳转时不迷路的最关键因素。导航需要告诉用户,我在哪,我可以去哪,如何回去等问题。首先在微信系统内的所有小程序的全部页面,均会自带微信提供的导航栏,统一解决我在哪,如何回去的问题。在微信层级导航保持体验一致,有助于用户在微信内形成统一的体验和交互认知,无需在各小程序和微信切换中新增学习成本或改变使用习惯。 微信导航栏 微信导航栏,直接继承于客户端,除导航栏颜色之外,开发者无需亦不可以对其中的内容进行自定义。但开发者需要规定小程序各个页面的跳转关系,让导航系统能够以合理的方式工作。

小程序使用说明文档

小程序使用说明文档 1.登录角色: 本次小程序主要支持的登录角色有:代理商、业务员两种角色 2.功能模块: 本次一期小程序主要实现的功能有三个,第一个商户经营状况查询;第二个商户预警提醒功能;第三个数据罗盘。 (1)商户经营状况 商户经营状况中,可以查看到所登录角色下属的所有活跃商户的交易状况(如果某个商户某一天一条交易记录都没有,那么它不会出现在当天的经营状况列表里面) 商户经营状况可以按照商户名查询某一个商户的经营状况;也可以按照具体某一天,或者按月来查询下属商户的交易状况;当然,这两个条件是可以组合使用的,你可以查询下属商户某一天或者某一个月份的经营情况! (2)商户预警 预警提醒功能分两个页签:“预警信息”和“等待确认”,都可支持按照商户名进行搜索 预警提醒中会显示登录角色下属的所有昨天交易量相对前天有所下降的商户,并且会按照下降比例从高到低的顺序进行排序。在预警提醒中,可以预警商户进行操作。 对于处于正常波动范围内的商户,点击长按,在弹出框中点击“忽略”,即可从预警信息列表中清楚该数据。

对于下降比例不正常的商户,点击长按,在弹出框中选择“等待确认”,即可把该条记录添加到等待确认列表中(预警列表中的数据每天都会刷新,所以请务必记得把异常商户及时添加到等待确认列表!)。 等待确认列表列表中显示当前登录角色从预警信息列表中添加过来的所有商户数据,在改列表中可以对商户进行处理。 对于不小心误操作过来的商户,可以点击长按,选择“正常”,从该列表中清楚该条数据。 对于无法挽回的商户,点击长按,在弹出框中选择“确认流失”,填写流失原因说明(必填!)后可从该列表中移出该条数据。 对于已经做出处理并挽回的商户,点击长按,在弹出框中选择“确认处理”,填写处理方法(必填)后,可从该列表中移出该记录。 对于所有添加到等待确认列表中的商户,具体的处理方法和处理说明记录,都有在数据库做记录。 (3)数据罗盘 数据罗盘主要是展示当前登录角色下的所有商户的交易情况的一些汇总信息。如:昨日交易总金额、较上周昨日同比增长或下降比例,昨日交易总笔数、较上周昨日同比增长或下降比例,累计开户数、本月新开户数;以及下属商户的星级占比饼图。 昨日交易总金额、较上周昨日同比增长或下降比例:昨日交易金额是指当前登录角色昨天的首款总额;较上周昨日同比增长或下降比例是指,昨天的交易总额和上周的同一天(如昨天是周二,就和上周二进行比较)的交易总额的上浮或下降比例[(昨天交易金额-上周昨日交易金额)/上周昨日交易金额] 昨日交易总笔数、较上周昨日同比增长或下降比例:比较方式与昨日交易总金额一样,只是以笔数为统计单位。 累计开户数和本月新开户数:累计开户数是当前登录角色下属所有的商户个数;本月新开是指进件日期为当前月份的商户个数。 星级排行:即后台的商户星级排行功能以饼图形式的展现,类别“其它”是指暂时没有星级的

Java程序性能优化方案

Java程序性能优化方案 StringTokenizer比String.split()方法效率高 更优化的方式 Java代码 while(true){ String splitStr=null; int j=temp.indexOf(';'); if(j<0)break; SplitStr=tmp.substring(0,j); tmp=tmp.substring(j+1); } while(true){ String splitStr=null; int j=temp.indexOf(';'); if(j<0)break; SplitStr=tmp.substring(0,j); tmp=tmp.substring(j+1); } 比String.startsWith和endsWith性能更优的方式:Java代码 int len=orgStr.length(); if(orgStr.charAt(0)=='a' &&orgStr.charAt(1)=='b' &&orgStr.charAt(2)=='b'); if(orgStr.charAt(len-1)=='a' &&orgStr.charAt(len-2)=='b' &&orgStr.charAt(len-3)=='c');

int len=orgStr.length(); if(orgStr.charAt(0)=='a' &&orgStr.charAt(1)=='b' &&orgStr.charAt(2)=='b'); if(orgStr.charAt(len-1)=='a' &&orgStr.charAt(len-2)=='b' &&orgStr.charAt(len-3)=='c'); StringBuffer(int capacity)指定初始容量可以减少扩容的操作

SQLServer数据查询的优化方法

SQLServer数据查询的优化方法聂文燕 摘要:SQLServer是一种功能强大的数据库管理系统,许多数据库应用系统都是以它作为后台数据库。本文在分析影响SQLSERVER数据查询效率的因素的基础上,提出了几种优化数据查询的方法。 关键词:SQLServer,数据,查询,优化 一、引言 SQLServer是是由微软公司开发的基于Windows操作系统的关系型数据库管理系统,它是一个全面的、集成的、端到端的数据解决方案,为企业中的用户提供了一个安全、可靠和高效的平台用于企业数据管理和商业智能应用。目前,许多中小型企业的数据库应用系统都是用SQLServer作为后台数据库管理系统设计开发的。设计一个应用系统并不难,但是要想使系统达到最优化的性能并不是一件容易的事。根据多年的实践,由于初期的数据库中表的记录数比较少,性能不会有太大问题,但数据积累到一定程度,达到数百万甚至上千万条,全面扫描一次往往需要数十分钟,甚至数小时。20%的代码用去了80%的时间,这是程序设计中的一个著名定律,在数据库应用程序中也同样如此。如果用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟。而且我们知道,目前数据库系统应用中,查询操作占了绝大多数,查询优化成为数据库性能优化最为重要的手段之一。 二、影响查询效率的因素 SQLServer处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给SQLServer的查询优化器,查询优化器通过检查索引的存在性、有效性和基于列的统计数据来决定如何处理扫描、检索和连接,并生成若干执行计划,然后通过分析执行开销来评估每个执行计划,从中选出开销最小的执行计划,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。所以,SQLServer中影响查询效率的因素主要有以下几种:1.没有索引或者没有用到索引。索引是数据库中重要的数据结构,使用索引的目的是避免全表扫描,减少磁盘I/O,以加快查询速度。 2.没有创建计算列导致查询不优化。 3.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。 4.返回了不必要的行和列。 5.查询语句不好,没有优化。其中包括:查询条件中操作符使用是否得当;查询条件中的数据类型是否兼容;对多个表查询时,数据表的次序是否合理;多个选择条件查询时,选择条件的次序是否合理;是否合理安排联接选择运算等。 三、SQLServer数据查询优化方法 3.1建立合适的索引索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引,数据库也能根据SELECT语句成功地检索到结果,但随着表变得越来越大,使用“适当”的索引的效果就越来越明显。索引的使用要恰到好处,其使用原则有: (1)对于基本表,不宜建立过多的索引; (2)对于那些查询频度高,实时性要求高的数据一定要建立索引,而对于其他的数据不考虑建立索引; (3)在经常进行连接,但是没有指定为外键的列上建立索引; (4)在频繁进行排序或分组(即进行groupby或orderby操作)的列上建立索引;

小程序客服使用教程

小程序客服 一、步骤 1、第一步 开发——开发设置——消息推送——启用——管理员扫码

第二步绑定客服人员 使用网页版与移动端小程序客服工具前,小程序管理员需在小程序后台完成客服人员的绑定。目前小程序支持绑定不多于100个客服人员。

二、客服工具 1、移动端客服小助手 已被绑定的小程序客服人员可微信搜索“客服小助手”或扫码登录客服小助手小程序,并选择对应的小程序帐号,登录后即可看到与小程序对话的用户,可选择接入对话。 切换客服状态 点击在线状态,可以选择在线状态、离开状态:选择在线状态后,即使退出客服小程序,仍可在“服务通知”中接收到用户咨询的消息提醒;选择离开状态后,将无法收到客服消息与消息提醒。 接收与发送消息 首次打开小程序后,会自动接入客服消息,后续有新的客服消息,可点击顶部接

入栏进行接入;已经接入的会话,客服人员可以在48小时内和用户进行对话,目前支持发送文本、图片类型的消息。 2、PC端微信公众平台网页客服 已被绑定的小程序客服人员可扫码登录微信公众平台网页版客服工具,并选择对应的小程序帐号,登录后即可看到与小程序对话的用户,可选择接入对话。 切换客服状态 点击在线状态,可以选择在线状态、离开状态或退出登录

接收消息 手动接入:客服人员上线后,点击“待接入”,即可在“待接入”列表中,手动接入待回复的对话 自动接入:当待接入的对话太多时,可以在设置/接入设置中,开启自动接入重新接入:退出登录,或对话超过半小时,需要重新接入,激活对话 发送消息 已经接入的会话,客服人员可以在48小时内和用户进行对话,目前支持发送文本、图片类型的消息。

常用sql查询优化规则

1.说明 数据库系统需要保存大量历史记录,系统内存在许多历史记录表,因此常常出现系统运行一段时间,表记录数达到一定数量后,系统响应明显变慢的现象。为尽可能的提高SQL 执行的效率,我们在编写SQL语句应该遵循一定的优化规则,使代码风格统一、规范。充分利用表索引,避免进行全表扫描;充分利用结构化编程方式,提高查询的复用能力,也许完全遵守以下方法速度未必达到想要的结果,但是养成一个好的编程习惯是重要的。 2.调优方法 2.1. 相同功能、性能的SQL语句 ORACLE采用共享内存SGA的机制,因此ORACLE会对每个不同写法的SQL进行分析,并且占用共享内存;如果书写格式完全相同,则ORACLE只分析一次,遇到相同书写格式的SQL,会直接从共享内存中获取结果集;这样便能减少共享池的开销以及代码的复用。处理方法:保证书写格式相同,包括大小写,空格位置,表别名等一致;将一些通用的SQL 语句作为公共函数由其它函数调用的方式使用。 2.2. 动态SQL:动态SQL采用变量动态绑定的方式,避免 重复解析。 2.3. 连接方式与表名顺序 多表查询时需要选择最有效率的表名顺序(基于规则的优化器有效),ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名;因此写在最后的那张基础表最先被处理,即选择记录数最少的表作为基础表,首先,扫描FROM子句中最右的那个表,并对记录进行排序,然后扫描FROM子句中最后第二个表,最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。 2.4. 查询条件顺序 ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件适合写在WHERE子句的末尾。 2.5. 语法和语义 2.5.1.SELECT子句中避免使用' * ' 使用'*' ,Oracle便会查询数据字典,依次解析各列名,应明确指定各列的名称,这样也便于理解。 Select * from t_user t;

微信小程序入门指南

目 录 关于作者 (3) 前言 (5) 第一节 什么是小程序? (7) 第二节 小程序将给我们带来什么改变 (12) 第三节 小程序上手案例 (18) 知了交通 (19) 剁手吗 (24) 知了地铁 (32) 解忧室 (36) 第四节 如何转行小程序开发? (41) 第五节 如何拥有自己的小程序? (45) 如何注册微信小程序 (46) 如何搞定微信认证? (52) 如何完善小程序信息? (59) 开发者工具怎么用? (65) 小程序的审核与发布 (74) 第六节 小程序官方文档解读 (83) 开发文档解读 (84) 设计文档解读 (94) 运营文档解读 (104) 第七节 电商类小程序开发教程 (112) 如何做轮播图 (113) 如何做商品列表 (123) 数据加载和图文排版 (134) 写在最后 (148) 附录 (149) 小程序大事记 (149)

关于作者 爱范儿是首批获得微信小程序内测资格的200 个公司之一,也是全球第一个开发出微信小程序的公司。 知晓程序,是爱范儿旗下专注小程序生态的新品牌。 我们提供最全面、新鲜的小程序资讯、观点、教程、Demo、活动等内容和服务,在这里你能了解到关于小程序的一切。 我们还跟全国各地的小程序关注者开展了深入交流,形成了面向小程序开发者的未来小程序·黑客马拉松/面向非技术从业人员(产品/运营/市场等)的未来小程序·workshop/面向小程序爱好者的未来小程序·MindTalk 的活动矩阵。 目前,知晓程序共包含四大版块: l知晓程序微信公众号:小程序资讯媒体 l知晓程序商店:小程序应用商店; l知晓程序社区:小程序交流平台; l知晓程序BaaS:小程序后端服务平台。

相关主题
文本预览
相关文档 最新文档