我有一个名为VW_PURCHASE_ORDER_LIST的视图。它总共有大约200,000条记录。
运行查询需要16ms:
select first 128 * from VW_PURCHASE_ORDER_LIST
然而,当我使用order by语句时,它需要更长的时间......大约9s
select first 128 * from VW_PURCHASE_ORDER_LIST
order by id asc
Plan
PLAN SORT (JOIN (VW_PURCHASE_ORDER_LIST LEVY BT NATURAL, VW_PURCHASE_ORDER_LIST M INDEX (PK_MATTER), VW_PURCHASE_ORDER_LIST LEVY F INDEX (PK_B_BUDGET_LEVY_FREQUENCY), VW_PURCHASE_ORDER_LIST BT_FHC INDEX (PK_BT_FINANCIAL_HEALTH_CHECK), VW_PURCHASE_ORDER_LIST BD INDEX (PK_BT_BUILDING_DETAILS), VW_PURCHASE_ORDER_LIST USR_STRATAMANAGER INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST POH INDEX (FK_PURCHASE_ORDER_HEADER_1), VW_PURCHASE_ORDER_LIST PS INDEX (PK_LK_PO_PAID_STATUS), VW_PURCHASE_ORDER_LIST POS INDEX (PK_LK_PURCHASE_ORDER_STATUS), VW_PURCHASE_ORDER_LIST LM INDEX (UNQ1_P_ORDER_MODIFIED_DATE), VW_PURCHASE_ORDER_LIST SUPPLIER INDEX (PK_CONTACT), VW_PURCHASE_ORDER_LIST USR_CREATED INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST USR_MODIFIED INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST USR_APPROVED INDEX (PK_USER_DETAIL)))
------ Performance info ------
Prepare time = 32ms
Execute time = 8s 80ms
Avg fetch time = 237.65 ms
Current memory = 98,671,784
Max memory = 99,258,368
Memory buffers = 2,048
Reads from disk to cache = 230,443
Writes from cache to disk = 0
Fetches from cache = 6,253,743
有没有办法加快速度?问题是我们的数据库规模在不断扩大,现在有很多大型表。我们的应用程序用于将整个表加载到网格中,但由于我们现在拥有如此多的数据,因此需要几分钟才能加载并最大化客户端PC的RAM。
作为解决方案,我们使用的是DevExpress ServerMode XtraGrid。在网格上加载和滚动很慢,因为它正在发送初始select count(*) from x_table_or_view_name
以获取总记录,然后在滚动时发送select first x skip y from x_table_or_view_name order by id
....这样的顺序会减慢查询的速度。使网格无法使用
我不知道从哪里开始,因为我不是数据库专家,如果有人可以提供一些建议,我们将不胜感激。
无订单更新:
select first 128 * from VW_PURCHASE_ORDER_LIST
Plan
PLAN JOIN (VW_PURCHASE_ORDER_LIST LEVY BT NATURAL, VW_PURCHASE_ORDER_LIST M INDEX (PK_MATTER), VW_PURCHASE_ORDER_LIST LEVY F INDEX (PK_B_BUDGET_LEVY_FREQUENCY), VW_PURCHASE_ORDER_LIST BT_FHC INDEX (PK_BT_FINANCIAL_HEALTH_CHECK), VW_PURCHASE_ORDER_LIST BD INDEX (PK_BT_BUILDING_DETAILS), VW_PURCHASE_ORDER_LIST USR_STRATAMANAGER INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST POH INDEX (FK_PURCHASE_ORDER_HEADER_1), VW_PURCHASE_ORDER_LIST PS INDEX (PK_LK_PO_PAID_STATUS), VW_PURCHASE_ORDER_LIST POS INDEX (PK_LK_PURCHASE_ORDER_STATUS), VW_PURCHASE_ORDER_LIST LM INDEX (UNQ1_P_ORDER_MODIFIED_DATE), VW_PURCHASE_ORDER_LIST SUPPLIER INDEX (PK_CONTACT), VW_PURCHASE_ORDER_LIST USR_CREATED INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST USR_MODIFIED INDEX (PK_USER_DETAIL), VW_PURCHASE_ORDER_LIST USR_APPROVED INDEX (PK_USER_DETAIL))
------ Performance info ------
Prepare time = 16ms
Execute time = 15ms
Avg fetch time = 0.44 ms
Current memory = 36,398,384
Max memory = 0
Memory buffers = 2,048
Reads from disk to cache = 172
Writes from cache to disk = 0
Fetches from cache = 2,654
这是下面的实际视图。如果这有帮助,我可以在联接中为表格发布DDL吗?
CREATE VIEW VW_PURCHASE_ORDER_LIST(
ID,
ID_BUILDING,
ID_SUPPLIER,
ID_STATUS,
ID_USER_CREATED,
ID_USER_MODIFIED,
DATE_ORDER,
DATE_CREATED,
DATE_MODIFIED,
DATE_PAYMENT_COMMITMENT,
ISARCHIVED,
JOURNAL,
NOTES,
PO_NUMBER,
SUPPLIER_INVOICE_NUMBER,
TERMS_IN_DAYS,
STRATA_PLAN_NUMBER,
BUILDING_DISPLAY,
SUPPLIER_DISPLAY,
USERNAME_CREATED,
USERNAME_MODIFIED,
STATUS_DESCRIPTION,
ID_USER_APPROVED,
USERNAME_APPROVED,
ID_STRATA_MANAGER,
USERNAME_STRATAMANAGER,
DATE_LATEST_PAYMENT_BANKED,
INSURANCE_PREMIUM,
NEXT_DATE_RENEWAL,
COUNT_UNALLOCATED_BANK_TRANS,
SUM_UNALLOCATED_BANK_TRANS,
LIST_PAYMENT_TRANS_TYPE,
LIST_PAYMENT_ACCOUNT,
LIST_PAYMENT_NUMBER,
ID_PAID_STATUS,
PAID_STATUS_DESC,
LIST_DEBIT_ACCOUNTS,
LIST_DETAIL_AMOUNT,
ADMIN_LEVY_YEAR_END_DATE,
LEVY_ARREARS,
NEXT_ADMIN_LEVY_DATE,
ADMIN_LEVY_FREQUENCY,
PAYABLE_NOTES)
AS
select
poh.id,
poh.id_building,
poh.id_supplier,
poh.id_status,
poh.id_user_created,
poh.id_user_modified,
poh.date_order,
poh.date_created,
MAXVALUE(lm.date_modified, levy.modified_date, bd.modified_date),
poh.date_payment_commitment,
poh.isarchived,
poh.journal,
poh.notes,
poh.order_number,
poh.supplier_invoice_number,
poh.terms_in_days,
m.matter_code,
m.matter_display,
supplier.contact_display,
usr_created.user_name,
usr_modified.user_name,
pos.description,
poh.id_user_approved,
usr_approved.user_name,
bd.id_strata_manager,
usr_stratamanager.user_name,
poh.date_latest_payment_banked,
m.sum_insurance_premium,
m.next_date_renewal,
bt_fhc.count_unallocated_bank_trans,
bt_fhc.sum_unallocated_bank_trans,
lm.list_payment_trans_type,
lm.list_payment_account,
lm.list_payment_number,
poh.id_paid_status,
ps.description,
lm.list_debit_accounts,
lm.list_detail_amount,
levy.admin_levy_year_end_date,
levy.levy_arrears,
levy.next_admin_levy_date,
levy.admin_frequency,
bd.payable_notes
from purchase_order_header poh
join purchase_order_modified_date lm on lm.id_purchase_order = poh.id
join lk_purchase_order_status pos on pos.id = poh.id_status
join matter m on m.matter_id = poh.id_building
join contact supplier on supplier.contact_id = poh.id_supplier
join user_detail usr_created on usr_created.user_id = poh.id_user_created
join user_detail usr_modified on usr_modified.user_id = poh.id_user_modified
join user_detail usr_approved on usr_approved.user_id = poh.id_user_approved
join bt_building_details bd on bd.id = m.matter_id
join user_detail usr_stratamanager on usr_stratamanager.user_id = bd.id_strata_manager
join BT_FINANCIAL_HEALTH_CHECK bt_fhc on bt_fhc.id = poh.id_building
join lk_po_paid_status ps on ps.id = poh.id_paid_status
join VW_BT_LEVY levy on levy.Id = poh.id_building
where poh.id <> 0
;
答案 0 :(得分:1)
我知道这是一个非常老的问题,但是由于有很多反对意见,所以我认为这是一个普遍的问题。从2.5迁移到3.0后,我也遇到了这个问题,我发现的解决方案非常简单。就您而言:
order by id || '' asc
或者,如果id是数字:
order by id + 0 asc
可能的解释:
Firebird 3尝试尽可能使用现有索引来产生排序。当结果集仅占数据库的一小部分时,将是有害的。呈现的表达式不会更改顺序键值,但会“欺骗”数据库优化器,并且不使用索引。