The French philosopher Montesquieu wrote, “Le mieux est le mortel ennemi du bien”, which means, “The best is the mortal enemy of the good.” Montesquieu was an interesting man who lived in the 18th century, and influenced many of the political structures around the world. His book “The Spirit of Law” from 1748 described ways to avoid absolute power, established concepts like “innocent until proven guilty”, and campaigned against slavery. I guess some countries adopted those ideas more than others.
I mentioned it because Josephine Bush has invited us to write about the topic of “Good enough is perfect“. And while I realise that the two statements are not identical, I consider that they are essentially the same. If we always strive for perfect then we can all too easily miss the mark of being able to deliver anything worthwhile. As a consultant I have to understand that the ideal solution for my customers is not the one where everything is completely perfect if achieving that means that the cost is too high. Instead, I need to find the point where good enough really is good enough.
With data, we should expect that the results of any query we write should be perfect. If you meant to search for item “10437” and you actually searched for “10438”, then that’s not good enough, and you should put some effort into making sure the results of your queries are correct and trustworthy. But let’s consider performance, which has a lot more grey-area involved.
In the world of SQL, we see that the Query Optimizer takes some time to work out the plan that should be used for a query. The amount of time taken for this compilation needs to be appropriate for the amount of time that the query is going to take to run – it shouldn’t take two minutes to find the perfect plan for a query that will only take one second to run even with an awful plan. And besides, can we really define what perfect is with a query plan? There is always going to be some amount of guesswork around statistics and the like.
At some point the QO needs to simply stop looking for a better plan, and we see why it stops as an attribute of the plan itself – the Reason for Early Termination of Statement Optimization. Sometimes it’s because the query is quite trivial and it reckons that it really has found the perfect plan – probably there aren’t that many ways it could run. The other two reasons it stops are that it’s found a “good enough” plan or that it’s timed out trying to find a better one. The idea is that it finds a valid plan and then repeatedly takes some time to find a better one, until it either thinks “this will do“ (GoodEnoughPlanFound) or “I guess I can’t find something better“ (Timeout).
My perspective, perhaps controversially, is that these two scenarios are essentially the same thing. A plan has been found and although there might be something which is better, that better plan cannot be easily found quickly enough to make it worthwhile. Good Enough Plan Found means that it doesn’t expect to be able to find anything better with another cycle of looking. Timeout means that it tried and couldn’t find anything better with another cycle of looking. Neither implies that the plan is perfect. Neither implies that the plan is awful. A query that is going to take more time is more likely to timeout on the search just because it figures it may as well take an extra few seconds to see if it can improve on a query that might take a few minutes. The plan could already be good enough.
In life in general, the principle of accepting that good enough means good enough is important for our mental health. We can spend an inordinate amount of time trying to be perfect, when it’s completely unnecessary. Just ask anybody who sits an exam after spending a huge amount of time studying only to find that they could’ve achieved a passing score with far less effort. My daughter has just finished high school, and she doesn’t need to get a perfect score in all her subjects, she just wants to be able to get enough to qualify for her preferred university degree. If you’re looking for a house to move into, do you search for perfect, or do you take the one which is good enough? You could timeout trying to find the perfect one, and miss out on the house that was the best of the rest.
Let’s think again about the SQL Query Optimizer, and what I do to try to tune a database system so that its queries run quickly. Sometimes I might know the execution plan that I want the QO to use for a query. If this is the case I can force it to use that plan. However, if over time the conditions change somewhat then maybe my plan becomes less “perfect”. Instead, my preferred way of tuning is to create an environment in which a good plan can be found more easily. This can be by writing the query in a particular way, or by providing particular indexes, or by using particular data types – all the standard types of things that people do when tuning queries.
And maybe we should try to do similar in real life. We can get our life towards good enough by providing “helps” along the way. To-do lists, reminders, good habits, positive friends, taking breaks, delegating, etc, are all ways that we can get closer to the life we want, like how an index can help the SQL engine access the data we want. and maybe the best of these “helps” is simply the acceptance that good enough really is good enough. Good enough doesn’t mean having to compromise. It simply means that you stop striving for further improvement and accept that what you’ve got is already perfect.
@robfarley.com@bluesky (previously @rob_farley@twitter)
By the way: This is T-SQL Tuesday 180. That means this has been going for 15 full years now. I was 35 when it started, and now I’ve just turned 50. The world has changed a lot in that time, and perhaps some of the French philosopher’s teachings should be revisited again around the world. Who knows what the next 15 years will hold, and whether we’ll be optimistic, pessimistic, nostalgic, or something else. Whatever it is, let’s be pragmatic and make good choices with wherever we’re at.