Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize queries and indexes for internal_transactions table #2910

Merged
merged 4 commits into from Jan 4, 2020

Conversation

vbaranov
Copy link
Member

@vbaranov vbaranov commented Dec 6, 2019

#2879

Motivation

  1. Queries to internal transactions table are not optimized efficiently
  2. internal_transactions_to_address_hash_from_address_hash_created" btree (to_address_hash, from_address_hash, created_contract_address_hash, type, index) is the largest index in the table (351 Gb on ETH Mainnet instance) and it is not used by the query to get internal transactions on address, but it was specifically created for that query.

The idea is to get rid of this large index and improve the query to get internal transactions for address for both cases: page and API endpoint.

Changelog

DB Migartion

  1. remove multi-column internal_transactions_to_address_hash_from_address_hash_created index
  2. add 3 partial indexes for each column to_address_hash, from_address_hash, created_contract_address_hash with a specific clause used by the query to get rid of first call trace of transactions:
WHERE (type::text = 'call'::text AND index > 0 OR type
::text <> 'call'::text) AND NOT block_number IS NULL

This change leverages 222 Gb on ETH Mainned DB instance:

Before:

public.internal_transactions_to_address_hash_from_address_hash_created | 351 GB

After:

public.internal_transactions_from_address_hash_partial_index           | 48 GB
 public.internal_transactions_to_address_hash_partial_index             | 48 GB
public.internal_transactions_created_contract_address_hash_partial_ind | 33 GB

and addresses the performance of queries to get internal transactions on the address. Though, the queries need to be changed a little bit to use new partial indexes.

Queries update

In order to start using those new partial indexes, the queries to get internal transactions for an address should be changed from using OR clause to use UNION. Specifically, we want to get rid of this clause:

WHERE (((i0.to_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22')
OR (i0.from_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22'))
OR (i0.created_contract_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22'))

in favour:

...
WHERE (i0.to_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22')
...

UNION

...
WHERE (i0.from_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22')
...

UNION

...
WHERE (i0.created_contract_address_hash = '\xbcf935d206ca32929e1b887a07ed240f0d8ccd22')
...

Here is the analysis of the "OR"-based query with a huge multi-column index:

 Limit  (cost=200.14..200.27 rows=51 width=942) (actual time=0.398..0.421 rows=51 loops=1)
   ->  Sort  (cost=200.14..200.29 rows=60 width=942) (actual time=0.397..0.405 rows=51 loops=1)
         Sort Key: block_number DESC, transaction_index DESC, index DESC
         Sort Method: quicksort  Memory: 58kB
         ->  Bitmap Heap Scan on internal_transactions i0  (cost=4.75..198.37 rows=60 width=942) (actual time=0.050..0.131 rows=81 loops=1)
               Recheck Cond: ((from_address_hash = '\xcb0bb361fdccd3ee16e1c0df5c72f27b2f584042'::bytea) AND ((((type)::text = 'call'::text) AND (index > 0)) OR ((type)::text <> 'call'::text)) AND (block_number IS NOT NULL))
               Heap Blocks: exact=11
               ->  Bitmap Index Scan on internal_transactions_from_address_hash_partial_index  (cost=0.00..4.74 rows=60 width=0) (actual time=0.030..0.030 rows=81 loops=1)
                     Index Cond: (from_address_hash = '\xcb0bb361fdccd3ee16e1c0df5c72f27b2f584042'::bytea)
 Planning Time: 0.452 ms
 Execution Time: 0.481 ms

And here is the result of "UNION"-based query with partial index:

Limit  (cost=0.41..199.04 rows=51 width=942) (actual time=0.038..0.100 rows=51 loops=1)
   ->  Index Scan using internal_transactions_from_address_hash_partial_index on internal_transactions i0  (cost=0.41..234.10 rows=60 width=942) (actual time=0.036..0.085 rows=51 loops=1)
         Index Cond: ((from_address_hash = '\xcb0bb361fdccd3ee16e1c0df5c72f27b2f584042'::bytea) AND (block_number IS NOT NULL))
 Planning Time: 0.589 ms
 Execution Time: 0.145 ms

As a result, 3x speed-up of the query

@vbaranov vbaranov added the wip label Dec 6, 2019
@vbaranov vbaranov self-assigned this Dec 6, 2019
@vbaranov vbaranov force-pushed the vb-avoid-complex-index branch 2 times, most recently from 39a7f59 to 78d3e0c Compare December 6, 2019 11:59
@vbaranov vbaranov added ready for review This PR is ready for reviews. and removed wip labels Dec 6, 2019
@coveralls
Copy link

coveralls commented Dec 6, 2019

Pull Request Test Coverage Report for Build 6c938b2b-841c-4b2a-be21-e5be1bf4ee3b

  • 34 of 40 (85.0%) changed or added relevant lines in 4 files are covered.
  • 2 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.03%) to 75.245%

Changes Missing Coverage Covered Lines Changed/Added Lines %
apps/explorer/lib/explorer/chain.ex 11 13 84.62%
apps/explorer/lib/explorer/etherscan.ex 11 15 73.33%
Files with Coverage Reduction New Missed Lines %
apps/block_scout_web/lib/block_scout_web/controllers/chain/market_history_chart_controller.ex 1 78.57%
apps/explorer/lib/explorer/chain/internal_transaction.ex 1 88.89%
Totals Coverage Status
Change from base Build 5d810de6-9b14-4309-936a-4c657e52a76c: 0.03%
Covered Lines: 5377
Relevant Lines: 7146

💛 - Coveralls

@vbaranov vbaranov force-pushed the vb-avoid-complex-index branch 5 times, most recently from 018130f to 53e0d3e Compare December 6, 2019 17:43
@vbaranov vbaranov force-pushed the vb-avoid-complex-index branch 2 times, most recently from 227ce0d to 4b931a0 Compare December 6, 2019 19:00
@vbaranov vbaranov added this to the 3.0.0 milestone Dec 18, 2019
@vbaranov vbaranov merged commit 1a95ba0 into master Jan 4, 2020
@vbaranov vbaranov deleted the vb-avoid-complex-index branch January 4, 2020 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance ready for review This PR is ready for reviews.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants