3 개의 테이블에서 레코드를 선택해야하는 3 개의 테이블이 있습니다. 즉 162161 개의 레코드가있는 계정 Account_Types 10761247 개의 레코드가있는 트랜잭션
아래는 테이블 구조입니다.
업무
id bigint (20) unsigned NO PRI auto_increment transfer_number bigint (20) unsigned YES MUL
debit_credit varchar (255) NO MUL
fund_type varchar (255) NO MUL
fund_id bigint (20) unsigned YES MUL
통화 varchar (255) NO
amount decimal (20, 2) NO MUL 0
설명 텍스트 NO
other_type varchar (255) NO
other_id bigint (20) unsigned YES
transaction_type varchar (255) NO
accounts_receivable int (1) unsigned NO 0
transaction_status varchar (255) NO MUL
creation_date datetime NO 0000-00-00 00:00:00 execution_date datetime 아니오 MUL 0000-00-00 00:00:00 api int (1) YES
claim_id char (8) YES
계좌
id bigint (20) unsigned NO PRI auto_increment user_id bigint (20) unsigned YES MUL
account_number varchar (255) NO UNI
type_id bigint (20) unsigned YES MUL
설명 varchar (255) NO
Commission_acc_id bigint (20) unsigned YES MUL
allow_debit varchar (255) ) NO
allow_credit varchar (255) NO
account_status varchar (255) NO MUL
creation_date datetime NO 0000-00-00 00:00:00
ACCOUNT_TYPES
id bigint(20) unsigned NO PRI auto_increment description varchar(255) NO MUL
currency varchar(255) NO MUL
monthly_fee_amount double NO 0
monthly_fee_description varchar(255) NO
yearly_fee_amount double NO 0
yearly_fee_description varchar(255) NO
generate_interests varchar(255) NO
interest_rate double NO 0
interest_payout_period varchar(255) NO
interest_payout_day char(2) NO
interest_payout_month char(2) NO
interest_payout_hour char(2) NO
interest_based_on varchar(255) NO
interest_based_on_period varchar(255) NO
interest_minimum_balance double NO 0
generate_commissions varchar(255) NO
commission_rate double NO 0
Commission_payout_period varchar (255) NO
커미션 _payout_day char (2) NO
커미션 _payout_month char (2) NO
커미션 _payout_hour char (2) NO
커미션 _ 기반 _on varchar (255) NO
커미션 _ 기반 _on_period varchar (255) NO 커미션 _ 최소 _ 잔액
두 배 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로 표시됩니다.
먼저 트랜잭션 테이블에서 필요한 모든 열에 인덱스를 추가해보십시오.
ALTER TABLE transaction
ADD INDEX `DebCredFundTypeTransStatus`
(`fund_id`,`debit_credit`,`fund_type`,`transaction_status`,`amount`)
이렇게하면 데이터를 위해 테이블 자체로 이동할 필요없이이 테이블에 대한 조회 수를이 인덱스로만 줄일 수 있습니다. amount
색인의 가장 오른쪽 부분 이 중요합니다 .
a.account_status
및 at.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';
아마도 가장 간단하고 생산적인 변경 일 것입니다. 그것을 시도하고 상황이 충분히 개선되었는지 확인하십시오. 그렇지 않은 경우 적용 할 수있는 다른 최적화가 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다