Oracle 分页查询在子查询中使用了 排序和like 会影响效率吗? 怎样优化呢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 分页查询在子查询中使用了 排序和like 会影响效率吗? 怎样优化呢相关的知识,希望对你有一定的参考价值。

像是这样写的。
SELECT * FROM (SELECT A.*,Rownum rn FROM
(SELECT * FROM tb_one where
id1 like 'xy%'
and name in (select name from tb_one where id2 like 'xy%')
and to_char(INSTIME,'yyyy-mm-dd hh24:mi:ss')>='2013-1-8 00:00:00'
and to_char(INSTIME,'yyyy-mm-dd hh24:mi:ss')<='2013-1-8 23:59:59' order by INSTIME desc) A
WHERE ROWNUM <=20 ) WHERE rn >=10 ;
解决的话有加分。谢谢各位了
and name in (select name from tb_one where id2 like 'xy%')

这一行的 tb_one 是另外一个表 写错了 ,当作tb_two 就好,like 'xy%' 里面 xy 可能是其他输入的值,比如 ‘ab%’

参考技术A 1。 看能不能建立索引(和其他几位仁兄一致)
2。 能否不用like 如果tb_one中的id2不是主键也不是索引,可以改为substr(id2,1,2) = 'xy'
3。 排序尽量不要,既然LZ说了这是前提那就省略不说
4。 加hint并行处理(这个会提高不少,但需要数据库开启并行,并且硬件足以支持)
5。 这个肯定是全表扫描,不用想(都like了)
6。 根据你的时间条件,可以写成substr(instime) = '20130108'
7。 加表别名,并不要使用星号
9。 少些几个子查询。。。
参考技术B 如果数据量非常大的情况下一般都建立有索引,而like模糊查询是会影响索引的检索效率,所以最好不要用like。
另外写查询语句时尽量避免用select *,一般将需要显示的列select出来就ok
参考技术C SELECT * FROM (SELECT A.*,Rownum rn FROM
(SELECT * FROM tb_one where
id1 like 'xy%'
and name in (select name from tb_one where id2 like 'xy%')
and INSTIME>=to_date('2013-1-8 00:00:00','yyyy-mm-dd hh24:mi:ss')
and INSTIME<=to_date('2013-1-8 23:59:59','yyyy-mm-dd hh24:mi:ss') order by INSTIME desc) A
WHERE ROWNUM <=20 ) WHERE rn >=10 ;
name、instime上都要创建索引追问

name索引是创建在tb1 还是tb2呢?另外 like 模糊查询 和 order by 会影响效率吗?

追答

条件中使用的name应该是tb1表里的字段,like和order by肯定会对效率有影响,但是如果你的需求就是这样的话,那就没办法了
如果数据量不太大的话,速度应该可以接受

追问

需求模糊查询跟排序 并且是大表呀(至少几百万数据)。 查询时间过长。like会全表查询吗?
还能怎样提高效率,或者有优化的sql 语句呢?如果不排序怎样快速取出tb1表前10条记录?谢谢

追答

这需要分析你的执行计划才行,是不是全表扫描,都要看执行计划才能知道
如果不排序取前10条,那么
select * from tb1 where rownum<=10就可以了

追问

模糊查询是一定会全表扫描吗?有什么建议吗? 排序也会全表扫描吗?谢谢

追答

是不是全表扫描最终要看你的执行计划,like语句也可能会用到索引,比如like 'xy%'这种方式,就有可能会用到索引
另外排序也可能使用到索引,但是效率很低,这些都要看你的执行计划来分析,光看语句是看不出来的

本回答被提问者采纳

在子查询中排序

【中文标题】在子查询中排序【英文标题】:Order by inside a subquery 【发布时间】:2011-07-20 18:14:23 【问题描述】:
SELECT u.id
FROM user u
WHERE u.id IN 
((SELECT l.id FROM location l WHERE l.id = ?id ORDER BY l.idLocation DESC )) 

我想要做的是让这个 Order By 工作。但是不可能在视图中进行排序。如果不在视图内,我该如何执行此命令?

SQL 响应:

Msg 1033, Level 15, State 1, Line 5 ORDER BY 子句在 视图、内联函数、派生表、子查询和公用表 表达式,除非还指定了 TOP 或 FOR XML。

【问题讨论】:

你的意思是子查询吗?我在这里看不到风景。 我看不出使ORDER BY 工作对输出有何影响。你能给我们举个例子说明你现在得到的输出,以及你希望它有什么不同吗?在 IN 声明中,ORDER BY 即使“有效”也不太重要,因此您会得到一些令人困惑的答案。 +1 @ChrisCunningham - OP,从原始查询中不清楚您希望结果的顺序,因为您只是检查 u.id 是否在子选择的结果中。 【参考方案1】:

这里有两个问题。

1 - 您的ORDER BY 毫无意义。当您使用IN 子查询时,ORDER 无关紧要。

2 - 视图的ORDER BY 应该在调用查询中,而不是在视图本身中。

【讨论】:

【参考方案2】:

你不能。只有最外层 ORDER BY 很重要。

所以SELECT * FROM MyView ORDER By Whatever唯一的方式。

任何中间顺序(无论是 ORDER BY 还是巧合,还是局域网的一部分)都被忽略

【讨论】:

谢谢。可怜我,那我得另找办法了。 @pringlesinn - 做什么? - 这是目前最大的谜。 如果我有一个文章表,我需要按 A-Z 或 Z-A 顺序显示它们,但我也想一次选择 100 个。 ORDER BY 外部仅订购选定的 100 个。如何为所有人执行此操作? 这是不正确的。许多情况都受益于内部ORDER BY。分页查询是一个常见的例子。子查询中的排序获取在表范围内排序的行。最外层的 ORDER BY 订单只在最终结果的范围内。【参考方案3】:

我与之前的答案一样认为在子查询中执行order by 通常不是一个好主意。但是,我发现这样做有时非常有用。我假设 pringlesinn 的问题中的示例查询是更复杂要求的一个简单示例。您可以通过这种方式在子查询中执行order by

SELECT u.id
FROM user u
WHERE exists
(SELECT ROW_NUMBER() OVER (ORDER BY l.idLocation DESC) FROM location l WHERE u.id = l.id and l.id = ?id) 

但是您会注意到 WHERE 子句不再使用“IN”运算符。相反,您必须使用“EXISTS”并执行相关的子查询。或者你可以这样做:

SELECT u.id
FROM user u inner join 
  (
    SELECT ROW_NUMBER() OVER (ORDER BY l.idLocation DESC) as rowid, l.id 
    FROM location l 
    WHERE l.id = ?id
  ) as z on z.id = u.id

最好的祝愿, 詹姆斯

【讨论】:

gbn 所述,order by 在内部查询中被忽略。我检查了这两个代码 sn-ps 的执行计划,order by 似乎被消除了。然而,我确实记得在更复杂的情况下使用上述方法是完成任务的最佳方式。祝你好运!【参考方案4】:

在子查询中不需要使用ORDER BY

如果您想在视图中添加ORDER BY,您可以在视图中添加TOP(100) PERCENT,然后您就可以使用它了。

http://cf-bill.blogspot.com/2007/01/sql-server-order-view.html

【讨论】:

以上是关于Oracle 分页查询在子查询中使用了 排序和like 会影响效率吗? 怎样优化呢的主要内容,如果未能解决你的问题,请参考以下文章

在子查询和别名中排序

Oracle分页查询中排序与效率问题

解决Oracle分页查询中排序与效率问题

oracle 分页查询重复问题

oracle 分页查询数据重复问题

oracle 高效分页查询SQL