当前位置: 首页 > news >正文

爱站seo工具在线制作图片生成器小程序

爱站seo工具,在线制作图片生成器小程序,wordpress图片比例拉伸,做网站哪里的服务器速度快梁敬彬梁敬弘兄弟出品 往期回顾 论索引影响性能的一面①索引的各种开销 论索引影响性能的一面②索引的使用失效 论索引影响性能的一面③ 索引开销与经典案例 开篇#xff1a;DBA的深夜“寻人启事” 作为数据库的守护者#xff0c;我们最信赖的伙伴莫过于“索引”。它如同一…梁敬彬梁敬弘兄弟出品 往期回顾 论索引影响性能的一面①索引的各种开销 论索引影响性能的一面②索引的使用失效 论索引影响性能的一面③ 索引开销与经典案例 开篇DBA的深夜“寻人启事” 作为数据库的守护者我们最信赖的伙伴莫过于“索引”。它如同一位效率超群的图书管理员能于浩如烟海的数据中精准地为我们取出所需的那一页。但你是否也曾遇到过这样的“灵异事件”明明为它精心创建了索引性能却依旧惨不忍睹执行计划里那个熟悉的身影消失不见取而代之的是令人绝望的“全表扫描”TABLE ACCESS FULL。 索引失踪了到底去哪儿了 这并非灵异故事而是一系列潜藏在日常操作中的“性能悬案”。今天我们将化身侦探深入四个经典的“案发现场”揭开索引失踪的秘密。 悬案一like与 %间一波三折的故事 案情简介 江湖传言“LIKE一出索引必废”。这个说法流传甚广让许多开发者谈%色变。但这究竟是真相还是误解让我们用证据说话。 现场勘查与证据收集 首先我们准备“案发现场”——一张T表并在OBJECT_NAME列上建立索引。 drop table t purge; create table t as select * from dba_objects where object_id is not null; set autotrace off update t set object_idrownum; update t set object_nameAAALJB where object_id8; update t set object_nameLJBAAA where object_id10; commit; create index idx_object_name on t(object_name); SET AUTOTRACE ON SET LINESIZE 10001. 场景一前缀匹配查询 (‘LJB%’) select object_name,object_id from t where object_name like LJB%;OBJECT_NAME OBJECT_ID ------------------------------------------------------------------------------------- LJBAAA 10 LJB_TMP_SESSION 72521 LJB_TMP_SESSION 72910 LJB_TMP_TRANSACTION 72522 LJB_TMP_TRANSACTION 72911 已选择5行。执行计划 -------------------------------------------------------------------------------------- | Id |Operation | Name |Rows | Bytes | Cost (%CPU)| Time | | 0 |SELECT STATEMENT | | 5| 395 | 6 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 5| 395 | 6 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IDX_OBJECT_NAME | 5| | 3 (0)| 00:00:01 | -------------------------------------------------------------------------------------- 统计信息 ----------------------------------------------------------0 recursive calls0 db block gets9 consistent gets0 physical reads0 redo size602 bytes sent via SQL*Net to client415 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)5 rows processed破案分析 索引健在且表现优异 INDEX RANGE SCAN索引范围扫描赫然在列。like LJB%这种前缀匹配Oracle可以精准定位到索引树中“LJB”的位置开始扫描当然能用到索引。 2. 场景二模糊匹配查询 (‘%LJB%’) select object_name,object_id from t where object_name like %LJB%;执行计划 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 12 | 948 | 292 (1)| 00:00:04 | |* 1 | TABLE ACCESS FULL| T | 12 | 948 | 292 (1)| 00:00:04 | --------------------------------------------------------------------------------------统计信息 ----------------------------------------------------------0 recursive calls0 db block gets1049 consistent gets0 physical reads0 redo size653 bytes sent via SQL*Net to client415 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)6 rows processed破案分析 索引“人间蒸发” TABLE ACCESS FULL出现了。因为前导%的存在Oracle不知道检索何时能停下来只能放弃索引选择全表扫描。 3. 场景三后缀匹配的“曲线救国” (‘%LJB’) 正常情况下后缀匹配与模糊匹配原理相似无法使用常规索引。但我们可以通过reverse函数和函数索引巧妙破局。 create index idx_reverse_objname on t(reverse(object_name)); set autotrace on select object_name,object_id from t where reverse(object_name) like reverse(%LJB);OBJECT_NAME OBJECT_ID ------------------------------------------------------------------------------------- AAALJB 8执行计划 -------------------------------------------------------------------------------------- |Id |Operation |Name |Rows |Bytes |Cost (%CPU)| Time | | 0|SELECT STATEMENT | | 3596| 509K| 290 (0)| 00:00:04 | | 1| TABLE ACCESS BY INDEX ROWID|T | 3596| 509K| 290 (0)| 00:00:04 | |* 2| INDEX RANGE SCAN |IDX_REVERSE_OBJNAME| 647| | 6 (0)| 00:00:01 | -------------------------------------------------------------------------------------- 统计信息 ----------------------------------------------------------0 recursive calls0 db block gets5 consistent gets0 physical reads0 redo size496 bytes sent via SQL*Net to client415 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed悬案二move命令引发的“血案” 案情简介 这是一起发生在某大型制造业系统的真实“血案”。一个看似无害的ALTER TABLE … MOVE操作竟导致系统核心查询性能骤降业务近乎瘫痪。 现场勘查与证据收集 drop table t_p cascade constraints purge; drop table t_c cascade constraints purge; CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30)); ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID); CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30)); ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID); INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES; INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) 1, OBJECT_NAME FROM ALL_OBJECTS; COMMIT; CREATE INDEX IND_T_C_FID ON T_C (FID);-- 检查索引初始状态 SELECT TABLE_NAME,INDEX_NAME,STATUS FROM USER_INDEXES WHERE INDEX_NAMEIND_T_C_FID; TABLE_NAME INDEX_NAME STATUS -------------------- -------------------- -------- T_C IND_T_C_FID VALID-- 执行一个“不小心”的操作 ALTER TABLE T_C MOVE;-- 再次检查索引状态 SELECT TABLE_NAME,INDEX_NAME,STATUS FROM USER_INDEXES WHERE INDEX_NAMEIND_T_C_FID; TABLE_NAME INDEX_NAME STATUS -------------------- -------------------- -------- T_C IND_T_C_FID UNUSABLE破案分析 凶手正是MOVE命令 MOVE操作改变了表中所有行的ROWID而索引中存储的恰恰是旧的ROWID。Oracle为了避免数据错乱将该索引标记为UNUSABLE。这个“暗杀”是无声的操作本身不报错但索引已悄然“死亡”。 受害者索引失效后的查询 SET LINESIZE 1000 SET AUTOTRACE TRACEONLY SELECT A.ID, A.NAME, B.NAME FROM T_P A, T_C B WHERE A.ID B.FID AND A.ID 880;执行计划 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 25 | 1500 | 111 (1)| 00:00:02 | | 1 | NESTED LOOPS | | 25 | 1500 | 111 (1)| 00:00:02 | | 2 | TABLE ACCESS BY INDEX ROWID| T_P | 1 | 30 | 0 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN | T_P_ID_PK | 1 | | 0 (0)| 00:00:01 | |* 4 | TABLE ACCESS FULL | T_C | 25 | 750 | 111 (1)| 00:00:02 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ---------------------------------------------------3 - access(A.ID880)4 - filter(B.FID880)统计信息 ----------------------------------------------------------0 recursive calls0 db block gets394 consistent gets0 physical reads0 redo size3602 bytes sent via SQL*Net to client459 bytes received via SQL*Net from client6 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)72 rows processed对T_C表执行了TABLE ACCESS FULL逻辑读高达394。 “救治”方案与效果 ALTER INDEX IND_T_C_FID REBUILD;-- 再次执行查询 SELECT A.ID, A.NAME, B.NAME FROM T_P A, T_C B WHERE A.ID B.FID AND A.ID 880;执行计划 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 72 | 4320 | 87 (0)| 00:00:02 | | 1 | NESTED LOOPS | | 72 | 4320 | 87 (0)| 00:00:02 | | 2 | TABLE ACCESS BY INDEX ROWID| T_P | 1 | 30 | 0 (0)| 00:00:01 | |* 3 | INDEX UNIQUE SCAN | T_P_ID_PK | 1 | | 0 (0)| 00:00:01 | | 4 | TABLE ACCESS BY INDEX ROWID| T_C | 72 | 2160 | 87 (0)| 00:00:02 | |* 5 | INDEX RANGE SCAN | IND_T_C_FID | 72 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ---------------------------------------------------3 - access(A.ID880)5 - access(B.FID880)统计信息 ----------------------------------------------------------0 recursive calls0 db block gets81 consistent gets0 physical reads0 redo size3602 bytes sent via SQL*Net to client459 bytes received via SQL*Net from client6 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)72 rows processed侦探笔记 ALTER TABLE … MOVE是一个极其危险的操作。操作规范在执行MOVE后必须立即REBUILD该表上的所有索引。 悬案三外键索引失效引发的“幽灵锁” 案情简介 如果说上一个案例是MOVE命令造成的直接性能伤害那么这个案例则是它更隐蔽、更阴险的“并发症”——锁等待。 现场勘查与证据收集 -- 准备环境 drop table t_p cascade constraints purge; drop table t_c cascade constraints purge; CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30)); ALTER TABLE T_P ADD CONSTRAINT T_P_ID_PK PRIMARY KEY (ID); CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30)); ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID); INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES; INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) 1, OBJECT_NAME FROM ALL_OBJECTS; COMMIT; -- 注意这里没有给外键列T_C(FID)创建索引-- 以下操作导致外键相关的索引失效此处原文为move但实际场景是未创建索引 -- ALTER TABLE T_C MOVE;并发测试 -- 首先开启会话1 select sid from v$mystat where rownum1; DELETE T_C WHERE ID 2;-- 接下来开启会话2也就是开启一个新的连接 select sid from v$mystat where rownum1; DELETE T_P WHERE ID 2000; -- 居然发现卡住半天不动了破案分析 这起“幽灵锁”的根源在于外键约束的底层工作机制。当你操作主表如DELETE T_P时Oracle必须确保子表中没有任何记录引用你将要删除的主表记录。 索引有效时 Oracle会通过外键列上的索引快速检查子表T_C中是否存在FID 2000的记录。 索引失效或不存在时 Oracle无法快速检查只能在子表T_C上施加一个全表锁然后慢慢地进行全表扫描。当会话1持有T_C的行级锁时会话2想要获取全表锁自然会被阻塞。 侦探笔记 外键列上必须建立索引并保证其永远有效 这不仅是查询性能的需要更是保证高并发环境下系统稳定性的“生命线”。 悬案四shrink操作后的“伪装者” 案情简介 既然MOVE如此危险那我们用更现代的SHRINK命令来收缩表空间总该安全了吧它确实能避免索引失效但新的问题又来了索引明明VALID优化器为何依然弃之不用 现场勘查与证据收集 drop table t purge; create table t as select * from dba_objects where object_id is not null; alter table t modify object_id not null; set autotrace off insert into t select * from t; insert into t select * from t; commit; create index idx_object_id on t(object_id); set linesize 1000 set autotrace on select count(*) from t; set autotrace off delete from t where rownum292000; commit; set autotrace on alter table t enable row movement; alter table t shrink space; select count(*) from t;执行计划 ------------------------------------------------------------------------------------ Plan hash value: 2966233522 | Id | Operation | Name | Rows | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 1 | 5 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| T | 740 | 5 (0)| 00:00:01 | ------------------------------------------------------------------------------------统计信息 ----------------------------------------------------------0 recursive calls0 db block gets15 consistent gets0 physical reads0 redo size424 bytes sent via SQL*Net to client415 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed破案分析 索引再次“失踪”它明明状态VALID为何被优化器无情抛弃我们强制让它走索引使用hint看看。 select /*index(t)*/ count(*) from t;执行计划 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | | 0 | SELECT STATEMENT | | 1 | 675 (1)| 00:00:09 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FULL SCAN| IDX_OBJECT_ID | 740 | 675 (1)| 00:00:09 | -------------------------------------------------------------------------------------- 统计信息 ----------------------------------------------------------0 recursive calls0 db block gets649 consistent gets0 physical reads0 redo size424 bytes sent via SQL*Net to client415 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed真相大白强制走索引的成本Cost675逻辑读649远高于走全表扫描Cost5逻辑读15。原因在于SHRINK操作虽然收缩了表但并未有效地收缩索引段的空间。 大量DELETE操作在索引中留下了许多“空洞”导致索引变得稀疏而“臃肿”扫描它反而得不偿失。 侦探笔记 索引的VALID状态仅仅是它的“准入证”并不代表它的“健康证”。一个因大量删除而变得臃肿的索引即便有效也可能成为性能的拖累。在这种情况下ALTER INDEX … REBUILD 才是整理索引碎片、恢复其紧凑结构和高性能的“特效药”。 总结 今天的调查到此告一段落。我们揭开了四个导致索引“失踪”或“失效”的经典悬案 伪装者LIKE 被前导通配符%所迷惑。 刺客MOVE 无声地让索引状态变为UNUSABLE。 帮凶“无索引外键” 在并发操作中制造“幽灵锁”。 “亚健康”的SHRINK后遗症 索引虽在却因臃肿而被优化器嫌弃。 然而索引失踪之谜远未结束。在下一集中我们将继续追踪另外四位“嫌疑人”它们同样狡猾同样致命。敬请期待《索引失踪之谜下》。 未完待续… 论索引影响性能的一面⑤索引失踪之谜下 系列回顾 “大白话人工智能” 系列 “数据库拍案惊奇” 系列 “世事洞明皆学问” 系列
http://www.hkea.cn/news/14289385/

