My assumption is that the main loop is always the first loop and you're always supposed to use query_post? Is this correct? Then whenever you you need to feed in some arguments to get a different set or order of posts you use WP_Query or get_posts. These would both be secondary loops? I just feel I'm hardly interacting with the Main Loop at all so I have this feeling, whilst everything works, I'm just not doing things properly.
When you visit a link of your site, WordPress recognizes that link and understands (using the rewrite rules you have defined or using the query vars in the URL if there are no pretty permalinks) what is the request of the URL.
After that WordPress, using this request, run a query. This is the main query. So, the main query is the one that is triggered by the URL of the page.
It can seems strange, but main query may not even be the first query. This because WordPress does a lot of things before running the main query: include plugins, include theme and also fire some actions and filters.
So if a plugin or the theme hook into one of this hooks and run a query this one is effectively run before the main query.
After the main query run, WordPress includes the appropriate template file. Which is the appropriate file is defined by the template hierarchy.
So when template file is loaded the main query is already run and you can make use of it directly using the loop.
If you use
query_posts in a template file this cause the main query run again— slows down the page load.
This is the reason why, if you need to change the main query, is better using
pre_get_posts hook that let you alter the query before is runned, so without run it again.
Be aware that
pre_get_posts runs for every query, and not only for the main one, but using
is_main_query in the function that hooks into that action you can control only the main query.
As you seems to know WordPress gives possibility to run different queries from the main and you have different alternatives to do this thing, the most popular and the suggested one is to use a new instance of WP_Query.
Now, every query that is not the main is a secondary query (even if is runned before the main query, as said above).