简体   繁体   English

如何优化嵌套选择?

[英]How can I optimise an nested select?

My use-case is to retrieve invoices for a customer and a format code for each invoice which is found by a join to a customer_list table which a join to a generalised code table to work out the format code. 我的用例是为客户检索发票,并为每个发票检索格式代码,该代码是通过对customer_list表的联接找到的,该表又联接到通用代码表以计算格式代码。

A simplified version of my query follows, which is working fine, yet the subquery would return around 5k of rows, I have to wonder how this could be optimised so the sub-query did not contain as many rows. 接下来是我的查询的简化版本,它工作正常,但是子查询将返回约5k的行,我想知道如何优化该查询,以便子查询不包含太多的行。

select i.invoice_number,
       f.format_code
  from invoices i
  left join (
    select gc.code_1 as format_code,
           ls.account
      from gen_codes gc,
           customer_list ls
     where gc.code_name = 'invoice-format'
       and gc.code_1 <> ''
       and ls.list_type = gc.code_value
  ) f on account = i.account
      or account = i.billing_account
where i.account = :accountNumber

NOTE : Not all invoices have a format code, which is fine and why I am performing a left join. 注意 :并非所有发票都有格式代码,这很好,为什么我要执行左联接。

UPDATE : A similar query without using an inner select would be of the following form: 更新 :不使用内部选择的类似查询将具有以下形式:

select i.invoice_number,
       f.code_1 as format_code
  from invoices i
  left join customer_list ls on
    (account = i.account or account = i.billing_account) and ls.list_type in (
           select code_value
             from gen_codes
            where code_name = 'invoice-format'
              and code_1 <> ''
        )
  left join gen_codes f on code_value = ls.list_type
                       and code_name = 'invoice-format'
                       and code_1 <> ''

I have a feeling this latter version may be more efficient as there are only two dozen records in gen_codes with the matched query while customer_list contains ~ half a million records with ~5k matching in the first version. 我觉得后一个版本可能会更有效,因为gen_codes中只有两打带有匹配查询的记录,而customer_list包含约50万条记录,而第一个版本中有gen_codes匹配。

I would write it as follows: 我将其编写如下:

Get all the invoices corresponding to an account or billing account (using JOIN and ON clauses) and get only those gen_codes associated with the list_types of the account matched (using LEFT JOIN) whose code_name is 'invoice-format' and gc.code_1 is not empty. 获取与帐户或计费帐户对应的所有发票(使用JOIN和ON子句),并仅获取与匹配的帐户的list_types匹配的gen_code(使用LEFT JOIN),其代号名称为'invoice-format',而gc.code_1不是空的。

SELECT 
    i.invoice_number,
    gc.code_1 as format_code
FROM 
    invoices i
    JOIN customer_list ls
    ON 
        (i.billing_account = ls.account OR i.account = ls.account) AND 
        i.account = :accountNumber
    LEFT JOIN gen_codes gc
    ON 
        ls.list_type = gc.code_value AND 
        gc.code_name = 'invoice-format' AND 
        gc.code_1 != ''

This will prune the customer_list records that doesn't match the accountNumber input upfront, compared to the subquery in your question. 与问题中的子查询相比,这将删节与预先输入的accountNumber不匹配的customer_list记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM