前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Oracle with内嵌视图优化一例

使用Oracle with内嵌视图优化一例

作者头像
用户1148526
发布2019-05-25 19:45:07
6210
发布2019-05-25 19:45:07
举报
文章被收录于专栏:Hadoop数据仓库

需求:

  1. 有分类、物资、分类/物资关系三个表,要求按树的遍历方式查询出分类ID、分类/物资名称、从根到当前节点的路径。
  2. 一个分类下的物资显示在该分类下,同一级分类按序号排序,一个分类下的物资按创建时间排序。

[sql] view plain copy

  1. -- 创建分类表
  2. CREATE TABLE tab_class
  3. (
  4. id NUMBER (8) NOT NULL PRIMARY KEY,
  5. p_id NUMBER (8) NOT NULL,
  6. class_name VARCHAR2 (10),
  7. siblings_order NUMBER (4)
  8. );
  9. -- 创建物资表
  10. CREATE TABLE tab_item
  11. (
  12. id NUMBER (8) NOT NULL PRIMARY KEY,
  13. item_name VARCHAR2 (10),
  14. create_time DATE
  15. );
  16. -- 创建分类/物资关系表
  17. CREATE TABLE tab_item_class
  18. (
  19. id NUMBER (8) NOT NULL PRIMARY KEY,
  20. class_id NUMBER (8) NOT NULL,
  21. item_id NUMBER (8) NOT NULL
  22. );
  23. -- 生成1万条分类表数据
  24. DECLARE
  25. p_id NUMBER (8) DEFAULT 0;
  26. class_name VARCHAR2 (10);
  27. BEGIN
  28. FOR i IN 1 .. 10000
  29. LOOP
  30. p_id := FLOOR (SQRT (i - 1));
  31. class_name := SUBSTR (TO_CHAR (DBMS_RANDOM.VALUE), 1, 10);
  32. INSERT INTO tab_class (id,
  33. p_id,
  34. class_name,
  35. siblings_order)
  36. VALUES (i,
  37. p_id,
  38. class_name,
  39. 0);
  40. END LOOP;
  41. UPDATE tab_class tc
  42. SET tc.siblings_order =
  43. (SELECT xx.rn
  44. FROM (SELECT tc2.id,
  45. ROW_NUMBER ()
  46. OVER (PARTITION BY tc2.p_id
  47. ORDER BY tc2.class_name)
  48. rn
  49. FROM tab_class tc2) xx
  50. WHERE xx.id = tc.id);
  51. COMMIT;
  52. END;
  53. /
  54. -- 生成100万条物资表数据
  55. DECLARE
  56. item_name VARCHAR2 (10);
  57. rd_date NUMBER (3);
  58. BEGIN
  59. FOR i IN 1 .. 1000000
  60. LOOP
  61. item_name := SUBSTR (TO_CHAR (DBMS_RANDOM.VALUE), 1, 10);
  62. rd_date := FLOOR (1000 * (DBMS_RANDOM.VALUE - 0.5));
  63. INSERT INTO tab_item (id, item_name, create_time)
  64. VALUES (i, item_name, SYSDATE + rd_date);
  65. END LOOP;
  66. COMMIT;
  67. END;
  68. /
  69. -- 生成分类/物资关系表数据
  70. DECLARE
  71. ic_id NUMBER (8) DEFAULT 1;
  72. class_id NUMBER (8);
  73. item_id NUMBER (8);
  74. c_count NUMBER (2);
  75. BEGIN
  76. FOR item_id IN 1 .. 1000000
  77. LOOP
  78. c_count := FLOOR (10 * DBMS_RANDOM.VALUE) + 1;
  79. FOR i IN 1 .. c_count
  80. LOOP
  81. class_id := FLOOR (10000 * DBMS_RANDOM.VALUE) + 1;
  82. INSERT INTO tab_item_class (id, class_id, item_id)
  83. VALUES (ic_id, class_id, item_id);
  84. ic_id := ic_id + 1;
  85. END LOOP;
  86. END LOOP;
  87. COMMIT;
  88. END;
  89. /
  90. -- 建立索引
  91. CREATE INDEX idx_class_pid
  92. ON tab_class (p_id);
  93. CREATE INDEX idx_ic_class_id
  94. ON tab_item_class (class_id);
  95. CREATE INDEX idx_ic_item_id
  96. ON tab_item_class (item_id);
  97. -- 分析表
  98. ANALYZE TABLE tab_class COMPUTE STATISTICS FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS;
  99. ANALYZE TABLE tab_item COMPUTE STATISTICS FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS;
  100. ANALYZE TABLE tab_item_class COMPUTE STATISTICS FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS;
  101. -- 查询语句1
  102. WITH vs_tree
  103. AS ( SELECT fls.id flid,
  104. fls.class_name name,
  105. SUBSTR (SYS_CONNECT_BY_PATH (siblings_order, '.'), 2) xuhao,
  106. ROWNUM rn
  107. FROM tab_class fls
  108. CONNECT BY PRIOR fls.id = fls.p_id
  109. START WITH fls.p_id = 0
  110. ORDER SIBLINGS BY fls.siblings_order)
  111. SELECT temp.flid, temp.name, temp.xuhao
  112. FROM (SELECT t.flid,
  113. t.name,
  114. t.xuhao,
  115. t.rn,
  116. 0 xx
  117. FROM vs_tree t
  118. UNION ALL
  119. SELECT t.flid,
  120. wz.item_name,
  121. t.xuhao
  122. || '.'
  123. || (ROW_NUMBER ()
  124. OVER (PARTITION BY t.flid ORDER BY wz.create_time ASC))
  125. xuhao,
  126. t.rn,
  127. ROW_NUMBER ()
  128. OVER (PARTITION BY t.flid ORDER BY wz.create_time ASC)
  129. xx
  130. FROM vs_tree, tab_item_class gx, tab_item wz
  131. WHERE wz.id = gx.item_id AND t.flid = gx.class_id) temp
  132. ORDER BY temp.rn, temp.xx;
  133. -- 用时:7分9秒
  134. -- 查询语句2
  135. SELECT flid, name, RTRIM (SUBSTR (xuhao1, 2) || '.' || xx, '.') xuhao
  136. FROM ( SELECT flid,
  137. name,
  138. SYS_CONNECT_BY_PATH (siblings_order, '.') xuhao1,
  139. xx,
  140. ROWNUM rid
  141. FROM (SELECT fls.p_id pid,
  142. fls.id flid,
  143. fls.class_name name,
  144. siblings_order,
  145. 0 xx
  146. FROM tab_class fls
  147. UNION ALL
  148. SELECT t.pid,
  149. t.flid,
  150. wz.item_name,
  151. siblings_order,
  152. rom_number ()
  153. OVER (PARTITION BY t.flid ORDER BY wz.create_time ASC)
  154. xx
  155. FROM (SELECT fls.p_id pid,
  156. fls.id flid,
  157. fls.class_name name,
  158. siblings_order
  159. FROM tab_class fls) t,
  160. tab_item_class gx,
  161. tab_item wz
  162. WHERE wz.id = gx.item_id AND t.flid = gx.class_id) temp
  163. CONNECT BY PRIOR flid = pid
  164. START WITH pid = 0
  165. ORDER SIBLINGS BY siblings_order, xx)
  166. ORDER BY rid;
  167. -- 用时:半小时没出来,中断退出
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年12月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档