EXPLAIN EXTENDED
How to create fast database queries
- Posts
- 275 from 28 Feb 2009 to 31 Dec 2025
- Posting
- now and then (1 in the last year)
- Kind
- personal blog
- Feed
- https://explainextended.com/feed/
2025 1
2024 1
2023 1
2022 2
2021 1
2020 1
2019 1
2018 1
2017 1
2016 1
2015 1
2014 3
2013 10
- Happy New Year: drawing fractals in SQL
- 5 Claims About SQL, Explained
- NULL in SQL: explaining its behavior
- Did You Know You Could Index SUM() and COUNT(): SQL Server Indexed Views, Part 3
- Storing a Friendship: SQL Server Indexed Views, Part 2
- 10 things in SQL Server (which don’t work as expected)
- Score charts, friendship lists and unique multiple columns: easy with SQL Server’s indexed views
- SQL Server: joining NULL values
- INSERT … SELECT … OUTPUT …: returning source table data
- Empty row if condition does not match
2012 1
2011 7
2010 41
- Happy New Year: drawing clock in SQL
- PostgreSQL: parametrizing a recursive CTE
- 10 things in MySQL (that won’t work as expected)
- Mixed ASC/DESC sorting in MySQL
- Correlated LEFT JOIN in a subquery
- OLAP in MySQL: four ways to filter on higher level dimensions
- 20 latest unique records
- Questions
- Indexing for ORDER BY / LIMIT
- GROUP_CONCAT in SQL Server
- LEFT JOIN / IS NULL vs. NOT IN vs. NOT EXISTS: nullable columns
- Things SQL needs: determining range cardinality
- MAX and MIN on a composite index
- Things SQL needs: MERGE JOIN that would seek
- Groups holding highest ranked items
- Hierarchical query in MySQL: limiting parents
- Date ranges: overlapping with priority
- Multiple attributes in a EAV table: GROUP BY vs. NOT EXISTS
- Nosql
- Bayesian classification
- Greatest N per group: dealing with aggregates
- Aggregates and LEFT JOIN
- SQL Server: deleting with self-referential FOREIGN KEY
- PostgreSQL: using recursive functions in nested sets
- PostgreSQL: nested sets and R-Tree
- Six degrees of separation
- Efficient circle distance testing
- Matching sets: aggregates vs. first miss
- Sargability of monotonic functions: example
- Things SQL needs: sargability of monotonic functions
- Tags in nested sets: efficient indexing
- SQL Server: EXCEPT ALL
- Index search time depends on the value being searched
- Searching for arbitrary portions of a date
- Join on overlapping date ranges
- Aggregates: subqueries vs. GROUP BY
- Counting concurrent sessions
- SQL Server: running totals
- Cumulative values
- Calculating mode
- Latest visitors
2009 201
- Happy New Year!
- Grouping continuous ranges
- Linked lists in MySQL: multiple ordering
- Oracle: joining timestamps and time intervals
- Oracle: Selecting records holding group-wise maximum
- SQL Server: Selecting records holding group-wise maximum (with ties)
- SQL Server: Selecting records holding group-wise maximum
- PostgreSQL: Selecting records holding group-wise maximum
- MySQL: Selecting records holding group-wise maximum (resolving ties)
- MySQL: Selecting records holding group-wise maximum (on a unique column)
- Recursive CTE’s: PostgreSQL
- SQL Server: are the recursive CTE’s really set-based?
- Selecting most relevant row
- Inverting date ranges: MySQL
- SQL Server: clustered index and ordering
- MySQL: average of sums using indexes
- Inverting date ranges
- MySQL ORDER BY / LIMIT performance: late row lookups
- Generating row placeholders: SQL Server
- What is entity-relationship model?
- Constraints and the optimizer in SQL Server: FOREIGN KEY
- Constraints and the optimizer in SQL Server: PRIMARY KEY and UNIQUE
- Running root mean square: SQL Server
- Minimum and maximum on bit fields: SQL Server
- Oracle: nested SUM
- IN list vs. range condition: MySQL
- Shuffling rows: PostgreSQL
- Date range with possible NULL values
- Bitwise operations and indexes
- IN vs. JOIN vs. EXISTS: Oracle
- Adjacency list vs. nested sets: MySQL
- Adjacency list vs. nested sets: Oracle
- Adjacency list vs. nested sets: SQL Server
- Adjacency list vs. nested sets: PostgreSQL
- Building alphabetical index
- Finding sets within a time frame
- Rounding numbers preserving their sum
- NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: MySQL
- NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: Oracle
- NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: PostgreSQL
- NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL: SQL Server
- MySQL: emulating ROW_NUMBER with multiple ORDER BY conditions
- SQL Server 2005: finding foreign keys that have no index
- Oracle: generating a list of dates and counting ranges for each date
- MySQL: matching whole sets
- PostgreSQL: selecting items that belong to all categories
- SQL Server: leading wildcard match using an index
- What is a relational database?
- SQL Server: finding date closest to a birthdate
- SQL Server: efficient DISTINCT on dates
- MySQL: difference between sets
- Passing parameters in MySQL: IN list vs. temporary table
- Hierarchical queries in MySQL: VARCHAR keys
- Presentation layer
- Oracle: updating rows with partitioned incremental value
- Efficient date range query: SQL Server
- Fallback language names: MySQL
- Fallback language names: PostgreSQL
- Fallback language names: SQL Server
- Fallback language names: Oracle
- MySQL: LIMIT on LIMIT
- SQL Server: deleting adjacent values (improved)
- SQL Server: deleting adjacent values
- MySQL: DISTINCT on DISTINCT
- MySQL: counting items in pairs
- PostgreSQL: making duplicate records unique
- PostgreSQL 8.4: efficient MIN(COUNT(*))
- SQL Server: random records avoiding CTE reevaluation
- Dynamic pivot
- MySQL: selecting rows before and after filtered one
- MySQL: grouping continuous ranges
- PostgreSQL: last 12 weeks of a year
- Hierarchial queries in MySQL: identifying trees
- PostgreSQL: round-robin order
- Hierarchical data in MySQL: parents and children in one query
- PostgreSQL 8.4: sampling random rows
- PostgreSQL 8.4: preserving order for hierarchical query
- INNER JOIN vs. CROSS APPLY
- Oracle: OR on multiple EXISTS clauses
- Flattening timespans: PostgreSQL 8.4
- SQL Server: aggregate bitwise OR
- Double-thinking in SQL
- Selecting compatible articles
- Selecting birthdays
- Finding duplicates on either of the fields
- Selecting last forum posts
- Overlapping numbers
- Schema junk
- Searching for NULL columns
- Overlapping ranges: PostgreSQL
- Overlapping ranges: Oracle
- Overlapping ranges: MySQL
- Overlapping ranges: SQL Server
- The Island of Misfit Cursors
- Efficient INSERT ON DUPLICATE KEY UPDATE
- Included columns
- Building permutations: SQL Server
- Constant vs. NULL to mark missing values in OUTER JOINs
- IN with a comma separated list: SQL Server
- Indexing tiny tables
- Click
- NVL vs. COALESCE
- Ordering NULLs
- Counting bans
- Efficient EXISTS
- IN vs. JOIN vs. EXISTS
- Group based identity
- Flattening timespans: PostgreSQL
- Flattening timespans: MySQL
- Flattening timespans: Oracle
- Flattening timespans: SQL Server
- Joining unjoinable
- Latest DISTINCT records: efficient subquery
- Latest DISTINCT records
- Longest common prefix: MySQL
- Longest common prefix: Oracle
- Longest common prefix: PostgreSQL
- Longest common prefix: SQL Server
- Selecting records unique on each column
- Distinct pairs
- Numbering groups
- Aggregate AND
- Hierarchical queries in PostgreSQL
- Generating XML in subqueries
- Converting currencies
- Selecting options
- Genealogy: finding a descendant
- Genealogy query on both parents
- Ordering columns independently
- Choosing column order
- Oracle: matching SYS_GUID’s
- Finding loops in a tree
- Ranging random values
- UNION vs UNION ALL
- Ordering UNION’s
- PostgreSQL: selecting a function
- Oracle: returning deleted records
- Indexing a link table
- PostgreSQL: emulating ROW_NUMBER
- Creating indexes
- Selecting first letters
- Checking event dates
- Oracle: ROW_NUMBER vs ROWNUM
- PostgreSQL: row numbers
- Assigning people
- PostgreSQL: optimizing DISTINCT
- GROUP_CONCAT in PostgreSQL without aggregate functions
- Indexing VARCHAR(MAX)
- Rating movies
- Selecting N records for each group: PostgreSQL
- Descending indexes
- Keeping latest rows for a group
- Selecting timestamps for a time zone
- Selecting lowest value
- Making an index UNIQUE
- Counting missing rows: PostgreSQL
- Counting missing rows: Oracle
- Counting missing rows: SQL Server
- Counting missing rows: using DISTINCT
- Counting missing rows
- Matching 3 of 4
- Missing entries
- Keeping rows
- Emulating FULL OUTER JOIN in MySQL
- GROUP_CONCAT in Oracle 10g
- Banning IP’s
- Endless loops
- Emulating SKIP SCAN
- Choosing index
- Matching whole sets
- Sorting lists: deleting blocks
- Sorting lists: moving blocks
- Sorting lists: deleting items
- Sorting lists: adding items
- Sorting lists: moving items
- Sorting lists
- Article-aware title filtering: internationalization
- Article-aware title filtering
- Selecting non-unique rows
- Hierarchical queries in MySQL: finding loops
- Hierarchical queries in MySQL: finding leaves
- Hierarchical queries in MySQL: adding ancestry chains.
- Hierarchical queries in MySQL: adding level
- Hierarchical queries in MySQL
- Counting page views
- Aggregated hours
- Deleting duplicates
- Finding incomplete orders
- Analytic functions: optimizing LAG, LEAD, FIRST_VALUE, LAST_VALUE
- Analytic functions: optimizing SUM and ROW_NUMBER
- Analytic functions: FIRST_VALUE, LAST_VALUE, LEAD, LAG
- Analytic functions: NTILE
- Analytic functions: SUM, AVG, ROW_NUMBER
- Selecting friends
- Advanced row sampling
- Row sampling
- Aggregate concatenation
- First common ancestor
- Zen update
- Selecting random rows
- Counting skills