Skip to content
Advertisement

improve sql query with 2 EXISTS sub queries

I have this query (mysql):

It runs multiple times on app start. It takes more than 10 seconds (all of them).

I have indexes on:

balance_histories table: budget_item_id, family_id (tried also payment_date)

budget_lines table: family_id, budget_id, budget_item_id

How can I improve the speed? Query or maybe mysql (8) configuration.

balance_histories table: enter image description here

budget_lines table: enter image description here

Advertisement

Answer

I would start this query in reverse of what you have. Assuming you COULD have years of data, but your EXISTS query is looking more specifically at a date-range, or specific budget lines, start there, it will probably be much smaller. Once you have DISTINCT IDs, then go back to the budget items by qualified ID PLUS the additional criteria.

To help optimize the queries, I would have indexes on

Feedback

As for many SQL queries, there are typically multiple ways to get a solution. Sometimes using EXISTS works well, sometimes not as much. You need to consider cardinality of your data, and that is what I was shooting for. Look at what you were asking for first: Get budget items that are all category for and custom for family is 1 or 0 (which is all), but if family, only those for 999. You were correct on your balance of AND/OR. However, this is going through EVERY RECORD, and if you have millions of rows, that is what you are scanning through. Only after scanning through every row are you now doing a secondary query (for each record that qualified) against the histories for the specific date range OR family/budget.

My guess is that the number of possible records returned from your two EXISTS queries was going to be very small. So, by starting by getting a DISTINCT list of just those IDs that are part of that union would be the very small subset. Once that single “ID” if found, it now becomes a direct match to the budget items table and have the final filtering limits of categoryID / Family / Custom Item considerations.

By having indexes better match the context of your query WHERE clause will optimize pulling data. I have had answers to several other questions with similar resolutions and clarify indexes and why in those… take a look for example, and another here.

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