常用优化工具,诊断及定位问题根源
分类:面向对象

在具有许多活跃用户的繁忙生产环境中,跟踪SQL会话是费时且十分复杂的,因为在任何使用连接池的多层系统中处理SQL语句可能要涉及多个进程,或者甚至是不同的实例。

图片 1

目录:

利用Oracle数据库10g,Oralce通过一个新的内置软件包DBMS_MONITOR合理化了SQL的跟踪,这个软件包中包含以前无书面记载的跟踪工具的功能。现在,您可以轻松地从头到尾--从客户机到中间层再到后端--跟踪任何用户的会话,并且基于特定的客户ID、模块或动作生成跟踪文件。

 

Oracle数据完整性和锁机制 

此外,Oracle数据库10g包含一种新的实用程序trcsess,它可以让您基于会话ID或模块名称之类的条件,有选择地从大量跟踪文件中抽取出跟踪数据,并将它们保存到一个文件中。该实用程序在共享服务器配置中特别有用,因为调度程序可能把每一个用户请求传递给不同的共享服务器进程,从而为任何给定的会话产生多个跟踪文件。与通过大量跟踪文件发掘信息不同,Oracle数据库10g的trcsess可以让您获得关于单一用户会话的整合后的跟踪信息。

图片 2图片 3

索引及优化之表分析 

开始

SELECT round(bitand(s.ownerid, 65535)) parent_session_sid,

表分析、约束及表间关系 

和Oracle数据库的以前版本一样,跟踪文件将被输出到由服务器的初始化文件的user_dump_dest参数指定的目录中。默认的位置取决于操作系统;例如,对于使用DBCA的Microsoft Windows平台,默认位置是$ORACLE_BASE/instance_name/admin/udump,其中instance_ name是Oracle实例的名称。您可以通过使用以下改变会话命令来动态地更改该参数:

round(bitand(s.ownerid,16711680)/65536) parent_session_instid, s.SADDR, s.SID,

Oracle体系结构1

alter session set user_dump_dest=c:/kflosstrace;

s.SERIAL#, s.AUDSID, s.PADDR, s.USER#, s.USERNAME, s.COMMAND, s.OWNERID,

Oracle体系结构2 

您还可以把您自己的标记添加到跟踪文件名中,以便您能够更容易地找到生成的文件。为此,可以在启动跟踪之前设置tracefile_identifier初始化参数:

s.TADDR, s.LOCKWAIT, s.STATUS, s.SERVER, s.SCHEMA#, s.SCHEMANAME, s.OSUSER,

海量数据库及分区1 

alter session settracefile_identifier =kfloss_test;

s.PROCESS, s.MACHINE, s.TERMINAL, UPPER(s.PROGRAM) PROGRAM, s.TYPE,

海量数据库及分区2 

通过该命令生成的跟踪文件带有您设置的附加在文件名后的字符串值。尽管这些改变会话命令都不是必要的,但是它们都会使查找跟踪会话的结果更容易。

s.SQL_ADDRESS, s.SQL_HASH_VALUE, s.SQL_ID, s.SQL_CHILD_NUMBER, s.PREV_SQL_ADDR,

海量数据库及分区3 

现在,我们已经设置了这些参数,那么让我们看看新的跟踪软件包和Oracle企业管理器的界面。让我们使用新的DBMS_MONITOR软件包通过模块名称和客户机名称来建立一个跟踪。

s.PREV_HASH_VALUE, s.PREV_SQL_ID, s.PREV_CHILD_NUMBER, s.PLSQL_ENTRY_OBJECT_ID,

海量数据库及分区4 

用DBMS_MONITOR建立跟踪

s.PLSQL_ENTRY_SUBPROGRAM_ID, s.PLSQL_OBJECT_ID, s.PLSQL_SUBPROGRAM_ID, s.MODULE,

高级SQL优化(一)  

DBMS_MONITOR包具有多个例程,用于启用和禁用统计数据集合,以及用于根据会话ID进行跟踪、或者基于服务名称、模块名称和动作名称的组合进行跟踪。。 模块名称和动作名称都来自于应用程序代码内部。例如,Oracle电子商务套件应用程序在代码中提供了模块名称和动作名称,这样您就可以在任何Oralce企业管理器页面中通过名称来识别它们。 。

s.MODULE_HASH, s.ACTION, s.ACTION_HASH, s.CLIENT_INFO, s.FIXED_TABLE_SEQUENCE,

高级SQL优化(二)  

请注意,设置模块、动作及其他参数将不造成对数据库的往返操作--这些例程携带来自应用程序的所有调用。

s.ROW_WAIT_OBJ#, s.ROW_WAIT_FILE#, s.ROW_WAIT_BLOCK#, s.ROW_WAIT_ROW#,

高级SQL优化(三) 常用优化工具 

服务名称由用于连接该服务的连接字符串来确定。未与特定服务关联的用户会话将由sys$users处理。由于我们具有一个服务和一个模块名称,因而我们可以启动对该模块的跟踪,如下所示:

s.LOGON_TIME, s.LAST_CALL_ET, s.PDML_ENABLED, s.FAILOVER_TYPE,

PPT和源码下载:   

SQL exec dbms_monitor.serv_mod_act_trace_enable(service_name=testenv, module_name=product_update);

s.FAILOVER_METHOD, s.FAILED_OVER, s.RESOURCE_CONSUMER_GROUP, s.PDML_STATUS,

配套视频课程

PL/SQL过程已成功完成。

s.PDDL_STATUS, s.PQ_STATUS, s.CURRENT_QUEUE_DURATION, s.CLIENT_IDENTIFIER,

    Oracle性能优化  

我们可以启动对客户机的跟踪:

s.BLOCKING_SESSION_STATUS, s.BLOCKING_INSTANCE, s.BLOCKING_SESSION, s.SEQ#,

    海量数据库和高级SQL优化 

SQL exec dbms_monitor.client_id_trace_enable(client_id=kimberly);

s.EVENT#, s.EVENT, s.P1TEXT, s.P1, s.P1RAW, s.P2TEXT, s.P2, s.P2RAW, s.P3TEXT,

 

PL/SQL过程已成功完成。

s.P3, s.P3RAW, s.WAIT_CLASS_ID, s.WAIT_CLASS#, s.WAIT_CLASS, s.WAIT_TIME,

 

请注意,所有这些设置都是永久性的--所有与该服务和模块关联的会话都会被跟踪,而不仅仅是跟踪当前会话。

s.SECONDS_IN_WAIT, s.STATE, s.SERVICE_NAME, s.SQL_TRACE, s.SQL_TRACE_WAITS,

SQL*PLUS下使用AUTOTRACE

为了基于会话ID跟踪SQL,可以查看Oracle企业管理器的Top Sessions页面,或者像您当前做的那样查询V$SESSION视图。

s.SQL_TRACE_BINDS, stat.cpu - stat.CPU_this_call_start cpu_this_call, stat.CPU,

1.AUTOTRACE简介  

SQL select sid, serial#, usernamefrom v$session;SID SERIAL# USERNAME------ ------- ------------133 4152 SYS137 2418 SYSMAN139 53 KIMBERLY140 561 DBSNMP141 4 DBSNMP. . .168 1169 1170 128 rows selected.

stat.UGA_memory, stat.PGA_memory, stat.Commits, stat.Rollbacks, si.Block_Gets,

  AUTOTRACE是SQL*Plus的一项功能,其作用是自动跟踪SQL语句,为SQL 语句生成一个 执行计划并且提供与 该语句的处理有关的统计信息

通过会话ID(SID)和序号,您可以使用DBMS_MONITOR只对下面的会话启用跟踪:

si.Consistent_Gets, si.Physical_Reads, si.Block_Changes, si.Consistent_Changes FROM V$SESSION S, V$SESS_IO si,

SQL*Plus AUTOTRACE 可以用来替代 SQL Trace 使用,AUTOTRACE 的好处是不必设置跟踪文件的格式,并且它将自动为 SQL 语句显示执行计划。AUTOTRACE与执行计划的区别是AUTOTRACE 分析和执行语句;而EXPLAIN PLAN仅分析语句,而不负责执行语句。

SQL exec dbms_monitor.session_trace_enable(139);

(select ss.sid stat_sid,

   AUTOTRACE在SQL*PLUS下执行,使用AUTOTRACE不会产生跟踪文件。

PL/SQL过程已成功完成。

sum(decode(sn.name, 'CPU used when call started', ss.value, 0))

2.配置AUTOTRACE

该序号默认为该SID的当前序号,因此如果那就是您想跟踪的会话和序号,那么您就不必查看更多的内容了。还有,默认情况下,WAITS设置为true而BINDS设置为false,因此上面的语法实际上与下面的语法效果相同:

CPU_this_call_start, sum(decode(sn.name, 'CPU used by this session', ss.value, 0)) CPU,

  (1).确保表PLAN_TABLE已经创建,如果没有则如下创建:

SQL exec dbms_monitor.session_trace_enable(session_id=139, serial_num=53, waits=true, binds=false);

sum(decode(sn.name, 'session uga memory', ss.value, 0)) uga_memory,

  图片 4

请注意,WAITS和BINDS是相同的参数,您在过去可能已经使用DBMS_SUPPORT和10046事件对它们进行了设置。

sum(decode(sn.name, 'session pga memory', ss.value, 0)) pga_memory,

  (2).确保角色plustrace已经创建,如果没有则如下创建:

如果您正在一个生产环境中工作,那么此时您最好重新运行出错的SQL或应用程序,并且相应地创建跟踪文件。

sum(decode(sn.name, 'user commits', ss.value, 0)) commits,

图片 5

用企业管理器建立跟踪

sum(decode(sn.name, 'user rollbacks', ss.value, 0)) rollbacks

 

通过Oracle企业管理器建立跟踪从Top Consumers页面开始。该页面显示服务、模块、客户和动作对系统资源的当前使用情况。

from v$sesstat ss, v$statname sn

3.使用AUTOTRACE

图1:Oracle企业管理器的Top Consumers页面

where ss.STATISTIC# = sn.STATISTIC#

图片 6

您可以单击Top Services、Top Modules、Top Actions、Top Clients或Top Sessions选项卡,来查看这些类别的顶级消费者中每一种的详细信息,随后您可以通过这些页面中的每一个页面轻松启用SQL跟踪。从页面上的列表中简单地选择项目,然后单击启用SQL跟踪开始跟踪。

and (sn.name = 'CPU used when call started' or

 

您还可以启用这些页面上列出的任何项目的统计数据集合。。

sn.name = 'CPU used by this session' or

4. AUTOTRACE设置命令

分析跟踪结果

sn.name = 'session uga memory' or

序号
命令
解释
1
SET AUTOTRACE OFF
此为默认值,即关闭Autotrace
2
SET AUTOTRACE ON
产生结果集和解释计划并列出统计
3
SET AUTOTRACE ON EXPLAIN
显示结果集和解释计划不显示统计
4
SETAUTOTRACE TRACEONLY
显示解释计划和统计,尽管执行该语句但将看不到结果集
5
SET AUTOTRACE TRACEONLY STATISTICS
只显示统计

获取关于Kimberly Floss的图书的信息

sn.name = 'session pga memory' or

参见每个设置的现场举例

无论您是使用DBMS_MONITOR或者是使用Oracle企业管理器建立跟踪,您都将使用trcsess 命令行工具来整合跟踪文件。单击Oracle企业管理器中的查看SQL跟踪按钮显示一个页面,其中显示了您将用于整合所有跟踪文件的语法。

sn.name = 'user commits' or

 

要确保用双引号括住字符串,并在文件名后添加一个.trc扩展名;否则,TKPROF将不会把它作为一个文件名来接受。在执行该命令之前,找到在user_dump_dest中指定的目录。

sn.name = 'user rollbacks')

5. AUTOTRACE STATISTICS含义

C:/.../udump trcsess output=kfloss.trc service=testenvmodule=product updateaction=batch insert

group by ss.sid) stat

序号
列名
解释
1
recursive call
递归调用SQL的个数;Oracle在执行这个SQL的时候,有时候会生成很多额外的SQL语句,这个就称为递归调用
2
db block gets
从buffer cache中读取的block的数量
3
consistent gets
从buffer cache中读取的undo数据的block的数量
4
physical reads
从磁盘读取的block的数量
5
redo size
DML生成的redo的大小
6
sorts (memory)
在内存执行的排序量
7
sorts (disk)
在磁盘上执行的排序量,如果memory空间使用不足,是会使用disk的空间的
8
bytes sent via SQL*Net to client
利用sql*net传入到client的字节数;
9
bytes received via SQL*Net from client
利用sql*net传出client的字节数;

