materialized view(1)

  1. 这两天偶然发现两个导致物化视图无法快速刷新的原因刷新,这两个原因在Oracle的文档上并没有明确给出,在MV_CAPABILITIES_TABLE中给出的msgno在文档中也找不到对应的说明。
  2. 下面做两个简单的例子重新这两个错误:
  3. SQL> CREATE TABLE TEST AS SELECT MOD(ROWNUM, 5) COL1, ROWNUM COL2 FROM ALL_OBJECTS;
  4. 表已创建。
  5. SQL> CREATE MATERIALIZED VIEW LOG ON TEST WITH ROWID, SEQUENCE (COL1, COL2) INCLUDING NEW VALUES;
  6. 实体化视图日志已创建。
  7. SQL> CREATE MATERIALIZED VIEW MV_TEST REFRESH FAST AS SELECT COL1, SUM(COL2), COUNT(COL2), COUNT(*)
  8. 2 FROM TEST GROUP BY COL1;
  9. 实体化视图已创建。
  10. 上面建立的这个简单的物化视图显然是可以快速刷新的,下面做点变化,建立一个指向基表的同义词,然后建立物化视图的时候指向同义词。
  11. SQL> CREATE SYNONYM C_TEST FOR TEST;
  12. 同义词已创建。
  13. SQL> DROP MATERIALIZED VIEW MV_TEST;
  14. 实体化视图已删除。
  15. SQL> CREATE MATERIALIZED VIEW MV_TEST REFRESH FAST AS SELECT COL1, SUM(COL2), COUNT(COL2), COUNT(*)
  16. 2 FROM C_TEST GROUP BY COL1;
  17. FROM C_TEST GROUP BY COL1
  18. *
  19. ERROR 位于第 2 行:
  20. ORA-12015: cannot create a fast refresh materialized view from a complex query
  21. 现在出现错误了,检查一下错误原因:
  22. SQL> BEGIN
  23. 2 DBMS_MVIEW.EXPLAIN_MVIEW('SELECT COL1, SUM(COL2), COUNT(COL2), COUNT(*)
  24. 3 FROM C_TEST GROUP BY COL1');
  25. 4 END;
  26. 5 /
  27. PL/SQL 过程已成功完成。
  28. SQL> COL MSGTXT FORMAT A80
  29. SQL> SELECT MSGNO, MSGTXT FROM MV_CAPABILITIES_TABLE 
  30. 2 WHERE CAPABILITY_NAME = 'REFRESH_FAST_AFTER_INSERT';
  31. MSGNO MSGTXT
  32. ---------- ---------------------------------------------------------------
  33. 2101 mv references a synonym in the FROM list
  34. 很显然是由于引用了同义词造成的,但是这个错误很奇怪,首先Oracle的文档里并没有明确说明不能引用同义词(也可能是我没有看到),而且Oracle的文档中也没有看到2101的错误。
  35. 对这个错误的解决方法就是不要使用同义词,直接使用基表,当然如果非要利用同义词来达到隐藏基表的目的,可以考虑使用视图代替,入下例,当然,视图和同义词还是有很多差别的,这里就不再讨论了。
  36. SQL> CREATE VIEW V_TEST AS SELECT * FROM TEST;
  37. 视图已建立。
  38. SQL> CREATE MATERIALIZED VIEW MV_TEST REFRESH FAST AS SELECT COL1, SUM(COL2), COUNT(COL2), COUNT(*)
  39. 2 FROM V_TEST GROUP BY COL1;
  40. 实体化视图已创建。
  41. 下面看第二个问题:
  42. SQL> CREATE TABLE TEST1 AS SELECT * FROM TEST;
  43. 表已创建。
  44. SQL> CREATE MATERIALIZED VIEW LOG ON TEST1 WITH ROWID, SEQUENCE (COL1, COL2) INCLUDING NEW VALUES;
  45. 实体化视图日志已创建。
  46. SQL> CREATE MATERIALIZED VIEW MV_TEST_TEST1 REFRESH FAST AS
  47. 2 SELECT A.ROWID A_ROWID, B.ROWID B_ROWID, A.COL1, A.COL2||B.COL2 COL2 
  48. 3 FROM TEST A, TEST1 B
  49. 4 WHERE A.COL2 = B.COL2;
  50. FROM TEST A, TEST1 B
  51. *
  52. ERROR 位于第 3 行:
  53. ORA-12015: cannot create a fast refresh materialized view from a complex query
  54. SQL> TRUNCATE TABLE MV_CAPABILITIES_TABLE;
  55. 表已截掉。
  56. SQL> BEGIN
  57. 2 DBMS_MVIEW.EXPLAIN_MVIEW('SELECT A.COL1, A.COL2||B.COL2 COL2 FROM TEST A, TEST1 B
  58. 3 WHERE A.COL2 = B.COL2');
  59. 4 END;
  60. 5 /
  61. PL/SQL 过程已成功完成。
  62. SQL> SELECT MSGNO, MSGTXT FROM MV_CAPABILITIES_TABLE 
  63. 2 WHERE CAPABILITY_NAME = 'REFRESH_FAST_AFTER_INSERT';
  64. MSGNO MSGTXT
  65. ---------- ---------------------------------------------------------------
  66. 2113 expression in select list references multiple tables or views
  67. 2061 one or more joins present in mv
  68. 这个解释描述的也比较清楚,一个表达式同时参考了多个表。对于同一个中的字段是可以进行‘||’操作的。
  69. SQL> CREATE MATERIALIZED VIEW MV_TEST_TEST1 REFRESH FAST AS
  70. 2 SELECT A.ROWID A_ROWID, B.ROWID B_ROWID, A.COL1, 
  71. 3 A.COL2||A.COL1 COL2, B.COL1||B.COL2 COL3
  72. 4 FROM TEST A, TEST1 B
  73. 5 WHERE A.COL2 = B.COL2;
  74. 实体化视图已创建。
  75. 但是,同样Oracle在文档中并没有说明这一点,上面的两个MSGNO号码在文档中也是找不到对应关系的。怀疑Oracle的msgno是连续的或者基本上是连续的,也就是说,还有很多类似的原因会导致Oracle的物化视图无法刷新,只是不清楚Oracle为什么没有写在文档中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值