ACCESS 的 ORDER BY 问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACCESS 的 ORDER BY 问题相关的知识,希望对你有一定的参考价值。
有一个表,其中一个字段是有表达式的,例如 (表达式1)as 列名。
这个时候用order by怎么用? access好像不能直接用 order by 列名。
我用order by (表达式1) 这种方式也不行,没有起到排序的效果。。正确的应该是怎样。。。谢谢!
可能没说的清,现在是这样的
select sum(表1.A) AS B from 表1
order by ?
这个问号这里应该怎么写? 我尝试了用order by B desc 不行,用order by sum(表1.A) desc 也不行。。。
SQL里面是可以直接order by B DESC;就实现了。。access里不知怎么实现不了
现在可以排序了。。但是。。有点差异。。比如数字2,会排在数字100后面。。是按照第一个数字的大小依次排序的。。怎么按照实际数字大小排啊。。
=========回答补充=========
你的表1.A是字符串吗?字符串是按照第一个字符的大小依次排序的.如果是数值型,应该会按照实际数字大小.
还有一般情况下,查询的列不可用于作排序或条件的. 你的SUM函数是对整个列的求和,你怎么排序啊,除非你是分组(group by)求和.
如果真那样,那只能说ACCESS不支持表达式用order by功能落.本回答被提问者采纳 参考技术B 可以的。
正确格式如下:
Select * From Table Order By ID Asc 参考技术C access的排序可以使用表达式
你说的要按数字大小排列,那么你必须保证排序字段是数值型。 参考技术D order by 为指定查询结果的顺序
order by 子句的性能问题
【中文标题】order by 子句的性能问题【英文标题】:Performance issue with order by clause 【发布时间】:2012-02-25 05:46:07 【问题描述】:我有以下查询,它在执行后从 100000000 返回 20000 条记录..
SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (select TIME,url,bytes
FROM (SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS TIME, url, BYTES
FROM available_web_details
WHERE "5mintime" >= TIMESTAMP '2012-02-10 00:00:00'
AND "5mintime" <= TIMESTAMP '2012-02-13 23:59:59'
AND username = 'asha1328874833'
AND CATEGORY = 'None240001'AND domain = '1328874833.vmware.com.'
AND (appid IN ('216.198.204.192id','216.198.207.0id','216.198.211.64id','216.198.211.128id','216.198.212.0id', '216.198.214.128id','216.198.214.192id','216.198.218.0id','216.198.220.192id','216.198.222.0id','216.198.223.32id','216.198.228.128id','216.198.229.128id',.....)))
ORDER BY TIME DESC) a
WHERE ROWNUM <= 10)
WHERE rnum > 0
执行它大约需要 5 分钟。但是当我删除 order by 子句时,它会在 4 秒内执行。您能建议我如何提高性能吗?
available_web_details 架构:
Name Null Type
------------ ---- --------------
5mintime TIMESTAMP(6)
USERNAME VARCHAR2(64)
HOST NUMBER
SRC_ZONE VARCHAR2(32)
DOMAIN VARCHAR2(512)
DST_ZONE VARCHAR2(32)
CONTENT VARCHAR2(64)
CATEGORY VARCHAR2(64)
URL VARCHAR2(1024)
HITS NUMBER
BYTES NUMBER
APPID VARCHAR2(32)
APPLICATION VARCHAR2(64)
CATEGORYTYPE VARCHAR2(64)
USERGROUP VARCHAR2(384)
我在 appid, "5mintime" 上有本地分区的索引。 available_web_details
是1个月的范围分区表。
【问题讨论】:
你考虑过索引吗? @roymustang86:你为什么要把我们的时间浪费在你毫无价值的建议上? 你能去掉rnum > 0
子句吗?我很确定这不会有任何作用。
@eaolson,它的存在是为了让第二页 Asha 可以选择rownum <= 20
的位置然后rownum > 10
的位置
【参考方案1】:
让我们从免责声明开始:如果您不删除 order by
或开始使用临时表,则执行时间永远不会减少到 4 秒。第二个免责声明:我犯了一个大错误,我现在正在纠正;我花了很长时间才意识到这一点。谢谢Alex Poole。
我的观点(我总是有几个)。
在 cmets 中提出了一些非常有效的观点,特别是 DimitryB。如果您一次只显示 10 条记录,则 20,000 行等于 2,000 页。没有人会费心查看所有这些信息。如果不是一两百条,您可以非常安全地将返回的记录数减少到 500 条。
craigmj's answer 提出了同样有效的观点,尽管我想大大扩展它。通过不索引where
子句中的所有内容和 select
中的所有内容,您保证 table access by index rowid
。这意味着对于您从最里面的select
返回的每一行,您已经从索引中拉出,您还可以重新访问该表。不过,我认识到这将是您当前表上的一个可笑的大索引。
您的子选择似乎比需要的多。您可以在主select
下订单。您还在别名上方的两个级别上引用了别名a
。虽然这可能不会导致任何问题,但它有点令人困惑,您最终会出现两次 rnum
列。
100m 行正在接近频谱的 大 端。任何人都不太可能翻阅所有这些内容,并且从您的 cmets 中,报告中并未全部使用它们。虽然表是分区的,这将有很大帮助,但 Oracle 仍然需要确定要使用哪个分区。
从第 5 点开始,您按月对表进行了分区,但只选择了 3 天的数据。我同意这是明智的,但如果您只需要一个月的最大数据量即可轻松访问,那么对于较小的表可能值得按天分区?您提到有 2,300 份报告使用此表;如果它们都需要 5 分钟,则应考虑使用诸如此类的激烈方法。
有点可怜,url
有必要是 1024 个字符吗?
这些要点有效地归结为我的主要建议; 减小表的大小。 然后,尽一切可能消除 Oracle 需要做的任何额外工作;甚至可以将大部分表格变成索引。
所以,步骤是:
将超过一个月的所有内容归档到单独的表中。每天坚持这样做。
按天对较小的表进行分区。
如果您只需要几天的数据,那么绝对值得考虑创建一个materialized view,并且订单已经到位。
在这个新的较小的表上使用 "optimal" 索引;所以你根本不必真正触摸桌子。我已将反逗号放在最佳位置,因为这总是有争议的,我的建议可能有点不正确,但通常它是where, group by, order by and select clauses
中的所有列,按此顺序和 按选择性递减的顺序。这将使您的索引类似于"5mintime", username, category, domain, appid, url, bytes
。
尽可能使索引唯一。
确保您的查询没有做任何不必要的事情以减少工作量。这包括返回人类可读的行数。我会这样重写它:
SELECT time, url, bytes, rownum as rnum
FROM ( SELECT time, url, bytes, rowum as rnum
FROM ( SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS time
, url
, bytes
FROM available_web_details
WHERE "5mintime" BETWEEN to_timestamp('2012-02-10 00:00:00','YYYY-MM-DD HH24:MI:SS')
AND to_timestamp('2012-02-13 23:59:59','YYYY-MM-DD HH24:MI:SS')
AND username = 'asha1328874833'
AND category = 'None240001'
AND domain = '1328874833.vmware.com.'
AND appid IN ('216.198.204.192id',...)
ORDER BY "5mintime" DESC
)
WHERE rownum <= 10)
WHERE rnum > 0
希望这一切都有意义;在一天结束时,您的报告在服务器上完成的工作量以及您希望它们运行的速度将决定您想要做什么。
【讨论】:
你在 where 子句中的to_char
s 是否应该是你第四点的to_timestamp
s? order by
中的 to_char
是否对使用原始列有任何影响,无论是正面还是负面?
@AlexPoole,谢谢;我在重读时没有意识到这一点。对于你的第二点,是的,你是对的,它会更快,但它也会增加索引大小,因为你必须索引它,所以我认为它不会导致速度提高。
以上只是一个报告查询。对于不同的报告,我们在同一个表中有很多这样的查询,其中 where 子句的条件发生了变化。所以如果我在每个字段上创建索引,使用 where ,order by,group by 和 select 子句。它可能涵盖表字段的所有组合..!!!!!所以这样做是否可行..??
@AshaKoshti,如果您不减小表格的大小,则不;这是不可行的。如果你这样做,那么它可能是。我无法确定,因为我无权访问您的数据库,但值得调查。
请说明我将如何减小表格的大小..??【参考方案2】:
您是否尝试过将顺序从 Time 更改为 5mintime,我很确定您在转换值并对其进行排序时没有使用索引。
【讨论】:
ye.. 我在上面的查询中也做到了这一点,用 5mintime 替换 time 并且我在 5mintime 上有索引,但它仍然没有提供相同的性能..最新我应该能够在 30 到 45 秒内完成它..你能建议一些提示吗.. 无论哪种方式,排序都将是性能损失 - 您不能期望与没有 order by 子句的性能相同。 ye..这是真的..但是我有 JSP 可以在分页中显示这个结果..所以在每个页面上它都会点击相同的查询,只是将 rownum 字段从 10、20、30 更改。 ..等等..所以应用程序的性能很差。 嗯,也许您需要重新考虑查询。一次滚动 10 行 20K 行有什么用:) 其他选项可以是物化视图,可以每小时刷新一次,然后就像从表中直接选择一样。【参考方案3】:你有一个 5 分钟的索引,所以按它排序,然后在最外面的选择中进行 TO_CHAR
转换。您还可以考虑对您在 WHERE
子句中使用的其他字段进行索引。
另一个想法是查看 Oracle 正在使用的查询计划,看看它是如何解决问题的。这里有一个很好的关于Oracle的explain plan
的教程:http://www.adp-gmbh.ch/ora/explainplan.html
【讨论】:
ye.. 我在上面的查询中也做到了这一点,用 5mintime 替换 time 并且我在 5mintime 上有索引,但它仍然没有提供相同的性能..最新我应该能够在 30 到 45 秒内完成它。你能建议一些提示吗? 我已经编辑了一个解释计划教程的链接——它应该向您展示 Oracle 如何处理查询,并让您确定使用了哪些索引以及您可能需要创建哪些索引来获取最佳性能。以上是关于ACCESS 的 ORDER BY 问题的主要内容,如果未能解决你的问题,请参考以下文章