随后,您可以对整合的跟踪文件运行TKPROF,以生成一份报告。

WHERE ( (s.USERNAME is not null) and (NVL(s.osuser,'x') <> 'SYSTEM') and

 

C:/.../udump tkprof kfloss.trcoutput=kfloss_trace_report SORT=(EXEELA, PRSELA, FCHELA)

(s.type <> 'BACKGROUND') ) and (si.sid(+)=s.sid)

使用SQL调优顾问

如果您不终止跟踪,那么运行该服务和模块的每一个会话都会被跟踪。因此,当您完成跟踪时,要确保通过使用Oralce企业管理器或DBMS_MONITOR包来终止跟踪。

and (stat.stat_sid = s.sid)

删除掉bigtab和smalltab上的所有索引:

--先用上面的查询列出当前session的状况

  图片 7

select p.spid thread_1,s.username,

  图片 8

decode(nvl(p.background,0),1,bg.description,

 

s.program ) program,

既然上述语句性能很差,那么怎么优化呢?幸运的是Oracle提供一个工具称为SQL调优顾问。从Oracle 10g起,可以使用SQL调优顾问 (SQL Tuning Advisor ,STA)来获得一个性能很差的语句的优化结果。STA的特点是简单、智能,DBA只需要调用函数就可以给出一个性能很差的语句的优化结果,从而做到有的放矢!

ss.value/100 CPU,physical_reads disk_io

使用DBMS_SQLTUNE包来创建优化任务并阅读优化建议:

from v$process p,

图片 9

v$session s,

创建完成后验证是否完成:

v$sesstat ss,

图片 10

v$sess_io si,

 

v$bgprocess bg

创建完成后验证是否完成:

where s.paddr=p.addr

图片 11 

and ss.sid=s.sid

单击该条目查看优化结果

and ss.statistic#=12

图片 12

and si.sid=s.sid

也可以通过SQL语句来查看结果,此方法是我们最喜欢的方法:

and bg.paddr(+)=p.addr

图片 13  

order by ss.value desc;

进行优化:

--进程消耗的CPU,IO资源

图片 14

select a.sid session_id,b.spid process_id

优化后在使用autotrace:

from v$session a,v$process b

图片 15

where a.paddr = b.addr and a.sid = (select sid from v$mystat where rownum = 1);

优化后在使用autotrace:

--当前的session_id

图片 16

SELECT S.USERNAME, P.SPID OS_PROCESS_ID, P.PID ORACLE_PROCESS_ID FROM V$SESSION S, V$PROCESS P WHERE S.PADDR = P.ADDR AND S.SID=227

结论:

--透过SESSION_ID 找process_ID

 

select

项目
优化前
优化后
倍数
从持久层获取consistent gets(从buffer cache中读取的undo数据的block的数量)
21688
6950
3
物理读physical reads(从磁盘读取的block的数量)
21589
6928
3
递归调用recursive call
0
1
N/A
时间(毫秒)
2070
1078
2

o.sid, o.sql_text, o.address, o.hash_value, o.user_name, s.schemaname

使用STA能快速定位性能瓶颈,从而为性能优化提供了准确的依据!

from v$open_cursor o, v$session s

 

where o.saddr = s.saddr

实时SQL监视

and o.sid = s.sid

   实时SQL监视(real-time SQL Monitorning)是Oracle 11g的另外一个新功能,其作用是允许用户监视正在执行的SQL。默认情况下,当使用并行查询、或者当SQL执行的CPU或I/O超过5秒钟时会自动启动。

and ( O.SID = '275')

也可以使用优化提示强制使用实时SQL监视功能,如下:

--定位好session ID后,可以开始查看这个sid最近所open的游标,可以找到部分cursor

 select   count()*

SELECT SQL_TEXT FROM V$SQLTEXT_WITH_NEWLINES WHERE

*  from bigtab a, smalltab b*

HASH_VALUE=TO_NUMBER('561877498') ORDER BY PIECE

