If you have been using certain DBMSs, or reading recent versions
of the SQL standard, you are probably aware of the so-called
“WITH clause” of SQL.
Some call it Subquery Factoring. Others call
it Common Table Expression. A form of the WITH
CLAUSE, “WITH RECURSIVE”, allows to design a
recursive query: a query which repeats itself again and again,
each time using the results of the previous iteration. This can
be quite useful to produce reports based on hierarchical data.
And thus is an alternative to Oracle’s CONNECT BY. MySQL does not
natively support WITH RECURSIVE, but it is easy to emulate it
with a generic, reusable stored procedure. Read the full article
…
[2017 update: MySQL 8.0.1 now features SQL-standard CTE
syntax; more information is here ; the entry below, from 2013, shows how
to work around the absence of CTEs in older MySQL
versions.]
If you have been using certain DBMSs, or reading recent versions
of the SQL standard, you are probably aware of the so-called
"WITH clause" of SQL.
Some call it Subquery Factoring. Others call
it Common Table Expression (CTE). In its simplest
form, this feature is a kind of "boosted derived table".
Assume that a table T1 has three columns:
CREATE TABLE T1( YEAR …[Read more]
MySQL 5.6 introduced a new feature called extended secondary
keys. We get a lot of questions about it and find that most
of them come from a few incorrect assumption. In this post I’ll
try to get rid of the confusion once and for all. Famous last
words… here goes:
Q1: Do I need to do anything
to enable extended secondary keys?No, nothing at all. It’s on
by default and I can’t see any sensible reason why you would want
to disable it. However, it is possible to disable it by tuning
the optimizer_switch: SET
optimizer_switch=’use_index_extensions={on|off}’.
Q2: Does extended secondary keys only work with InnoDB?
No, it should work with any storage engine that uses the primary key columns as reference to the row, which means most storage engines with clustered primary keys. I say “should” because it requires a minimum of work from the storage engine provider; it must …
[Read more]
MySQL 5.6 introduced a new feature called extended secondary
keys. We get a lot of questions about it and find that most
of them come from a few incorrect assumption. In this post I'll
try to get rid of the confusion once and for all. Famous last
words... here goes:
Q1: Do I need to do anything to enable extended
secondary keys?
No, nothing at all. It's on by default and I can't see any
sensible reason why you would want to disable it. However, it is
possible to disable it by tuning the optimizer_switch: SET
optimizer_switch='use_index_extensions={on|off}'.
Q2: Does extended secondary keys only work with
InnoDB?
No, it should work with any storage engine that uses the primary
key columns as reference to the row, which means most storage
engines with clustered primary keys. I say "should" because it
requires a minimum of work from the storage engine provider; it …
On Friday I gave a presentation on “MySQL Query Patterns, Optimized” for Percona MySQL Webinars. If you missed it, you can still register to view the recording and my slides.
Thanks to everyone who attended, and especially to folks who asked the great questions. I answered as many as we had time for during the session, but here are all the questions with my complete answers:
Q: Can you compare the use of subqueries/multiple joins vs. multiple queries (e.g. temp tables)?
For performance, it’s hard to make …
[Read more]MySQL can optimize aggregate functions like MIN and MAX as long as the columns specified are indexed. This means that, in the case of MIN and MAX, the optimizer should be able to identify the highest and lowest values of an indexed column from the B-Tree index. Say I have a table like below:
CREATE TABLE `history` ( `h_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `u_id` int(10) unsigned NOT NULL, `cn_id` int(10) unsigned NOT NULL, `f_id` int(10) unsigned NOT NULL PRIMARY KEY (`h_id`) ) ENGINE=InnoDB
If I want to get the MAX value for cn_id, I’d to a query like this which will be a full table scan:
mysql (test) > EXPLAIN SELECT MAX(cn_id) FROM history \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: history type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 19908716 …[Read more]
It is finally here. After three years of development, the new version of Shard-Query is finally available for broad testing.
This new version of Shard-Query is vastly improved over previous versions in many ways. This is in large part due to the fact that the previous version of Shard-Query (version 1.1) entered into production at a large company. Their feedback during implementation was invaluable in building the new Shard-Query features. The great thing is that this means that many of the new 2.0 features have already been tested in at least one production environment.
This post is intended to highlight the new features in Shard-Query 2.0. I will be making posts about individual features as well as posting benchmark results.
…
[Read more]Next Friday, May 31 at 10 a.m. Pacific, I’ll present Percona’s next webinar, “SQL Query Patterns, Optimized.”
Based on my experiences solving tough SQL problems for Percona training and consulting, I’ll classify several common types of queries with which developers struggle. I’ll test several SQL solutions for each type of query objective, and show how you can use MySQL 5.6 built-in methods to analyze them for optimal query efficiency. The discussion will cover optimizer reports, query profiling, and session status to measure performance.
The query patterns will …
[Read more]
From time to time I will observe servers wasting lots of CPU when
doing batch row operations. In perf top
it will look
like this:
8.24% mysqld [.] Arg_comparator::compare_int_unsigned() 7.17% mysqld [.] Item_cond_and::val_int() 4.37% mysqld [.] Item_field::val_int() 4.37% mysqld [.] Item_cond_or::val_int() 2.90% mysqld [.] MYSQLparse(void*) 2.64% mysqld [.] Item::val_bool()
Essentially if you construct queries like (a=1 AND b=2) OR
(a=3 AND b=4) ...
, at large enough batch size evaluating
the WHERE will become far more expensive than anything else (yes,
more expensive than decompressing rows or doing all the InnoDB
magic and what not).
MySQL has awesome syntax that makes certain batch lookups much faster: WHERE a IN (1,2,3). It constructs a tree that then each row can be compared against and one does not have to iterate through lists of predicates to check whether the row returned by batch index lookups …
[Read more]
There are great features in MySQL 5.6. But not only that. We also
tried to correct some old behaviors and limitations which, over
the years, have shown to irritate our Community. The behavior of
TIMESTAMP columns is one of them.
My colleague Martin Hansson did most of the work and summarized
it well in his blog. Thanks to him, since MySQL 5.6.5, it's
possible to declare more than one TIMESTAMP column with the
DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP
attributes. And it's possible to have DATETIME columns with such
attributes. Two limitations lifted!
But that is not the end of the story. TIMESTAMP was still
special. Unlike other datatypes, if not declared with the NULL or
NOT NULL attributes, it would automatically get NOT NULL. And the
first TIMESTAMP column of the table would automatically …