What I talk about when I talk about query optimizer (part 1): IR design
xuanwo.io
xuanwo.io
I don't know much about the context, but it was interesting to note that Materialize scrapped their QGM code last year: https://github.com/MaterializeInc/materialize/pull/17139
Also, a couple of interesting projects in the IR space:
- https://substrait.io/ is a cross-language serialization for Relational Algebra
- https://www.lingo-db.com/ is an MLIR-based (LLVM) query engine described extensively in this paper https://db.in.tum.de/~jungmair/papers/p2485-jungmair.pdf?lan...
This is awesome.
(can also use it in your own projects)
It is quite similar to what is described in this post
So for example using DuckDB with the Substrait extension, if you create a table
create table t(a int);
and then query it as in the article, you can see something similar to what is described in the article CALL get_substrait_json('select * from t');
{"relations":[{"root":{"input":{"project":{"input":{"read":{"baseSchema":{"names":["a"],"struct":{"types":[{"i32":{"nullability":"NULLABILITY_NULLABLE"}}],...
DuckDB extension doesn't seem to cover any DDL operations though.https://duckdb.org/docs/extensions/substrait
Some other related discussions and links that i've collected over the years
https://news.ycombinator.com/item?id=37415494
https://news.ycombinator.com/item?id=34233697
https://news.ycombinator.com/item?id=31981568
https://datastation.multiprocess.io/blog/2022-04-11-sql-pars...
https://medium.com/starrocks-engineering/starrocks-inside-sc...
https://github.com/dolthub/go-mysql-server
Getting the IR correct so that it's both easy to use and flexible enough to be useful is a really interesting design challenge. Our primary abstraction in the query plan is called a Node, and is way more general than the IR type described in the article from OP. This has probably hurt us: we only recently separated the responsibility to fetch rows into its own part of the runtime, out of the IR -- originally row fetching was coupled to the Node type directly.
This is also the query engine that Dolt uses:
https://github.com/dolthub/dolt
But it has a plug-in architecture, so you can use the engine on any data source that implements a handful of Go interface.
I also recommend the sqlite.org docs "overview of the optimizer" and "vbdb bytecode" which you could see as an IR.
I have been thinking about sharing something about database internals for a long time, but none of my writing ideas was out of cliché then(e.g. introduce some algorithms, summarize some papers).
But I just realized that it maybe an interesting thing to talk about "how" and "why" instead of "what".
The rest posts are coming soon, hope you can see them on hacker news again.
They also implemented DPhyp join reorder algorithm but with an ad-hoc IR. The join optimizer IR(they call it RelationalExpression) is based on relational algebra. I think this is a good start.
But it’s not easy to migrate a project lived for decades, especially one with poor design.
It's true that if you are using the hypergraph optimizer, you will get a rewrite from the array of tables into RelationalExpression. But I find it hard to call that relational algebra; in particular, it only supports joins and tables as operations. Filters are pushed down ad-hoc, and things like grouping or windowing operators are simply not representable in this structure at all. Columns are not dealt with at all either (projection is unavailable).
And perhaps more importantly; RelationalExpression is hardly used. Most of the optimizer works on the old array-of-tables structure, then it briefly becomes RelationalExpression for condition pushdown, then the hypergraph is created and RelationalExpression is never to be seen again. The entire hypergraph optimizer works by inducing subgraphs of a hypergraph; it does not use relational algebra.
Also, notably, MySQL 8.0 does not actually _use_ the hypergraph optimizer by default. You need to explicitly compile it in (it's off in release builds), and then enable it using an optimizer switch. So unless you go to fairly great lengths to enable it yourself, RelationalExpression and friends is never used.
I agree that using a relational algebra IR would be a good idea; it's a better structure than what's in there right now (which comes all the way from MySQL 3.x, and is extremely unflexible to work with). It's just that I don't think MySQL 8.0 does it. :-)
(I obviously don't speak for Oracle, not the least because I haven't worked there in a while)
This format is now very widely used in blogs and other pieces, almost to the point of being overdone. TIL from (https://lithub.com/what-we-talk-about-when-we-talk-about-thi...) that Murakami "asked Tess Gallagher, Carver’s widow, for permission to use the title form." for his memoir published in 2009. He's probably an important factor in the resurgence of the format.
Murakami credited Raymond Carver's collection of short stories called “What We Talk About When We Talk About Love” for inspiring his title. Might be nice for you to include a small mention.