*   where  a.object_name=b.table_name*

--依靠hash_value可以继续往下定位详细的sql语句.

  如果要强制不使用实时SQL监视功能,则也可以使用优化提示:

SELECT

select   count()*

SID, EVENT, TOTAL_WAITS, TOTAL_TIMEOUTS, TIME_WAITED, AVERAGE_WAIT

*  from bigtab a, smalltab b*

, MAX_WAIT

*   where  a.object_name=b.table_name*

, TIME_WAITED_MICRO

 

FROM v$session_event

   与实时SQL监视相关的系统视图包括:

Where sid = '278'

uV$SQL_MONITOR

ORDER BY SID, TIME_WAITED DESC

uV$SQL_PLAN_MONITOR

--依靠sid,可以抓取这个session最近的event时间总和

uV$ACTIVE_SESSION_HISTORY

SELECT

uV$SESSION

SID, SEQ#, EVENT, WAIT_TIME, SECONDS_IN_WAIT, STATE, p1, p1text, p2,

uV$SESSION_LONGOPS

p2text, p3, p3text FROM v$session_wait

uV$SQL

WHERE sid = '278'

uV$SQL_PLAN

ORDER BY SID, SECONDS_IN_WAIT DESC

对于刚刚监视的结果,可以使用DBMS包读取:

--这个是查找sid的wait event

select dbms_sqltune.report_sql_monitor from dual;

SELECT LK.SID, SE.USERNAME, SE.OSUSER, SE.MACHINE, DECODE(LK.TYPE, 'TX', 'Transaction', 'TM', 'DML', 'UL', 'PL/SQL User Lock', LK.TYPE) LOCK_TYPE, DECODE(LK.LMODE, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(LK.LMODE)) MODE_HELD, DECODE(LK.REQUEST, 0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(LK.REQUEST)) MODE_REQUESTED, TO_CHAR(LK.ID1) LOCK_ID1, TO_CHAR(LK.ID2) LOCK_ID2, OB.OWNER, OB.OBJECT_TYPE, OB.OBJECT_NAME, DECODE(LK.BLOCK, 0, 'No', 1, 'Yes', 2, 'Global') BLOCK, SE.LOCKWAIT

 

FROM V$LOCK LK

1.实时SQL监视示例1-执行超过5秒的SQL

INNER JOIN V$SESSION SE ON LK.SID = SE.SID

  图片 17

LEFT JOIN DBA_OBJECTS OB ON LK.ID1 = OB.OBJECT_ID

 

WHERE LK.TYPE IN ('TM', 'UL', 'TX')

 在OEM中查看监视结果,选择“性能”->“其它监视链接”->“SQL Monitoring”:

AND (LK.SID = '278');

  图片 18

--当前sid的lock状况,当然啦,如果把最后的条件去掉,那就是当前数据库的全局lock状况.

 

SELECT * FROM v$session_longops;

 

--表扫描状态

 查看具体的监视报告(图形化):

/*******************************************************************/

  图片 19

/************************下面是trace部分****************************/

单击“文本报告”,则:

/*******************************************************************/

图片 20

ALTER SESSION SET timed_statistics=true;

使用DBMS包查看监视结果:

ALTER SESSION SET max_dump_file_size=unlimited;

  图片 21

ALTER SESSION SET tracefile_identifier='my_trace_session';

2.实时SQL监视示例2-使用优化提示强制监视

--几个相关的参数

  图片 22

--正常情况,一般都是直接上10046

图片 23 图片 24   

ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';

结论:

ALTER SESSION SET EVENTS '10046 trace name context off';

1.实时SQL监视通过OEM查看其监视报告时,具有更好的图形化的展示效果,因此更加直观

exec dbms_monitor.serv_mod_act_trace_enable(service_name=>' ', module_name=>' ');

2.如果监视的SQL语句发现具有全表扫描等执行计划的特征,或者CPU时间和I/O时间比较长,则可以与SQL调优顾问接合起来,不但能获知性能瓶颈,而且能获得Oracle推荐的优化策略。

--使用 SERVICE_NAME,module_name来跟踪

3.实践中,程序员往往不加思考的按照自己的理解和经验编写SQL,此举在90%的项目中存在,从而造成项目产品投用后很快就产生各种性能瓶颈,正确的做法应该是 在准备好足够的测试数据,并且监视每一条SQL并在开发的初始阶段即 优化之