相关文章:

  • 成都建站模板公司网站建设卖点
  • 彩妆网站建设策划书网站建设主要问题及建议
  • 昆明网站设计制作公司网址建站
  • 如何做网站静态页面企业文化建设方案案例
  • 家政月嫂网站源码html5商城网站
  • 成都网站建设选择到访率企业宣传类网站建设
  • 建设一个视频网站需要什么站酷app
  • 昆明网站建设时间课程资源网站的建设
  • 狐表做网站西宁最好的网络公司
  • 河北建设网站信息查询中心网络服务商怎么找
  • 网站开发语言那个好黄骅港天气预报
  • 怎么做旅游网站自己做网站接入微信和支付宝
  • 无锡滨湖住房与城乡建设局网站阿里云服务器搭建网站
  • 网站色彩的应用免费网站建设必择山东绘政科技
  • 推广策划案怎么写北京百度seo服务
  • 谷歌有做网站建设中山 家居 骏域网站建设专家
  • 郑州港区建设投资公司网站做健身网站
  • 做网站需要的信息网站建设管理和运行维护制度
  • jsp mysql 网站开发wordpress hls
  • 广西北海市住房和建设厅网站tripod wordpress
  • 临湘市建设局网站网站怎么做定位功能
  • Php做网站创业母婴用品网站建设
  • 房产网站怎么做异地楼盘nginx wordpress 多站点
  • 咸宁网站设计如何拥有自己的域名
  • 保定建设网站科技广告公司网站模板
  • 昌邑微信网站建设公司设计公司网站多少钱
  • 电脑做网站服务器教程做外贸网站 用国外空间 还是 国内空间 区别
  • 商城型网站建设多少钱注册公司费用计入什么科目
  • 广州手机网站建设哪家好软件外包合同模板
  • 河北省网站建设公司住房和城乡建设部网站安广东省