sql查询优化(oracle)

sql查询优化(oracle),sql,oracle,select,optimization,join,Sql,Oracle,Select,Optimization,Join,我的sql时代已经过去了一段时间,因此我想知道是否有可能进一步优化以下查询?目标是收集每个会计师的所有账目,包括与之相关的所有预订和变动。性能/查询时间非常重要,因为有“3位数”的百万数据集 select Accountant.person_id, Account.account_id, Account.number, Account.balance, Account_Type.type_number, Booking.booking_id,

我的sql时代已经过去了一段时间,因此我想知道是否有可能进一步优化以下查询?目标是收集每个会计师的所有账目,包括与之相关的所有预订和变动。性能/查询时间非常重要,因为有“3位数”的百万数据集

select Accountant.person_id, 
    Account.account_id, 
    Account.number, 
    Account.balance,
    Account_Type.type_number, 
    Booking.booking_id, 
    Booking.amount, 
    Movement.movement_date, 
    Movement.movement_desc
from Accountant
join Account on Accountant.person_id = Account.person_id
join Account_Type on Account.account_type_id = Account_Type.account_type_id
left outer join Booking on Account.account_id = Booking.account_id
left outer join Movement on Booking.movement_id = Movement.movement_id;
实体模型如下所示:

更新: 因为有些人想知道:是的,我只是选择了数亿行,因为查询用于迁移数据。查询的数据用于构造新的数据结构,并将其放入另一个数据库中

  • 为了允许在没有预订的情况下返回帐户,我添加了外部联接。这是正确的语法吗
  • 这里是解释计划-看到任何优化的可能性吗?
  • 添加一些缺少的索引后,查询(在外部工具中)需要大约1/2小时。在java中,内存错误会在某个点抛出。有什么提示(除了增加内存)如何优化

  • 联接语法更清晰,建议使用。我不认为您可以进一步优化查询本身,但是您可以检查DB模式,或者研究替代方案

    数据库模式:

    • 是否所有ID都标记为主ID(即索引和群集)
    • 您能否检查查询计划以确保查询以最佳方式执行

    您还可以考虑在每天结束时建立的报表表(或者如果需要的话更频繁),并从中查询。Oracle支持可能有所帮助的具体化视图


    最后,一个返回n,000000条记录的查询对任何人都没有多大用处,所以您可能会重新考虑您的逻辑。如果要向用户显示这些记录,则需要对其进行分页(因此将查询限制为页面大小)-或者如果要显示摘要信息,请重写查询以使用聚合函数(sum/max/avg等)。不要使用代码来实现DB的最佳功能。

    联接语法更清晰,建议使用。我不认为您可以进一步优化查询本身,但是您可以检查DB模式,或者研究替代方案

    数据库模式:

    • 是否所有ID都标记为主ID(即索引和群集)
    • 您能否检查查询计划以确保查询以最佳方式执行

    您还可以考虑在每天结束时建立的报表表(或者如果需要的话更频繁),并从中查询。Oracle支持可能有所帮助的具体化视图


    最后,一个返回n,000000条记录的查询对任何人都没有多大用处,所以您可能会重新考虑您的逻辑。如果要向用户显示这些记录,则需要对其进行分页(因此将查询限制为页面大小)-或者如果要显示摘要信息,请重写查询以使用聚合函数(sum/max/avg等)。不要使用代码来实现DB的最佳功能。

    正如其他人已经提到的:这很奇怪,您希望一次性选择数亿条记录

    除此之外:

  • 如果您同时进行外部联接表移动,则表预订上的左侧外部联接将仅起作用
  • 因为您需要所有记录,所以只有完整表扫描(或快速完整索引扫描)才有意义。如果是这种情况,请检查解释计划。(它应该。)否则使用/*+full(tablename)*/
  • 由于您将使用全表扫描,您可能希望它们并行运行。如果情况已经如此,请检查解释计划。否则使用/*+并行(表名、系数)*/
  • 如果表有许多列,最好有包含所需列的索引,这样就可以使用快速的全索引扫描而不是全表扫描,因此需要读取的磁盘块更少
  • 您可以通过压缩表(Oracle 11g及更高版本)来减少光盘读取

  • 正如其他人已经提到的:奇怪的是,你想要一次选择数亿条记录

    除此之外:

  • 如果您同时进行外部联接表移动,则表预订上的左侧外部联接将仅起作用
  • 因为您需要所有记录,所以只有完整表扫描(或快速完整索引扫描)才有意义。如果是这种情况,请检查解释计划。(它应该。)否则使用/*+full(tablename)*/
  • 由于您将使用全表扫描,您可能希望它们并行运行。如果情况已经如此,请检查解释计划。否则使用/*+并行(表名、系数)*/
  • 如果表有许多列,最好有包含所需列的索引,这样就可以使用快速的全索引扫描而不是全表扫描,因此需要读取的磁盘块更少
  • 您可以通过压缩表(Oracle 11g及更高版本)来减少光盘读取

  • 使用一个合适的
    连接如何?对于州政府来说,你(可能)会很明显错过了一些正确的笛卡尔积?因为记账和移动未链接到会计、科目、科目类型,但在
    where
    子句中,
    记账
    未链接到
    科目
    。您的图表显示了四种关系,因此在
    where
    子句中只有三种关系有点危险。使用ANSI连接会更明显。(没有实际的过滤器,只需连接条件,希望您期望得到一个大的结果集;听起来您期望所有五个表中的所有数据;不确定这有多有用!)在帮助您优化查询之前,我们需要更多的信息。真正的查询是什么(我假设您不会简单地选择数亿行?),需要多长时间,等等。使用适当的
    连接如何?对于州政府来说,您(可能)会明显地错过一些正确的笛卡尔积?因为记账和移动未链接到会计、科目、科目类型,但在
    where
    子句中,
    记账
    未链接到
    科目
    。您的图表显示了四种关系,以此类推