exec dbms_monitor.client_id_trace_enable(client_id=>' ');

 

-- 使用CLIENT_IDENTIFIER来跟踪

 

exec dbms_monitor.session_trace_enable(139);

习题

--如果定位得到session_id的话,就可以直接依靠session_ID跟踪

1.在对索引的限制中,关于NOT和不等于的限制在11g数据库CBO模式下还存在吗,为什么?在RBO模式下呢?

CREATE OR REPLACE TRIGGER trace_test_user AFTER LOGON ON DATABASE

2.如果某个索引中的列具有可空属性,则Oracle执行类似 is null时不会使用索引,其原因是什么?

BEGIN

3.Oralce具有那三种访问路径,其中最快的两种是什么?

IF USER LIKE '%_test' ESCAPE '' THEN

4.什么情况下应该使用复合索引,此时使用复合索引比使用多个单个索引具有哪些优势?

EXECUTE IMMEDIATE 'ALTER SESSION SET timed_statistics=true';

5.分别配置并使用SQL优化常用的三种工具:Autotrace、调优顾问和实时监视顾问,复习本课的举例来加深理解。

EXECUTE IMMEDIATE 'ALTER SESSION SET max_dump_file_size=unlimited';

EXECUTE IMMEDIATE 'ALTER SESSION SET EVENTS ''10046 trace name context forever, level 8'' ';

END IF;

END;

/

-- 代码来自《Optimazing Oracle Performance》 P116

--触发器来做trace,一般属于最后的杀手锏.

/***********通过OS PID,使用oradebug来做trace**************/

SELECT S.USERNAME,

P.SPID OS_PROCESS_ID,

P.PID ORACLE_PROCESS_ID

FROM V$SESSION S, V$PROCESS P

WHERE S.PADDR = P.ADDR

--先找出OS PID

oradebug setospid 9999;

--set os PID

oradebug unlimit;

-- 设置Trace文件大小

oradebug event 10046 trace name context forever ,level 12;

-- 开启级别为12的Trace

Oradebug event 10046 trace name context off;

--关闭trace

/*使用DBMS_SYSTEM.SET_EV包, 也可以进行基于SID,SERIAL的跟踪*/

EXEC SYS.DBMS_SYSTEM.SET_EV(:sid, :serial, 10046, 12, '');

-- 开启level 12的Trace

EXEC SYS.DBMS_SYSTEM.SET_EV(:sid, :serial, 10046, 0, '');

-- 关闭Trace

/*DBMS_SUPPORT包默认情况下并没有包含在数据库中,需要通过运行$ORACLE_HOME/rdbms/admin/dbmssupp.sql 安装之后才能使用。*/

--开启自身进程:

EXEC SYS.DBMS_SUPPORT.START_TRACE(true, true);

EXEC SYS.DBMS_SUPPORT.STOP_TRACE();

--开启其他的进程

EXEC SYS.DBMS_SUPPORT.START_TRACE_IN_SESSION(:sid, :serial, true, true);

EXEC SYS.DBMS_SUPPORT.STOP_TRACE_IN_SESSION(:sid, :serial);

/*******************************使用DBMS_MONITOR包************************************/

--当前

EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(WAITS=>true,BINDS=>true);

EXEC DBMS_MONITOR.SESSION_TRACE_DISABLE();

--其他的进程

EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(:sid, :serial, true, true);

EXEC DBMS_MONITOR.SESSION_TRACE_DISABLE(:sid, :serial);

--依靠client_identifier来trace

EXECUTE DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE('client_name', true, true);

EXECUTE DBMS_MONITOR.CLIENT_ID_TRACE_DISABLE('client_name');

/*************************************数据库级的trace**********************************/

EXEC DBMS_MONITOR.DATABASE_TRACE_ENABLE(true, true);

EXEC DBMS_MONITOR.DATABASE_TRACE_DISABLE(); 

本文由10bet手机官网发布于面向对象,转载请注明出处:常用优化工具,诊断及定位问题根源

上一篇:Whois 的PHP代码 下一篇:没有了
猜你喜欢
热门排行
精彩图文