Skip to content
Advertisement

Simplifying SELECT statement

so I have a statement I believe should work… However it feels pretty suboptimal and I can’t for the life of me figure out how to optimise it.

I have the following tables:

  • Transactions
    • [Id] is PRIMARY KEY IDENTITY
    • [Hash] has a UNIQUE constraint
    • [BlockNumber] has an Index
  • Transfers
    • [Id] is PRIMARY KEY IDENTITY
    • [TransactionId] is a Foreign Key referencing [Transactions].[Id]
  • TokenPrices
    • [Id] is PRIMARY KEY IDENTITY
  • TokenPriceAttempts
    • [Id] is PRIMARY KEY IDENTITY
    • [TransferId] is a Foreign Key referencing [Transfers].[Id]

What I want to do, is select all the transfers, with a few bits of data from their related transaction (one transaction to many transfers), where I don’t currently have a price stored in TokenPrices related to that transfer.

In the first part of the query, I am getting a list of all the transfers, and calculating the DIFF between the nearest found token price. If one isn’t found, this is null (what I ultimately want to select). I am allowing 3 hours either side of the transaction timestamp – if nothing is found within that timespan, it will be null.

Secondly, I am selecting from this set, ensuring first that diff is null as this means the price is missing, and finally that token price attempts either doesn’t have an entry for attempting to get a price, or if it does than it has fewer than 5 attempts listed and the last attempt was more than a week ago.

The way I have laid this out results in essentially 3 of the same / similar SELECT statements within the WHERE clause, which feels hugely suboptimal…

How could I improve this approach?

Advertisement

Answer

Here is an attempt to help simplify. I stripped out all the [brackets] that really are not required unless you are running into something like a reserved keyword, or columns with spaces in their name (bad to begin with).

Anyhow, your main query had 3 instances of a select per ID. To eliminate that, I did a LEFT JOIN to a subquery that pulls all transfers of type < 2 AND JOINS to the price attempts ONCE. This way, the result will have already pre-aggregated the count(*) and Max(Created) done ONCE for the same basis of transfers in question with your WITH CTE declaration. So you dont have to keep running the 3 queries each time, and you dont have to query the entire table of ALL transfers, just those with same underlying type < 2 condition. The result subquery alias “PQ” (preQuery)

This now simplifies the readability of the outer WHERE clause from the redundant counts per Id.

REVISED to remove the WITH CTE into a single query

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement