|
1
|
|
|
2
|
- Introduction
- Code what you know
- Know what you code
|
|
3
|
- This presentation deals with writing the initial SQL, before it is even
tested the first time.
- If the initial SQL is functionally right, SQL tuners can take it as a
clean spec for the rows the application requires at that point in the
flow of control, and they don’t need an understanding of the application
or even the tables.
|
|
4
|
- To write that clean initial SQL, the developer absolutely does need a precise
understanding of the application requirements and the tables.
- There is no point in writing initial SQL that is not a clean, correct
spec for what the application needs at that stage in its flow of
control!
- Iteration, or trial and error, is a terrible way to write the initial
SQL.
|
|
5
|
- Clean initial SQL, written by a developer who fully understands the
functional requirements, is likely to get a good execution plan from the
optimizer without manual tuning.
- Even if clean initial SQL does not perform well, as a clean,
transparent, correct spec for the functional requirements of the
application, it is much easier to tune than unclean SQL, and it avoids
wasting time tuning something that isn’t even functionally sensible.
|
|
6
|
- First principles:
- If you don’t really understand what the tables and/or views represent,
the SQL will likely perform poorly,…
|
|
7
|
- First principles:
- If you don’t really understand what the tables and/or views represent,
the SQL will likely perform poorly,…
- and even if it doesn’t, it will likely be functionally wrong!
|
|
8
|
- First Principles:
- If you don’t really understand what the SQL is supposed to accomplish,
it will likely perform poorly,…
|
|
9
|
- First Principles:
- If you don’t really understand what the SQL is supposed to accomplish,
it will likely perform poorly,…
- and even if it didn’t, it will likely be functionally wrong!
|
|
10
|
- First Principles:
- If you don’t really understand what the SQL is supposed to accomplish,
it will likely perform poorly,…
- and even if it didn’t, it will likely be functionally wrong…
- And even if it isn’t, it will be hard to understand and maintain!
|
|
11
|
- What set of entities does each table represent?
- What is the complete primary key to each table?
- What set of entities does each view represent?
- What is the virtual primary key of each view?
- Roughly how many rows in production will there be in each table or view?
|
|
12
|
- If you don’t know enough to…
- Fully understand the tables and views…
- You don’t know enough to write the SQL!
|
|
13
|
|
|
14
|
|
|
15
|
|
|
16
|
|
|
17
|
- Are the tables joined in a tree (no loops, no missing joins)? If not,
why, exactly?
- What is the direction of every join? (Which side or sides are unique?)
If any join is many-to-many, why is it, and how can that be right?
- What is the purpose of each join? Are you using anything from the
joined-to table?
|
|
18
|
- If you don’t know enough to…
- Understand the nature and purpose of the joins…
- You don’t know enough to write the SQL!
|
|
19
|
- What is the entity that each result row (or each pre-aggregated result
row) should represent? What table or view maps to that entity?
- Is the table or the view mapping to the results the (only!) root detail
table, the only table not joined to the other tables with its primary
key? (Are all joins from the single root node downward-pointing?)
|
|
20
|
- If you don’t know enough to…
- Understand the structure of the join tree, and how it maps to the
desired query result…
- You don’t know enough to write the SQL!
|
|
21
|
- Create the join tree before you even begin to write the SQL!
- Write the SQL to precisely match the join tree. (See the whitepaper for
details.)
- Use the join trees to document the SQL.
- *Thanks to Fahd Mirza!
|
|
22
|
- If you use a view, the view-defining SQL is part of your SQL, and your
SQL is only right if the whole combination is right!
|
|
23
|
- Do rows from the view map cleanly, one-to-one, to a single entity? (Are
the view-defining join trees clean?) Is that exactly the right entity
for purposes of your query?
- Are there elements in the view (joins, subqueries) that are unnecessary
or redundant to your query?
- Will use of the view still be correct when and if the view changes?
|
|
24
|
- If you don’t know enough to…
- Understand the structure of the views you use…
- You don’t know enough to write the SQL!
|
|
25
|
- Would the complete join diagram, which explodes the view-defining
queries into the view-using query, still be a normal, clean join tree?
If not, exactly what would be the corner-case behaviors of that query,
and would those behaviors be correct?
- How could you code the query to base-tables, only? If the resulting
base-table query would be unusual or complex, is that complexity necessary
and correct?
|
|
26
|
- If you don’t know enough to…
- Understand how to write the query direct to the base tables…
- You don’t know enough to write the SQL!
|
|
27
|
- If you don’t know enough to…
- Understand how to write the query direct to the base tables…
- You don’t know enough to write the SQL!
- Oh, and by the way…
|
|
28
|
- If you do know enough to
- Understand how to write the query direct to the base tables…
- Why don’t you!?!
|
|
29
|
- If you do know enough to
- Understand how to write the query direct to the base tables…
- Why don’t you!?!
- (Yes, there are reasons, but have a reason.)
|
|
30
|
- Roughly, how many rows should the query return? Is that a useful result
set (not too large for human consumption)?
- Does the query return any rows or columns that aren’t really needed?
- When, and how often, does the query run? Can it perform well in that
context, given reasonable per-row performance, or do we have an example
of an “unsolvable” tuning problem?
|
|
31
|
- If you don’t know enough to…
- Understand the context of the query and the rows it returns…
- You don’t know enough to write the SQL!
|
|
32
|
- What is the main, most-selective filter that will trim the result set
from the unfiltered rowcount of the root detail table to the desired
rowcount? If this isn’t obvious to the casual SQL reviewer, make it
obvious, with comments.
- Is there a clean, indexed path to that that best filter, and to the
other big tables, from there, and have you provided it?
|
|
33
|
- If you don’t know enough to…
- Understand a clean path to the data from the best (most selective)
filter…
- You don’t know enough to write the SQL!
|
|
34
|
- Is the SQL clear enough that the next developer (who will know far less
about that module of the application), or even a SQL tuning specialist
(who may know almost nothing about the application) can easily
understand it?
- Are the unusual features of the SQL, if any, well commented with clear
explanations?
- Is every column preceded with its alias?
|
|
35
|
- If you don’t know enough to…
- Make the SQL transparently understandable and clear…
- You don’t know enough to write the SQL!
|
|
36
|
- Are these rules seemingly impossible to follow on your database?
Problems coding clean SQL often point to schema-design flaws – push back
on these flaws when you find them.
- Does is seem impossible to make the deadline with clean SQL, following
these rules? Would it be better to release the wrong SQL on time? (NO!)
|
|
37
|
- If you don’t know enough to…
- Know the value of getting it right in the first place…
- You don’t know enough to write the SQL!
|
|
38
|
- All SQL can be built right!
- All SQL should be built right!
- SQL that is built following the right principles rarely needs fixing,
and can always be fixed easily when necessary!
|
|
39
|
|