oracle – 改进SQL存在可伸缩性

oracle – 改进SQL存在可伸缩性,第1张

概述假设我们有两个表,TEST和TEST_CHILDS,方式如下: creat TABLE TEST(id1 number PRIMARY KEY, word VARCHAR(50),numero number);creat TABLE TEST_CHILD (id2 number references test(id), word2 VARCHAR(50));CREATE INDEX TEST 假设我们有两个表,TEST和TEST_CHILDS,方式如下:

creat table TEST(ID1 number PRIMARY KEY,word VARCHAR(50),numero number);creat table TEST_CHILD (ID2 number references test(ID),word2 VARCHAR(50));CREATE INDEX TEST_IDX ON TEST_CHILD(word2);CREATE INDEX TEST_JOIN_IDX ON TEST_CHILD(ID);insert into TEST SELECT ROWNUM,U1.USERname||U2.table_name,LENGTH(U1.USERname) FROM ALL_USERS U1,ALL_tableS U2;INSERT INTO TEST_CHILD SELECT MOD(ROWNUM,15000)+1,U1.USER_ID||U2.table_name FROM ALL_USERS U1,ALL_tableS U2;

我们想查询从TEST表中获取满足子表中某些条件的行,所以我们选择:

SELECT /*+FirsT_ROWS(10)*/* FROM TEST T WHERE EXISTS (SELECT NulL FROM TEST_CHILD TC WHERE word2 like 'string%' AND TC.ID = T.ID ) AND ROWNUM < 10;

我们总是只想要前10个结果,而不再是结果.因此,我们希望获得相同的响应时间来读取10个结果,无论表有10个匹配值还是1,000,000;因为它可以从子表中获得10个不同的结果并获取父表上的值(或者至少是我们想要的计划).但在检查实际执行计划时,我们看到:

-----------------------------------------------------------------------------------------------| ID  | Operation                       | name        | Rows  | Bytes | Cost (%cpu)| Time     |-----------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT                |             |     1 |    54 |     5  (20)| 00:00:01 ||*  1 |  COUNT StopKEY                  |             |       |       |            |          ||   2 |   nesTED LOOPS                  |             |       |       |            |          ||   3 |    nesTED LOOPS                 |             |     1 |    54 |     5  (20)| 00:00:01 ||   4 |     SORT UNIQUE                 |             |     1 |    23 |     3   (0)| 00:00:01 ||   5 |      table ACCESS BY INDEX ROWID| TEST_CHILD  |     1 |    23 |     3   (0)| 00:00:01 ||*  6 |       INDEX RANGE SCAN          | TEST_IDX    |     1 |       |     2   (0)| 00:00:01 ||*  7 |     INDEX UNIQUE SCAN           | SYS_C005145 |     1 |       |     0   (0)| 00:00:01 ||   8 |    table ACCESS BY INDEX ROWID  | TEST        |     1 |    31 |     1   (0)| 00:00:01 |-----------------------------------------------------------------------------------------------Predicate information (IDentifIEd by operation ID):---------------------------------------------------   1 - filter(ROWNUM<10)   6 - access("WORD2" liKE 'string%')       filter("WORD2" liKE 'string%')   7 - access("TC"."ID"="T"."ID")

在StopKEY下排序UNIQUE,afaik意味着它正在读取子表中的所有结果,使得distinct最终只选择前10个,使得查询不像我们希望的那样可扩展.

我的例子中有任何错误吗?

是否有可能改进这个执行计划,以便更好地扩展?

解决方法 SORT UNIQUE将查找和排序TEST_CHILD中匹配’string%’的所有记录 – 它不会从子表中读取所有结果.你的逻辑需要这个.如果您只从TEST_CHILD中选择了与’string%’匹配的前10行,并且这10行都具有相同的ID,那么来自TEST的最终结果将只有1行.

无论如何,只要’string%’匹配TEST_CHILD中相对较少的行数,您的表现就应该没问题.如果您的情况是’string%’经常匹配TEST_CHILD上的巨大记录数,那么在给定当前表的情况下,您可以做的事情并不多,以使sql更高效.在这种情况下,如果这是一个任务关键型sql,其性能与您的年度奖金相关,那么您可以使用MATERIAliZED VIEW来做一些花哨的步法,例如:在TEST_CHILD中为高基数WORD2值预先计算10个TEST行.

最后一个想法 – 一个“冒险”的解决方案,但如果你没有数千个与同一个TEST行匹配的TEST_CHILD行,它应该可以工作,如下所示:

SELECT  * FROM    TEST WHERE   ID1 IN             (SELECT ID2              FROM   TEST_CHILD              WHERE  word2 like 'string%'                     AND ROWNUM < 1000)          AND ROWNUM <10;

当然,您可以向上或向下调整1000,但如果它太低,您可能会发现少于10个不同的ID值,这将为您提供少于10行的最终结果.

总结

以上是内存溢出为你收集整理的oracle – 改进SQL存在可伸缩性全部内容,希望文章能够帮你解决oracle – 改进SQL存在可伸缩性所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1160843.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存