【问题标题】:Query Performance Issue - for select statement even with indexes on the table with more than 20 Trillion records查询性能问题 - 对于 select 语句,即使表上有超过 20 万亿条记录的索引
【发布时间】:2023-03-23 12:50:01
【问题描述】:

我们有三个表,需要从三个表中选择记录,即 拥有 162161 条记录的账户 Account_Types 6 条记录 有10761247条记录的交易

下面是表格结构

交易

id bigint(20) unsigned NO PRI auto_increment transfer_number bigint(20) 无符号 YES MUL
debit_credit varchar(255) NO MUL
fund_type varchar(255) NO MUL
fund_id bigint(20) 无符号 YES MUL
货币 varchar(255) 否
金额小数(20,2) NO MUL 0
描述文字没有
other_type varchar(255) 否
other_id bigint(20) 无符号 YES
transaction_type varchar(255) 否
account_receivable int(1) 无符号 NO 0
transaction_status varchar(255) NO MUL
creation_date 日期时间 NO 0000-00-00 00:00:00 execution_date datetime NO MUL 0000-00-00 00:00:00 api int(1) 是
claim_id char(8) 是

帐户

id bigint(20) unsigned NO PRI auto_increment user_id bigint(20) 无符号 YES MUL
account_number varchar(255) NO UNI
type_id bigint(20) 无符号 YES MUL
描述 varchar(255) 否
Commission_acc_id bigint(20) 无符号 YES MUL
allow_debit varchar(255) 否
allow_credit varchar(255) 否
account_status varchar(255) NO MUL
creation_date 日期时间 NO 0000-00-00 00:00:00

帐户类型

id bigint(20) unsigned NO PRI auto_increment 描述 varchar(255) NO MUL
货币 varchar(255) NO MUL
月费金额双倍 NO 0
monthly_fee_description varchar(255) 否
yearly_fee_amount 双 NO 0
yearly_fee_description varchar(255) 否
generate_interests varchar(255) 否
利率双倍 NO 0
interest_payout_period varchar(255) 否
interest_payout_day char(2) 否
interest_payout_month char(2) 否
interest_payout_hour char(2) 否
interest_based_on varchar(255) 否
interest_based_on_period varchar(255) 否
interest_minimum_balance 双 NO 0
generate_commissions varchar(255) 否
佣金率双倍 NO 0
Commission_payout_period varchar(255) 否
Commission_payout_day char(2) 否
Commission_payout_month char(2) 否
Commission_payout_hour char(2) 否
Commission_based_on varchar(255) 否
Commission_based_on_period varchar(255) 否
Commission_minimum_balance double NO 0

以下是我们使用以下查询的查询:

SELECT SUM(t.amount) AS total_credit 
FROM    account_types at, 
        accounts a, 
        transactions t 
WHERE   at.currency          = var_currency 
AND     at.id                = a.type_id 
AND     (a.account_status    = 'active' 
        OR a.account_status  = 'blocked')
AND     a.id                 = t.fund_id 
AND     t.debit_credit       = var_debit_credit 
AND     t.fund_type          = 'account'
AND     t.transaction_status = 'executed';

这需要 20 分钟或更长时间才能得到输出。

管理层的先决条件 - 因为它是一个交易表,所以我们无法归档该表,我们需要记录来计算总和,而不是允许硬件更改。 有索引的表也存在。在描述中表示为 MUL。

【问题讨论】:

  • 您能否发表一个解释,并告诉我们存在哪些索引?
  • 这些是表上的索引 TRANSACTIONS id debit_credit fund_type amount transaction_status ACCOUNTS id type_id Commission_acc_id account_status ACCOUNT_TYPES id currency
  • var_currencyvar_debit_credit 指的是哪里?它们是恒定的吗?
  • 除了activeblocked 之外,还有其他帐户状态吗?还有多少?
  • 没有解释,以及你已经拥有的确切索引,我们只能猜测......

标签: mysql query-optimization


【解决方案1】:

首先,尝试在事务表中为您需要的所有列添加索引。

ALTER TABLE transaction
ADD INDEX `DebCredFundTypeTransStatus`
(`fund_id`,`debit_credit`,`fund_type`,`transaction_status`,`amount`)

这会将对该表的查找次数减少到仅针对该索引,而无需前往表本身获取数据。 amount 是索引的最右侧部分,这一点很重要。

由于a.account_statusat.currency 是它们各自表中唯一需要访问的列(除了主键,它包含在所有索引的最右边部分中),那么你应该可以接受这些。

下一个大瓶颈是 OR 子句。由于您没有订购您的结果,我们可以轻松地使用 UNION ALL 并为每个所需的 account_status 值运行两次。

SELECT SUM(t.amount) AS total_credit 
FROM    account_types at, 
        accounts a, 
        transactions t 
WHERE   at.currency          = var_currency 
AND     at.id                = a.type_id 
AND     a.account_status    = 'active'
AND     a.id                 = t.fund_id 
AND     t.debit_credit       = var_debit_credit 
AND     t.fund_type          = 'account'
AND     t.transaction_status = 'executed'

UNION ALL

SELECT SUM(t.amount) AS total_credit 
FROM    account_types at, 
        accounts a, 
        transactions t 
WHERE   at.currency          = var_currency 
AND     at.id                = a.type_id 
AND     a.account_status  = 'blocked'
AND     a.id                 = t.fund_id 
AND     t.debit_credit       = var_debit_credit 
AND     t.fund_type          = 'account'
AND     t.transaction_status = 'executed';

这些可能是最简单和最有成效的变化。试试看,看看情况是否有足够的改善。如果没有,可以应用其他优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-09
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 2011-12-13
    • 1970-01-01
    相关资源
    最近更新 更多