Every so often I get called upon to troubleshoot the performance of some SQL queries (that I didn't design). Frankly I view this activity as both a waste of time and an indication of severe design failure. Yes it /is/ possible to optimize queries post hoc, and if you must work your way through this task I will give you some guidance shortly. It certainly isn't, however the optimal way to get work done.
First let me explain why this is a design failure. A critical task during development is building a test environment mocked up to full scale. If you fail to do this then you won't fully appreciate how to best design your queries to begin with.
Databases are all about reading data from disk. Yeah sure there is some writing too, but this is typically dwarfed a couple orders of magnitude by the task of reading the data. Databases are heavily IO bound.
Two things contribute to the time it takes to read table data or index pages: the "width" of each row and the quantity of rows. The width of a row is determined both by the number of columns as well as how much data each field contains.
Do you want fast reads? Use narrow tables and indexes (or use vertical partitioning). To limit the quantity of row reads, use horizontal partitioning or appropriate cluster indexing on tables with millions of rows. And guess what, you can't choose the best partitioning approach during development until you scale up.
Understand the above and you will have good baseline strategies for designing queries in the first place. Hence given the chance to "optimize" existing queries, a far better approach (if you have the time) is to refactor the application to take advantage of this knowledge.
Persist sub-queries to narrow temporary work tables. Target your query sequence to limit the selection criteria to the typically minimal rowset before finally joining in the "wide" information.
If you can't afford a full refactoring though, then you will have to resort to basic database query optimization techniques. Learn to understand the "explain plan" and to identify the time resource hogs. Use nolock hints where possible. Experiment with other hints to modify join order. Direct reads by a key are fast, full scans are slow, so build indices on columns used in joins.
Yeah you can soup up your Toyota Corolla queries to run at 160 miles per hour, but it would have been far better to design your queries like a Ferrari from the start.
Wednesday, November 16, 2016
Artful Query
Monday, October 17, 2016
Artful Bug Squashing
Bugs are just a fact of life in software development: nobody likes to see them, but so many demands confound a programmer’s time that it becomes impossible to design down to every last exception. Sometimes the bugs even pre-exist in the tools that we use, the development environments, or the compilers.
However much I’m reluctant to admit it, all the same we’ve got a vested interest in keeping a fair share of bugs in the works; if our offerings are perfect then we essentially program ourselves out of our jobs. Imagine if all the schoolkids picked up every last piece of trash and wiped down all the tables when they finished lunch. What would all the janitors do?
You can prevent some bugs by utilizing certain development techniques. One of my favorites is to rename all of your variables and functions to make them distinctively descriptive and non-overlapping. This adds another couple of days to the project, but in the long run it pays off twice: first in easier maintenance with standard names. Second the process of editing and replacing catches many bugs by itself.
As I mentioned in an earlier post, another useful trick during development is to make specific plans to keep audit trails (or trace logs). I usually ask the staff to define a global Boolean called Testing that when true should cause nearly all activity to log to external files.
When persisting to a database I prefer to avoid deleting records: instead I include an “obsolete” flag and set it True when the record should be ignored. Depending on the audit requirements of your system you may even prefer to append a copy of a record for modification, so that if necessary you can always go back to prior versions of a row (note however that this strategy is quite costly from a storage perspective).
Legally many systems also need to track the identity of the user and a timestamp when any rows or fields were modified. If you also include a field to identify the module name and version of the modifying process you can greatly aid version-debugging and historical corrections.
Tracking and fixing bugs is an art of its own. Under pressure rank a bug’s squash-priority by the nature of its criticality. Certainly items that involve the health and safety of your clients, your staff, and yourself come first. Items that adversely impact production cycles are the next highest importance. Bugs that interfere with someone accomplishing their work come in third (especially if you lack an immediate workaround).
Next you will have a large hodgepodge grouping of nuisance bugs, resource bottlenecks, and business-critical enhancements. Everything else will likely go into the bottom of your priority list for “when you have the time”. A useful trick-of-the-trade is to dedicate one-half to one day each week for the lowest priority items; that way you can at least address some of them. Keep the list of unfinished items however… at some point several months to a couple years down the road you will want to revisit many of them to see if they still have merit.
Wednesday, September 14, 2016
Artful Matchmaking
Fanning the spark of an idea for an IT project is always a tricky, precarious task. Somewhat like internal marketing, a Business Analyst is selling a vision. More than this however the analyst mentally surveys the capabilities and availabilities of everyone he knows and attempts to match this to a vision that he can impute to the desires of management. So it feels very much like matchmaking, except in the business-to-project realm.
To the managers you are selling an investment. Your job is to convince them that they will get an honorable and lucrative return on their investment in equipment and manpower. To the software developers you are selling professional advancement, knowledge enrichment, and a reasonable amount of job security.
And similar to romantic matchmaking sometimes you have to use a bit of deception in order to get the parties together despite their different opinions. Many times you will actually have a deeper awareness of the best interests of the managers and programmers than either party will know alone. Hence a bit of artful promising goes a long way. Is this unethical? Not if you're careful to make sure that the ends justify the means.
It's all about some balance and possibilities and getting folks over the hump of their current comfort levels to move them through a low spot to finally arrive at a new, higher comfort.
When an idea is just a concept -- before it is even a glimmer in a manager's eye -- when it is just a spark of "I wonder if it might make sense..." or "maybe we should look at..." the Business Analyst combs the psychic brainwaves of the company's employees and decides what is Possible.