Databases Reference
In-Depth Information
The
index_flags()
method returns a bitmap of flags describing the capabilities
of the key part
part
of the index
inx
. If
all_parts
is set, the bitmap describes
capabilities of the index prefix from the first and up to the key part
part
(including
all of the intermediate key parts, that is), otherwise it describes only the key part
part
. However, in our engine the capabilities do not depend on the key part, they
are always the same—a B+tree in Tokyo Cabinet can be traversed either forward,
using
tcbdbcurnext()
, or backward, using
tcbdbcurprev()
. All keys in B+tree
are naturally ordered according to our custom comparison functions, and thus can
do ranges too. Since we will store column values in their original form, we will
be able to copy them from the key back into the row buffer, thus supporting the
keyread
optimization.
Let's talk a bit more about
keyread
. Remember that our
position
is the primary key
and all secondary keys refer to a row by its primary key. It means that for every
search by a secondary key we need to perform
two
B+tree lookups—first, we look
up this secondary key and find a corresponding primary key, then we look up the
primary key to find the actual row data. But if this secondary key is
covering
, we do
not need to do a second lookup, we can restore key columns in the row buffer from
the key. Other columns' values will be undefined, but that is fine, MySQL does not
need them. It looks like not only our engine can do
keyread
, but it will also get twice
the speed with this optimization! But this is only for secondary keys. For a primary
key, this brings no benefits—that is, we should enable
HA_KEYREAD_ONLY
only for
secondary keys in our
index_flags()
method. A primary key in MySQL is always
the first, key number 0, and we disable
keyread
for it.
And note another fine detail—when we read from a secondary index we know not
only the secondary key, but also a corresponding primary key. That is, in the
keyread
optimization we know values for all columns that are part of this secondary key and
all columns that are part of the primary key—and after just one index lookup, not
two! We can convey this information to MySQL in
table_flags()
:
ulonglong ha_tocab::table_flags() const
{
return HA_NO_TRANSACTIONS |
HA_TABLE_SCAN_ON_INDEX |
HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY |
HA_STATS_RECORDS_IS_EXACT |
HA_CAN_INDEX_BLOBS |
HA_AUTO_PART_KEY |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_REQUIRE_PRIMARY_KEY ;
}